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();
37 template <
bool IsPostDom>
39 for (
auto entry : dominanceInfos)
40 delete entry.second.getPointer();
41 dominanceInfos.clear();
44 template <
bool IsPostDom>
46 auto it = dominanceInfos.find(region);
47 if (it != dominanceInfos.end()) {
48 delete it->second.getPointer();
49 dominanceInfos.erase(it);
56 template <
bool IsPostDom>
58 bool needsDomTree)
const
59 -> llvm::PointerIntPair<DomTree *, 1, bool> {
61 auto itAndInserted = dominanceInfos.insert({region, {
nullptr,
true}});
62 auto &entry = itAndInserted.first->second;
67 if (!itAndInserted.second) {
70 if (needsDomTree && !entry.getPointer() && !region->
hasOneBlock()) {
71 auto *domTree =
new DomTree();
72 domTree->recalculate(*region);
73 entry.setPointer(domTree);
81 auto *domTree =
new DomTree();
82 domTree->recalculate(*region);
83 entry.setPointer(domTree);
90 if (!parentOp->isRegistered()) {
92 }
else if (
auto regionKindItf = dyn_cast<RegionKindInterface>(parentOp)) {
106 return ancestorOp->getBlock();
115 template <
typename FuncT>
132 if (aRegion == bRegion)
138 size_t aRegionDepth = 0;
150 size_t bRegionDepth = 0;
162 if (aRegionDepth > bRegionDepth) {
165 }
else if (aRegionDepth < bRegionDepth) {
190 template <
bool IsPostDom>
213 return getDomTree(a->
getParent()).findNearestCommonDominator(a, b);
223 static std::pair<Block *, Block::iterator>
227 return std::make_pair(b, it);
233 Operation *op = r->findAncestorOpInRegion(*parentOp);
236 return std::make_pair(op->
getBlock(), op->getIterator());
246 if (a == block->
end())
248 if (b == block->
end())
250 return a->isBeforeInBlock(&*b);
253 template <
bool IsPostDom>
256 bool enclosingOk)
const {
257 assert(aBlock && bBlock &&
"expected non-null blocks");
261 if (aBlock == bBlock && aIt == bIt)
262 return !hasSSADominance(aBlock);
274 std::tie(bBlock, bIt) =
279 assert(bBlock->
getParent() == aRegion &&
"expected block in regionA");
282 if (aBlock == bBlock && aIt == bIt && enclosingOk)
287 if (aBlock == bBlock) {
291 if (!hasSSADominance(aBlock))
293 if constexpr (IsPostDom) {
301 return getDomTree(aRegion).properlyDominates(aBlock, bBlock);
306 template <
bool IsPostDom>
310 if (®ion->
front() == a)
314 return getDomTree(region).isReachableFromEntry(a);
325 bool enclosingOpOk)
const {
326 return super::properlyDominatesImpl(a->
getBlock(), a->getIterator(),
332 return super::properlyDominatesImpl(a, a->
begin(), b, b->
begin(),
342 if (
auto blockArg = dyn_cast<BlockArgument>(a))
343 return dominates(blockArg.getOwner(), b->
getBlock());
355 bool enclosingOpOk)
const {
356 return super::properlyDominatesImpl(a->
getBlock(), a->getIterator(),
362 return super::properlyDominatesImpl(a, a->
end(), b, b->
end(),
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 bool isBeforeInBlock(Block *block, Block::iterator a, Block::iterator b)
Given two iterators into the same block, return "true" if a is before `b.
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.
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 * getAncestorBlock(Block *block)
Return the ancestor block enclosing the specified block.
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.
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.
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.
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.
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.