17 #include "llvm/Support/Debug.h"
20 #define DEBUG_TYPE "licm"
38 for (
Value operand : child->getOperands()) {
40 if (op->
isAncestor(operand.getParentRegion()->getParentOp()))
42 if (!definedOutside(operand))
47 return !op->
walk(walkFn).wasInterrupted();
57 for (
Region *region : regions) {
58 LLVM_DEBUG(llvm::dbgs() <<
"Original loop:\n"
59 << *region->getParentOp() <<
"\n");
61 std::queue<Operation *> worklist;
66 auto definedOutside = [&](
Value value) {
67 return isDefinedOutsideRegion(value, region);
70 while (!worklist.empty()) {
77 LLVM_DEBUG(llvm::dbgs() <<
"Checking op: " << *op <<
"\n");
78 if (!shouldMoveOutOfRegion(op, region) ||
82 LLVM_DEBUG(llvm::dbgs() <<
"Moving loop-invariant op: " << *op <<
"\n");
83 moveOutOfRegion(op, region);
89 if (user->getParentRegion() == region)
99 loopLike.getLoopRegions(),
101 return loopLike.isDefinedOutsideOfLoop(value);
104 return isMemoryEffectFree(op) && isSpeculatable(op);
static bool canBeHoisted(Operation *op, function_ref< bool(Value)> definedOutside)
Checks whether the given op can be hoisted by checking that.
This class provides the API for ops that are known to be terminators.
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
user_range getUsers()
Returns a range of all users.
Region * getParentRegion()
Returns the region to which the instruction belongs.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
static WalkResult advance()
static WalkResult interrupt()
This header declares functions that assist transformations in the MemRef dialect.
size_t moveLoopInvariantCode(ArrayRef< Region * > regions, function_ref< bool(Value, Region *)> isDefinedOutsideRegion, function_ref< bool(Operation *, Region *)> shouldMoveOutOfRegion, function_ref< void(Operation *, Region *)> moveOutOfRegion)
Given a list of regions, perform loop-invariant code motion.