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");
74 *inPlaceUpdate =
false;
78 if (isFolderOwnedConstant(op)) {
82 if (&opBlock->
front() != op && !isFolderOwnedConstant(op->getPrevNode()))
94 if (results.empty()) {
96 *inPlaceUpdate =
true;
103 if (preReplaceAction)
104 preReplaceAction(op);
107 for (
unsigned i = 0, e = results.size(); i != e; ++i)
118 if (isFolderOwnedConstant(op)) {
119 if (&opBlock->
front() != op && !isFolderOwnedConstant(op->getPrevNode()))
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(
157 if (opBlock != insertBlock || (&insertBlock->
front() != op &&
158 !isFolderOwnedConstant(op->getPrevNode())))
162 referencedDialects[op].push_back(op->
getDialect());
170 auto it = referencedDialects.find(op);
171 if (it == referencedDialects.end())
181 auto &uniquedConstants =
186 for (
auto *dialect : it->second)
187 uniquedConstants.erase(std::make_tuple(dialect, constValue, type));
188 referencedDialects.erase(it);
194 referencedDialects.clear();
208 auto &entry = insertRegion->
front();
212 auto &uniquedConstants = foldScopes[insertRegion];
213 Operation *constOp = tryGetOrCreateConstant(uniquedConstants, dialect,
214 builder, value, type, loc);
218 bool OperationFolder::isFolderOwnedConstant(
Operation *op)
const {
219 return referencedDialects.count(op);
230 bool updatedOpOperands =
false;
235 auto *firstConstantIt =
237 auto *newConstantIt = std::stable_partition(
241 updatedOpOperands = firstConstantIt != newConstantIt;
254 if (
failed(op->
fold(operandConstants, foldResults)) ||
255 failed(processFoldResults(builder, op, results, foldResults,
256 processGeneratedConstants)))
257 return success(updatedOpOperands);
266 if (foldResults.empty())
274 auto &entry = insertRegion->
front();
279 auto &uniquedConstants = foldScopes[insertRegion];
284 assert(!foldResults[i].isNull() &&
"expected valid OpFoldResult");
287 if (
auto repl = foldResults[i].dyn_cast<Value>()) {
292 results.emplace_back(repl);
300 tryGetOrCreateConstant(uniquedConstants, dialect, builder, attrRepl,
306 if (opBlock == constOp->getBlock() && &opBlock->
front() != constOp)
309 results.push_back(constOp->getResult(0));
314 for (
Operation &op : llvm::make_early_inc_range(
324 if (processGeneratedConstants) {
326 processGeneratedConstants(&*i);
334 Operation *OperationFolder::tryGetOrCreateConstant(
338 auto constKey = std::make_tuple(dialect, value, type);
339 Operation *&constOp = uniquedConstants[constKey];
349 if (newDialect == dialect) {
350 referencedDialects[constOp].push_back(dialect);
356 auto newKey = std::make_tuple(newDialect, value, type);
360 if (
auto *existingOp = uniquedConstants.lookup(newKey)) {
362 referencedDialects[existingOp].push_back(dialect);
363 return constOp = existingOp;
367 referencedDialects[constOp].assign({dialect, newDialect});
368 auto newIt = uniquedConstants.insert({newKey, constOp});
369 return newIt.first->second;
void moveBefore(Operation *existingOp)
Unlink this operation from its current block and insert it right before existingOp which may be in th...
Include the generated interface declarations.
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
Operation is a basic unit of execution within MLIR.
This class adds property that the operation is commutative.
Block represents an ordered list of Operations.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void moveBefore(Block *block)
Unlink this block from its current region and insert it right before the specific block...
Value getOperand(unsigned idx)
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
unsigned getNumOperands()
A collection of dialect interfaces within a context, for a given concrete interface type...
Block * getBlock()
Returns the operation block that contains this operation.
void replaceAllUsesWith(Value newValue) const
Replace all uses of 'this' value with the new value, updating anything in the IR that uses 'this' to ...
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
static constexpr const bool value
void erase()
Remove this operation from its parent block and delete it.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MutableArrayRef< OpOperand > getOpOperands()
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
This class represents an efficient way to signal success or failure.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Value getOrCreateConstant(OpBuilder &builder, Dialect *dialect, Attribute value, Type type, Location loc)
Get or create a constant using the given builder.
Attributes are known-constant values of operations.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided 'values'.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Location getLoc()
The source location the operation was defined or derived from.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Operation * getParentOp()
Return the parent operation this region is attached to.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
RAII guard to reset the insertion point of the builder when destroyed.
Type getType() const
Return the type of this value.
result_type_iterator result_type_begin()
bool insertKnownConstant(Operation *op, Attribute constValue={})
Tries to fold a pre-existing constant operation.
This class provides the API for ops that are known to be isolated from above.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
This class represents an operand of an operation.
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
unsigned getNumResults()
Return the number of results held by this operation.
void notifyRemoval(Operation *op)
Notifies that the given constant op should be remove from this OperationFolder's internal bookkeeping...
Block::iterator getInsertionPoint() const
Returns the current insertion point of the builder.
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 helps build Operations.
void clear()
Clear out any constants cached inside of the folder.
LogicalResult tryToFold(Operation *op, function_ref< void(Operation *)> processGeneratedConstants=nullptr, function_ref< void(Operation *)> preReplaceAction=nullptr, bool *inPlaceUpdate=nullptr)
Tries to perform folding on the given op, including unifying deduplicated constants.
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...