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);
159 if (opBlock != insertBlock) {
161 op->
setLoc(erasedFoldedLocation);
162 }
else if (&insertBlock->
front() != op &&
163 !isFolderOwnedConstant(op->getPrevNode())) {
168 referencedDialects[op].push_back(op->
getDialect());
176 auto it = referencedDialects.find(op);
177 if (it == referencedDialects.end())
187 auto &uniquedConstants =
192 for (
auto *dialect : it->second)
193 uniquedConstants.erase(std::make_tuple(dialect, constValue, type));
194 referencedDialects.erase(it);
200 referencedDialects.clear();
209 auto &entry = insertRegion->front();
214 auto &uniquedConstants = foldScopes[insertRegion];
215 Operation *constOp = tryGetOrCreateConstant(uniquedConstants, dialect, value,
216 type, erasedFoldedLocation);
220 bool OperationFolder::isFolderOwnedConstant(
Operation *op)
const {
221 return referencedDialects.count(op);
230 failed(processFoldResults(op, results, foldResults)))
236 OperationFolder::processFoldResults(
Operation *op,
240 if (foldResults.empty())
247 auto &entry = insertRegion->front();
251 auto &uniquedConstants = foldScopes[insertRegion];
256 assert(!foldResults[i].isNull() &&
"expected valid OpFoldResult");
259 if (
auto repl = llvm::dyn_cast_if_present<Value>(foldResults[i])) {
260 results.emplace_back(repl);
266 Attribute attrRepl = cast<Attribute>(foldResults[i]);
268 tryGetOrCreateConstant(uniquedConstants, dialect, attrRepl,
269 res.getType(), erasedFoldedLocation)) {
274 if (opBlock == constOp->getBlock() && &opBlock->
front() != constOp)
277 results.push_back(constOp->getResult(0));
282 for (
Operation &op : llvm::make_early_inc_range(
298 OperationFolder::tryGetOrCreateConstant(ConstantMap &uniquedConstants,
302 auto constKey = std::make_tuple(dialect, value, type);
303 Operation *&constOp = uniquedConstants[constKey];
305 if (loc != constOp->
getLoc())
306 constOp->
setLoc(erasedFoldedLocation);
316 if (newDialect == dialect) {
317 referencedDialects[constOp].push_back(dialect);
323 auto newKey = std::make_tuple(newDialect, value, type);
327 if (
auto *existingOp = uniquedConstants.lookup(newKey)) {
330 referencedDialects[existingOp].push_back(dialect);
331 if (loc != existingOp->getLoc())
332 existingOp->setLoc(erasedFoldedLocation);
333 return constOp = existingOp;
337 referencedDialects[constOp].assign({dialect, newDialect});
338 auto newIt = uniquedConstants.insert({newKey, constOp});
339 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.