26 Block *insertionBlock) {
33 !parentOp->getBlock())
37 auto *
interface = interfaces.getInterfaceFor(parentOp);
38 if (LLVM_UNLIKELY(interface && interface->shouldMaterializeInto(region)))
42 insertionBlock = parentOp->getBlock();
44 llvm_unreachable(
"expected valid insertion region");
72 *inPlaceUpdate =
false;
76 if (isFolderOwnedConstant(op)) {
80 if (&opBlock->
front() != op && !isFolderOwnedConstant(op->getPrevNode())) {
82 op->
setLoc(erasedFoldedLocation);
93 if (results.empty()) {
95 *inPlaceUpdate =
true;
96 if (
auto *rewriteListener = dyn_cast_if_present<RewriterBase::Listener>(
99 rewriteListener->notifyOperationModified(op);
116 if (isFolderOwnedConstant(op)) {
117 if (&opBlock->
front() != op && !isFolderOwnedConstant(op->getPrevNode())) {
119 op->
setLoc(erasedFoldedLocation);
127 assert(constValue &&
"expected `op` to be a constant");
134 expectedValue == constValue &&
135 "provided constant value was not the expected value of the constant");
141 auto &uniquedConstants = foldScopes[insertRegion];
142 Operation *&folderConstOp = uniquedConstants[std::make_tuple(
149 folderConstOp->
setLoc(erasedFoldedLocation);
158 if (opBlock != insertBlock || (&insertBlock->
front() != op &&
159 !isFolderOwnedConstant(op->getPrevNode()))) {
161 op->
setLoc(erasedFoldedLocation);
165 referencedDialects[op].push_back(op->
getDialect());
173 auto it = referencedDialects.find(op);
174 if (it == referencedDialects.end())
184 auto &uniquedConstants =
189 for (
auto *dialect : it->second)
190 uniquedConstants.erase(std::make_tuple(dialect, constValue, type));
191 referencedDialects.erase(it);
197 referencedDialects.clear();
206 auto &entry = insertRegion->front();
211 auto &uniquedConstants = foldScopes[insertRegion];
212 Operation *constOp = tryGetOrCreateConstant(uniquedConstants, dialect, value,
213 type, erasedFoldedLocation);
217 bool OperationFolder::isFolderOwnedConstant(
Operation *op)
const {
218 return referencedDialects.count(op);
226 if (failed(op->
fold(foldResults)) ||
227 failed(processFoldResults(op, results, foldResults)))
233 OperationFolder::processFoldResults(
Operation *op,
237 if (foldResults.empty())
244 auto &entry = insertRegion->front();
248 auto &uniquedConstants = foldScopes[insertRegion];
253 assert(!foldResults[i].isNull() &&
"expected valid OpFoldResult");
256 if (
auto repl = llvm::dyn_cast_if_present<Value>(foldResults[i])) {
257 results.emplace_back(repl);
265 tryGetOrCreateConstant(uniquedConstants, dialect, attrRepl,
266 res.getType(), erasedFoldedLocation)) {
271 if (opBlock == constOp->getBlock() && &opBlock->
front() != constOp)
274 results.push_back(constOp->getResult(0));
279 for (
Operation &op : llvm::make_early_inc_range(
295 OperationFolder::tryGetOrCreateConstant(ConstantMap &uniquedConstants,
299 auto constKey = std::make_tuple(dialect, value, type);
300 Operation *&constOp = uniquedConstants[constKey];
302 if (loc != constOp->
getLoc())
303 constOp->
setLoc(erasedFoldedLocation);
313 if (newDialect == dialect) {
314 referencedDialects[constOp].push_back(dialect);
320 auto newKey = std::make_tuple(newDialect, value, type);
324 if (
auto *existingOp = uniquedConstants.lookup(newKey)) {
327 referencedDialects[existingOp].push_back(dialect);
328 if (loc != existingOp->getLoc())
329 existingOp->setLoc(erasedFoldedLocation);
330 return constOp = existingOp;
334 referencedDialects[constOp].assign({dialect, newDialect});
335 auto newIt = uniquedConstants.insert({newKey, constOp});
336 return newIt.first->second;
static Operation * materializeConstant(Dialect *dialect, OpBuilder &builder, Attribute value, Type type, Location loc)
A utility function used to materialize a constant for a given attribute and type.
static Region * getInsertionRegion(DialectInterfaceCollection< DialectFoldInterface > &interfaces, Block *insertionBlock)
Given an operation, find the parent region that folded constants should be inserted into.
Attributes are known-constant values of operations.
Block represents an ordered list of Operations.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
void moveBefore(Block *block)
Unlink this block from its current region and insert it right before the specific block.
A collection of dialect interfaces within a context, for a given concrete interface type.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
virtual Operation * materializeConstant(OpBuilder &builder, Attribute value, Type type, Location loc)
Registered hook to materialize a single constant operation from a given attribute value with the desi...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
This class helps build Operations.
Block::iterator getInsertionPoint() const
Returns the current insertion point of the builder.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
Listener * getListener() const
Returns the current listener of this builder, or nullptr if this builder doesn't have a listener.
This class provides the API for ops that are known to be isolated from above.
Value getOrCreateConstant(Block *block, Dialect *dialect, Attribute value, Type type)
Get or create a constant for use in the specified block.
void clear()
Clear out any constants cached inside of the folder.
LogicalResult tryToFold(Operation *op, bool *inPlaceUpdate=nullptr)
Tries to perform folding on the given op, including unifying deduplicated constants.
void notifyRemoval(Operation *op)
Notifies that the given constant op should be remove from this OperationFolder's internal bookkeeping...
bool insertKnownConstant(Operation *op, Attribute constValue={})
Tries to fold a pre-existing constant operation.
Operation is the basic unit of execution within MLIR.
void setLoc(Location loc)
Set the source location the operation was defined or derived from.
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Location getLoc()
The source location the operation was defined or derived from.
Block * getBlock()
Returns the operation block that contains this operation.
result_type_iterator result_type_begin()
void moveBefore(Operation *existingOp)
Unlink this operation from its current block and insert it right before existingOp which may be in th...
result_range getResults()
unsigned getNumResults()
Return the number of results held by this operation.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Operation * getParentOp()
Return the parent operation this region is attached to.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.