26 #include "llvm/Support/Casting.h"
60 auto getOperandIndexIfPred =
63 branch.getSuccessorRegions(pred, successors);
65 if (successor.getSuccessor() != region)
68 ValueRange inputs = successor.getSuccessorInputs();
70 output.push_back(inputValue);
73 unsigned firstInputIndex, lastInputIndex;
75 firstInputIndex = cast<BlockArgument>(inputs[0]).getArgNumber();
76 lastInputIndex = cast<BlockArgument>(inputs.back()).getArgNumber();
78 firstInputIndex = cast<OpResult>(inputs[0]).getResultNumber();
79 lastInputIndex = cast<OpResult>(inputs.back()).getResultNumber();
81 if (firstInputIndex > inputIndex || lastInputIndex < inputIndex) {
82 output.push_back(inputValue);
85 return inputIndex - firstInputIndex;
95 if (std::optional<unsigned> operandIndex =
98 branch.getEntrySuccessorOperands(branchPoint)[*operandIndex], maxDepth,
104 if (std::optional<unsigned> operandIndex = getOperandIndexIfPred(region)) {
105 for (
Block &block : region) {
108 if (
auto term = dyn_cast<RegionBranchTerminatorOpInterface>(
109 block.getTerminator())) {
111 term.getSuccessorOperands(branchPoint)[*operandIndex], maxDepth,
113 }
else if (block.getNumSuccessors()) {
116 output.push_back(inputValue);
131 if (ViewLikeOpInterface view = dyn_cast<ViewLikeOpInterface>(op))
135 if (
auto branch = dyn_cast<RegionBranchOpInterface>(op)) {
141 output.push_back(result);
155 auto branch = dyn_cast<BranchOpInterface>((*it)->getTerminator());
158 output.push_back(arg);
163 unsigned index = it.getSuccessorIndex();
164 Value operand = branch.getSuccessorOperands(index)[argNumber];
167 output.push_back(arg);
178 if (
auto branch = dyn_cast<RegionBranchOpInterface>(op)) {
180 maxDepth, visited, output);
184 output.push_back(arg);
192 if (!visited.insert(value).second)
195 output.push_back(value);
226 std::optional<MemoryEffects::EffectInstance> &effect,
233 op = cast<OpResult>(value).getOwner();
234 MemoryEffectOpInterface
interface = dyn_cast<MemoryEffectOpInterface>(op);
245 if (llvm::isa<SideEffects::AutomaticAllocationScopeResource>(
246 effect->getResource())) {
263 Operation *lhsAllocScope =
nullptr, *rhsAllocScope =
nullptr;
264 std::optional<MemoryEffects::EffectInstance> lhsAlloc, rhsAlloc;
294 if (lhsHasAlloc == rhsHasAlloc) {
306 lhsAllocScope = rhsAllocScope;
318 if (rhsParentOp == lhsAllocScope) {
342 if (lhsValues.empty() || rhsValues.empty())
346 std::optional<AliasResult> result;
347 for (
Value lhsVal : lhsValues) {
348 for (
Value rhsVal : rhsValues) {
350 result = result ? result->merge(nextResult) : nextResult;
374 MemoryEffectOpInterface
interface = dyn_cast<MemoryEffectOpInterface>(op);
381 interface.getEffects(effects);
385 if (isa<MemoryEffects::Allocate, MemoryEffects::Free>(effect.getEffect()))
391 if (
Value effectValue = effect.getValue())
392 aliasResult =
alias(effectValue, location);
395 if (aliasResult.
isNo())
399 if (isa<MemoryEffects::Read>(effect.getEffect())) {
402 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.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
This class represents an efficient way to signal success or failure.
The following effect indicates that the operation allocates from some resource.