25 #include "llvm/Support/Casting.h"
59 auto getOperandIndexIfPred =
62 branch.getSuccessorRegions(pred, successors);
64 if (successor.getSuccessor() != region)
67 ValueRange inputs = successor.getSuccessorInputs();
69 output.push_back(inputValue);
72 unsigned firstInputIndex, lastInputIndex;
74 firstInputIndex = cast<BlockArgument>(inputs[0]).getArgNumber();
75 lastInputIndex = cast<BlockArgument>(inputs.back()).getArgNumber();
77 firstInputIndex = cast<OpResult>(inputs[0]).getResultNumber();
78 lastInputIndex = cast<OpResult>(inputs.back()).getResultNumber();
80 if (firstInputIndex > inputIndex || lastInputIndex < inputIndex) {
81 output.push_back(inputValue);
84 return inputIndex - firstInputIndex;
94 if (std::optional<unsigned> operandIndex =
97 branch.getEntrySuccessorOperands(branchPoint)[*operandIndex], maxDepth,
103 if (std::optional<unsigned> operandIndex = getOperandIndexIfPred(region)) {
104 for (
Block &block : region) {
107 if (
auto term = dyn_cast<RegionBranchTerminatorOpInterface>(
108 block.getTerminator())) {
110 term.getSuccessorOperands(branchPoint)[*operandIndex], maxDepth,
112 }
else if (block.getNumSuccessors()) {
115 output.push_back(inputValue);
130 if (ViewLikeOpInterface view = dyn_cast<ViewLikeOpInterface>(op))
134 if (
auto branch = dyn_cast<RegionBranchOpInterface>(op)) {
140 output.push_back(result);
154 auto branch = dyn_cast<BranchOpInterface>((*it)->getTerminator());
157 output.push_back(arg);
162 unsigned index = it.getSuccessorIndex();
163 Value operand = branch.getSuccessorOperands(index)[argNumber];
166 output.push_back(arg);
177 if (
auto branch = dyn_cast<RegionBranchOpInterface>(op)) {
179 maxDepth, visited, output);
183 output.push_back(arg);
191 if (!visited.insert(value).second)
194 output.push_back(value);
225 std::optional<MemoryEffects::EffectInstance> &effect,
232 op = cast<OpResult>(value).getOwner();
233 MemoryEffectOpInterface
interface = dyn_cast<MemoryEffectOpInterface>(op);
244 if (llvm::isa<SideEffects::AutomaticAllocationScopeResource>(
245 effect->getResource())) {
262 Operation *lhsAllocScope =
nullptr, *rhsAllocScope =
nullptr;
263 std::optional<MemoryEffects::EffectInstance> lhsAlloc, rhsAlloc;
293 if (lhsHasAlloc == rhsHasAlloc) {
305 lhsAllocScope = rhsAllocScope;
317 if (rhsParentOp == lhsAllocScope) {
341 if (lhsValues.empty() || rhsValues.empty())
345 std::optional<AliasResult> result;
346 for (
Value lhsVal : lhsValues) {
347 for (
Value rhsVal : rhsValues) {
349 result = result ? result->merge(nextResult) : nextResult;
373 MemoryEffectOpInterface
interface = dyn_cast<MemoryEffectOpInterface>(op);
380 interface.getEffects(effects);
384 if (isa<MemoryEffects::Allocate, MemoryEffects::Free>(effect.getEffect()))
390 if (
Value effectValue = effect.getValue())
391 aliasResult =
alias(effectValue, location);
394 if (aliasResult.
isNo())
398 if (isa<MemoryEffects::Read>(effect.getEffect())) {
401 assert(isa<MemoryEffects::Write>(effect.getEffect()));
static LogicalResult getAllocEffectFor(Value value, std::optional< MemoryEffects::EffectInstance > &effect, Operation *&allocScopeOp)
Given a value, try to get an allocation effect attached to it.
static void collectUnderlyingAddressValues(Value value, unsigned maxDepth, DenseSet< Value > &visited, SmallVectorImpl< Value > &output)
Given a value, collect all of the underlying values being addressed.
static constexpr unsigned maxUnderlyingValueSearchDepth
The maximum depth that will be searched when trying to find an underlying value.
The possible results of an alias query.
bool isNo() const
Returns if this result indicates no possibility of aliasing.
@ MustAlias
The two locations precisely alias each other.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
Attributes are known-constant values of operations.
This class represents an argument of a Block.
Block * getOwner() const
Returns the block that owns this argument.
unsigned getArgNumber() const
Returns the number of this argument.
Block represents an ordered list of Operations.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
pred_iterator pred_begin()
bool isEntryBlock()
Return if this block is the entry block in the parent region.
ModRefResult getModRef(Operation *op, Value location)
Return the modify-reference behavior of op on location.
virtual AliasResult aliasImpl(Value lhs, Value rhs)
Given the two values, return their aliasing behavior.
AliasResult alias(Value lhs, Value rhs)
Given two values, return their aliasing behavior.
The possible results of whether a memory access modifies or references a memory location.
bool isModAndRef() const
Returns if this result modifies and references memory.
ModRefResult merge(const ModRefResult &other)
Merge this ModRef result with other and return the result.
static ModRefResult getRef()
Return a new result that indicates that the memory access may reference the value stored in memory.
static ModRefResult getNoModRef()
Return a new result that indicates that the memory access neither references nor modifies the value s...
static ModRefResult getModAndRef()
Return a new result that indicates that the memory access may reference and may modify the value stor...
static ModRefResult getMod()
Return a new result that indicates that the memory access may modify the value stored in memory.
This is a value defined by a result of an operation.
Operation * getOwner() const
Returns the operation that owns this result.
unsigned getResultNumber() const
Returns the number of this result.
A trait of region holding operations that define a new scope for automatic allocations,...
This trait indicates that the memory effects of an operation includes the effects of operations neste...
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
This class represents a point being branched from in the methods of the RegionBranchOpInterface.
static constexpr RegionBranchPoint parent()
Returns an instance of RegionBranchPoint representing the parent operation.
This class represents a successor of a region.
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.
This class represents a specific instance of an effect.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Block * getParentBlock()
Return the Block in which this Value is defined.
Region * getParentRegion()
Return the Region in which this Value is defined.
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.
The following effect indicates that the operation allocates from some resource.