| //===- Dominance.cpp - Dominator analysis for CFG Functions ---------------===// |
| // |
| // Copyright 2019 The MLIR Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // ============================================================================= |
| // |
| // Implementation of dominance related classes and instantiations of extern |
| // templates. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "mlir/Analysis/Dominance.h" |
| #include "llvm/Support/GenericDomTreeConstruction.h" |
| using namespace mlir; |
| |
| template class llvm::DominatorTreeBase<BasicBlock, false>; |
| template class llvm::DominatorTreeBase<BasicBlock, true>; |
| template class llvm::DomTreeNodeBase<BasicBlock>; |
| |
| /// Compute the immediate-dominators map. |
| DominanceInfo::DominanceInfo(CFGFunction *function) : DominatorTreeBase() { |
| // Build the dominator tree for the function. |
| recalculate(*function); |
| } |
| |
| /// Return true if instruction A properly dominates instruction B. |
| bool DominanceInfo::properlyDominates(const Instruction *a, |
| const Instruction *b) { |
| auto *aBlock = a->getBlock(), *bBlock = b->getBlock(); |
| |
| // If the blocks are different, it's as easy as whether A's block |
| // dominates B's block. |
| if (aBlock != bBlock) |
| return properlyDominates(a->getBlock(), b->getBlock()); |
| |
| // If a/b are the same, then they don't properly dominate each other. |
| if (a == b) |
| return false; |
| |
| // If one is a terminator, then the other dominates it. |
| auto *aOp = dyn_cast<OperationInst>(a); |
| if (!aOp) |
| return false; |
| |
| auto *bOp = dyn_cast<OperationInst>(b); |
| if (!bOp) |
| return true; |
| |
| // Otherwise, do a linear scan to determine whether B comes after A. |
| auto aIter = BasicBlock::const_iterator(aOp); |
| auto bIter = BasicBlock::const_iterator(bOp); |
| auto fIter = aBlock->begin(); |
| while (bIter != fIter) { |
| --bIter; |
| if (aIter == bIter) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /// Return true if value A properly dominates instruction B. |
| bool DominanceInfo::properlyDominates(const SSAValue *a, const Instruction *b) { |
| if (auto *aInst = a->getDefiningInst()) |
| return properlyDominates(aInst, b); |
| |
| // bbarguments properly dominate all instructions in their own block, so we |
| // use a dominates check here, not a properlyDominates check. |
| return dominates(cast<BBArgument>(a)->getOwner(), b->getBlock()); |
| } |