17#include "llvm/Support/GenericDomTreeConstruction.h"
22template class llvm::DominatorTreeBase<
Block,
false>;
23template class llvm::DominatorTreeBase<
Block,
true>;
24template class llvm::DomTreeNodeBase<Block>;
30template <
bool IsPostDom>
33 delete entry.second.getPointer();
36template <
bool IsPostDom>
39 delete entry.second.getPointer();
43template <
bool IsPostDom>
48 delete it->second.getPointer();
53 region->
walk([&](
Region *r) { invalidate(r); });
61template <
bool IsPostDom>
63 bool needsDomTree)
const
64 -> llvm::PointerIntPair<DomTree *, 1, bool> {
66 auto itAndInserted =
dominanceInfos.insert({region, {
nullptr,
true}});
67 auto &entry = itAndInserted.first->second;
72 if (!itAndInserted.second) {
75 if (needsDomTree && !entry.getPointer() && !region->
hasOneBlock()) {
76 auto *domTree =
new DomTree();
77 domTree->recalculate(*region);
78 entry.setPointer(domTree);
86 auto *domTree =
new DomTree();
87 domTree->recalculate(*region);
88 entry.setPointer(domTree);
95 if (!parentOp->isRegistered()) {
97 }
else if (
auto regionKindItf = dyn_cast<RegionKindInterface>(parentOp)) {
100 entry.setInt(regionKindItf.hasSSADominance(region->
getRegionNumber()));
111 return ancestorOp->getBlock();
120template <
typename FuncT>
136 Region *bRegion =
b->getParent();
137 if (aRegion == bRegion)
143 size_t aRegionDepth = 0;
155 size_t bRegionDepth = 0;
167 if (aRegionDepth > bRegionDepth) {
170 }
else if (aRegionDepth < bRegionDepth) {
195template <
bool IsPostDom>
228static std::pair<Block *, Block::iterator>
231 if (
b->getParent() == r)
232 return std::make_pair(
b, it);
241 return std::make_pair(op->
getBlock(), op->getIterator());
251 if (a == block->
end())
253 if (
b == block->
end())
255 return a->isBeforeInBlock(&*
b);
258template <
bool IsPostDom>
261 bool enclosingOk)
const {
262 assert(aBlock && bBlock &&
"expected non-null blocks");
266 if (aBlock == bBlock && aIt == bIt)
267 return !hasSSADominance(aBlock);
279 std::tie(bBlock, bIt) =
284 assert(bBlock->
getParent() == aRegion &&
"expected block in regionA");
287 if (aBlock == bBlock && aIt == bIt && enclosingOk)
292 if (aBlock == bBlock) {
296 if (!hasSSADominance(aBlock))
298 if constexpr (IsPostDom) {
299 return isBeforeInBlock(aBlock, bIt, aIt);
301 return isBeforeInBlock(aBlock, aIt, bIt);
306 return getDomTree(aRegion).properlyDominates(aBlock, bBlock);
311template <
bool IsPostDom>
315 if (®ion->
front() == a)
319 return getDomTree(region).isReachableFromEntry(a);
330 bool enclosingOpOk)
const {
332 b->getBlock(),
b->getIterator(),
347 if (
auto blockArg = dyn_cast<BlockArgument>(a))
348 return dominates(blockArg.getOwner(),
b->getBlock());
360 bool enclosingOpOk)
const {
362 b->getBlock(),
b->getIterator(),
static Block * getAncestorBlock(Block *block)
Return the ancestor block enclosing the specified block.
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...
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 ...
static std::pair< Block *, Block::iterator > findAncestorIteratorInRegion(Region *r, Block *b, Block::iterator it)
Returns the given block iterator if it lies within the region region.
Block represents an ordered list of Operations.
OpListType::iterator iterator
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
bool properlyDominates(Operation *a, Operation *b, bool enclosingOpOk=true) const
Return true if operation A properly dominates operation B, i.e.
bool dominates(Operation *a, Operation *b) const
Return true if operation A dominates operation B, i.e.
Operation is the basic unit of execution within MLIR.
Block * getBlock()
Returns the operation block that contains this operation.
bool properlyPostDominates(Operation *a, Operation *b, bool enclosingOpOk=true) const
Return true if operation A properly postdominates operation B.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Operation * findAncestorOpInRegion(Operation &op)
Returns 'op' if 'op' lies in this region, or otherwise finds the ancestor of 'op' that lies in this r...
unsigned getRegionNumber()
Return the number of this region in the parent operation.
Operation * getParentOp()
Return the parent operation this region is attached to.
bool hasOneBlock()
Return true if this region has exactly one block.
RetT walk(FnT &&callback)
Walk all nested operations, blocks or regions (including this region), depending on the type of callb...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
llvm::PointerIntPair< DomTree *, 1, bool > getDominanceInfo(Region *region, bool needsDomTree) const
Return the dom tree and "hasSSADominance" bit for the given region.
DenseMap< Region *, llvm::PointerIntPair< DomTree *, 1, bool > > dominanceInfos
A mapping of regions to their base dominator tree and a cached "hasSSADominance" bit.
DomTree & getDomTree(Region *region) const
bool isReachableFromEntry(Block *a) const
Return true if the specified block is reachable from the entry block of its region.
bool properlyDominatesImpl(Block *aBlock, Block::iterator aIt, Block *bBlock, Block::iterator bIt, bool enclosingOk=true) const
Return "true" if block iterator A properly (post)dominates block iterator B.
Block * findNearestCommonDominator(Block *a, Block *b) const
Finds the nearest common dominator block for the two given blocks a and b.
void invalidate()
Invalidate dominance info.
Include the generated interface declarations.