using DomSetType = typename DominanceFrontierBase<BlockT, false>::DomSetType;
void analyze(DomTreeT &DT) {
- assert(DT.getRoots().size() == 1 &&
+ assert(DT.root_size() == 1 &&
"Only one entry block for forward domfronts!");
this->Roots = {DT.getRoot()};
calculate(DT, DT[this->Roots[0]]);
void getAnalysisUsage(AnalysisUsage &AU) const override;
- /// getRoots - Return the root blocks of the current CFG. This may include
- /// multiple blocks if we are computing post dominators. For forward
- /// dominators, this will always be a single block (the entry node).
- ///
- const SmallVectorImpl<MachineBasicBlock*> &getRoots() const {
- applySplitCriticalEdges();
- return DT->getRoots();
- }
-
MachineBasicBlock *getRoot() const {
applySplitCriticalEdges();
return DT->getRoot();
FunctionPass *createMachinePostDominatorTreePass();
- const SmallVectorImpl<MachineBasicBlock *> &getRoots() const {
- return PDT->getRoots();
- }
-
MachineDomTreeNode *getRootNode() const { return PDT->getRootNode(); }
MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
DominatorTreeBase(const DominatorTreeBase &) = delete;
DominatorTreeBase &operator=(const DominatorTreeBase &) = delete;
- /// getRoots - Return the root blocks of the current CFG. This may include
- /// multiple blocks if we are computing post dominators. For forward
- /// dominators, this will always be a single block (the entry node).
+ /// Iteration over roots.
///
- const SmallVectorImpl<NodeT *> &getRoots() const { return Roots; }
+ /// This may include multiple blocks if we are computing post dominators.
+ /// For forward dominators, this will always be a single block (the entry
+ /// block).
+ using root_iterator = typename SmallVectorImpl<NodeT *>::iterator;
+ using const_root_iterator = typename SmallVectorImpl<NodeT *>::const_iterator;
+
+ root_iterator root_begin() { return Roots.begin(); }
+ const_root_iterator root_begin() const { return Roots.begin(); }
+ root_iterator root_end() { return Roots.end(); }
+ const_root_iterator root_end() const { return Roots.end(); }
+
+ size_t root_size() const { return Roots.size(); }
+
+ iterator_range<root_iterator> roots() {
+ return make_range(root_begin(), root_end());
+ }
+ iterator_range<const_root_iterator> roots() const {
+ return make_range(root_begin(), root_end());
+ }
/// isPostDominator - Returns true if analysis based of postdoms
///
if (!DT.DFSInfoValid || !DT.Parent)
return true;
- const NodePtr RootBB = IsPostDom ? nullptr : DT.getRoots()[0];
+ const NodePtr RootBB = IsPostDom ? nullptr : *DT.root_begin();
const TreeNodePtr Root = DT.getNode(RootBB);
auto PrintNodeAndDFSNums = [](const TreeNodePtr TN) {
// If there's only one exit, we don't need to do anything, unless this is a
// pixel shader and that exit is an infinite loop, since we still have to
// insert an export in that case.
- if (PDT.getRoots().size() <= 1 &&
- F.getCallingConv() != CallingConv::AMDGPU_PS)
+ if (PDT.root_size() <= 1 && F.getCallingConv() != CallingConv::AMDGPU_PS)
return false;
LegacyDivergenceAnalysis &DA = getAnalysis<LegacyDivergenceAnalysis>();
bool InsertExport = false;
bool Changed = false;
- for (BasicBlock *BB : PDT.getRoots()) {
+ for (BasicBlock *BB : PDT.roots()) {
if (isa<ReturnInst>(BB->getTerminator())) {
if (!isUniformlyReached(DA, *BB))
ReturningBlocks.push_back(BB);
if (CommonPred)
WorkList.insert(CommonPred);
else
- for (BasicBlock *R : PDT.getRoots())
+ for (BasicBlock *R : PDT.roots())
WorkList.insert(R);
NumCFGTries++;
BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
PDT.insertEdge(From, To);
EXPECT_TRUE(PDT.verify());
- EXPECT_TRUE(PDT.getRoots().size() == 2);
+ EXPECT_EQ(PDT.root_size(), 2);
// Make sure we can use a const pointer with getNode.
const BasicBlock *BB5 = B.getOrAddBlock("5");
EXPECT_NE(PDT.getNode(BB5), nullptr);