17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/Support/GenericDomTreeConstruction.h" 23 template class llvm::DominatorTreeBase<
Block,
false>;
24 template class llvm::DominatorTreeBase<
Block,
true>;
25 template class llvm::DomTreeNodeBase<Block>;
31 template <
bool IsPostDom>
33 for (
auto entry : dominanceInfos)
34 delete entry.second.getPointer();
40 template <
bool IsPostDom>
42 bool needsDomTree)
const 43 -> llvm::PointerIntPair<DomTree *, 1, bool> {
45 auto itAndInserted = dominanceInfos.insert({region, {
nullptr,
true}});
46 auto &entry = itAndInserted.first->second;
51 if (!itAndInserted.second) {
54 if (needsDomTree && !entry.getPointer() && !region->hasOneBlock()) {
55 auto *domTree =
new DomTree();
56 domTree->recalculate(*region);
57 entry.setPointer(domTree);
64 if (!region->hasOneBlock()) {
65 auto *domTree =
new DomTree();
66 domTree->recalculate(*region);
67 entry.setPointer(domTree);
74 if (!parentOp->isRegistered()) {
76 }
else if (
auto regionKindItf = dyn_cast<RegionKindInterface>(parentOp)) {
79 entry.setInt(regionKindItf.hasSSADominance(region->getRegionNumber()));
90 return ancestorOp->getBlock();
99 template <
typename FuncT>
116 if (aRegion == bRegion)
122 size_t aRegionDepth = 0;
134 size_t bRegionDepth = 0;
146 if (aRegionDepth > bRegionDepth) {
149 }
else if (aRegionDepth < bRegionDepth) {
174 template <
bool IsPostDom>
197 return getDomTree(a->
getParent()).findNearestCommonDominator(a, b);
201 template <
bool IsPostDom>
203 assert(a && b &&
"null blocks not allowed");
226 return getDomTree(regionA).properlyDominates(a, b);
231 template <
bool IsPostDom>
235 if (®ion->
front() == a)
239 return getDomTree(region).isReachableFromEntry(a);
253 bool enclosingOpOk)
const {
255 assert(aBlock && bBlock &&
"operations must be in a block");
260 return !hasSSADominance(aBlock);
264 if (aRegion != bBlock->getParent()) {
271 assert(bBlock->getParent() == aRegion);
274 if (a == b && enclosingOpOk)
279 if (aBlock == bBlock) {
283 if (hasSSADominance(aBlock)) {
291 return getDomTree(aRegion).properlyDominates(aBlock, bBlock);
301 return dominates(blockArg.getOwner(), b->
getBlock());
315 assert(aBlock && bBlock &&
"operations must be in a block");
320 return !hasSSADominance(aBlock);
323 Region *aRegion = aBlock->getParent();
324 if (aRegion != bBlock->getParent()) {
331 assert(bBlock->getParent() == aRegion);
340 if (aBlock == bBlock) {
342 if (hasSSADominance(aBlock)) {
350 return getDomTree(aRegion).properlyDominates(aBlock, bBlock);
bool properlyDominates(Operation *a, Operation *b, bool enclosingOpOk=true) const
Return true if operation A properly dominates operation B, i.e.
Include the generated interface declarations.
This class contains a list of basic blocks and a link to the parent operation it is attached to...
bool properlyDominates(Block *a, Block *b) const
Return true if the specified block A properly dominates block B.
Operation is a basic unit of execution within MLIR.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
Block represents an ordered list of Operations.
static Block * getAncestorBlock(Block *block)
Return the ancestor block enclosing the specified block.
bool isBeforeInBlock(Operation *other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
bool properlyPostDominates(Operation *a, Operation *b)
Return true if operation A properly postdominates operation B.
Block * getBlock()
Returns the operation block that contains this operation.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
static bool tryGetBlocksInSameRegion(Block *&a, Block *&b)
Tries to update the given block references to live in the same region by exploring the relationship o...
llvm::PointerIntPair< DomTree *, 1, bool > getDominanceInfo(Region *region, bool needsDomTree) const
Return the dom tree and "hasSSADominance" bit for the given region.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
This class represents an argument of a Block.
Operation * findAncestorOpInRegion(Operation &op)
Returns 'op' if 'op' lies in this region, or otherwise finds the ancestor of 'op' that lies in this r...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
bool isReachableFromEntry(Block *a) const
Return true if the specified block is reachable from the entry block of its region.
Block * findAncestorBlockInRegion(Block &block)
Returns 'block' if 'block' lies in this region, or otherwise finds the ancestor of 'block' that lies ...
static Block * traverseAncestors(Block *block, const FuncT &func)
Walks up the list of containers of the given block and calls the user-defined traversal function for ...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Block * findNearestCommonDominator(Block *a, Block *b) const
Finds the nearest common dominator block for the two given blocks a and b.