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()))
91 if (results.empty()) {
93 *inPlaceUpdate =
true;
94 if (
auto *rewriteListener = dyn_cast_if_present<RewriterBase::Listener>(
97 rewriteListener->notifyOperationModified(op);
114 if (isFolderOwnedConstant(op)) {
115 if (&opBlock->
front() != op && !isFolderOwnedConstant(op->getPrevNode()))
123 assert(constValue &&
"expected `op` to be a constant");
130 expectedValue == constValue &&
131 "provided constant value was not the expected value of the constant");
137 auto &uniquedConstants = foldScopes[insertRegion];
138 Operation *&folderConstOp = uniquedConstants[std::make_tuple(
153 if (opBlock != insertBlock || (&insertBlock->
front() != op &&
154 !isFolderOwnedConstant(op->getPrevNode())))
158 referencedDialects[op].push_back(op->
getDialect());
166 auto it = referencedDialects.find(op);
167 if (it == referencedDialects.end())
177 auto &uniquedConstants =
182 for (
auto *dialect : it->second)
183 uniquedConstants.erase(std::make_tuple(dialect, constValue, type));
184 referencedDialects.erase(it);
190 referencedDialects.clear();
200 auto &entry = insertRegion->front();
204 auto &uniquedConstants = foldScopes[insertRegion];
206 tryGetOrCreateConstant(uniquedConstants, dialect, value, type, loc);
210 bool OperationFolder::isFolderOwnedConstant(
Operation *op)
const {
211 return referencedDialects.count(op);
220 failed(processFoldResults(op, results, foldResults)))
226 OperationFolder::processFoldResults(
Operation *op,
230 if (foldResults.empty())
237 auto &entry = insertRegion->front();
241 auto &uniquedConstants = foldScopes[insertRegion];
246 assert(!foldResults[i].isNull() &&
"expected valid OpFoldResult");
249 if (
auto repl = llvm::dyn_cast_if_present<Value>(foldResults[i])) {
254 results.emplace_back(repl);
261 if (
auto *constOp = tryGetOrCreateConstant(
262 uniquedConstants, dialect, attrRepl, res.getType(), op->
getLoc())) {
267 if (opBlock == constOp->getBlock() && &opBlock->
front() != constOp)
270 results.push_back(constOp->getResult(0));
275 for (
Operation &op : llvm::make_early_inc_range(
291 OperationFolder::tryGetOrCreateConstant(ConstantMap &uniquedConstants,
295 auto constKey = std::make_tuple(dialect, value, type);
296 Operation *&constOp = uniquedConstants[constKey];
306 if (newDialect == dialect) {
307 referencedDialects[constOp].push_back(dialect);
313 auto newKey = std::make_tuple(newDialect, value, type);
317 if (
auto *existingOp = uniquedConstants.lookup(newKey)) {
320 referencedDialects[existingOp].push_back(dialect);
321 return constOp = existingOp;
325 referencedDialects[constOp].assign({dialect, newDialect});
326 auto newIt = uniquedConstants.insert({newKey, constOp});
327 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 setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
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, Location loc)
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.
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)
This method replaces the results of the operation with the specified list of values.
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.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.