Skip to content

Commit 62c20d8

Browse files
author
Justin Lebar
committedNov 28, 2016
[StructurizeCFG] Refactor NearestCommonDominator.
Summary: As far as I can tell, doing our own computations in NearestCommonDominator is a false optimization -- DomTree will build up what appears to be exactly this data when it decides it's worthwhile. Moreover, by building the cache ourselves, we cannot take advantage of the cache that the domtree might have available. In addition, I am not convinced of the correctness of the original code. In particular, setting ResultIndex = 1 on the first addBlock instead of setting it to 0 is quite fishy. Similarly, it's not clear to me that setting IndexMap[Node] = 0 for every node as we walk up the tree finding a common parent is correct. But rather than ponder over these questions, I'd rather just make the code do the obviously-correct thing. This patch also changes the NearestCommonDominator API a bit, improving the names and getting rid of the boolean parameter in addBlock -- see http://jlebar.com/2011/12/16/Boolean_parameters_to_API_functions_considered_harmful..html Reviewers: arsenm Subscribers: aemerson, wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D26998 llvm-svn: 288050
1 parent 2228f70 commit 62c20d8

File tree

1 file changed

+37
-56
lines changed

1 file changed

+37
-56
lines changed
 

‎llvm/lib/Transforms/Scalar/StructurizeCFG.cpp

+37-56
Original file line numberDiff line numberDiff line change
@@ -43,77 +43,58 @@ typedef SmallPtrSet<BasicBlock *, 8> BBSet;
4343
typedef MapVector<PHINode *, BBValueVector> PhiMap;
4444
typedef MapVector<BasicBlock *, BBVector> BB2BBVecMap;
4545

46-
typedef DenseMap<DomTreeNode *, unsigned> DTN2UnsignedMap;
4746
typedef DenseMap<BasicBlock *, PhiMap> BBPhiMap;
4847
typedef DenseMap<BasicBlock *, Value *> BBPredicates;
4948
typedef DenseMap<BasicBlock *, BBPredicates> PredMap;
5049
typedef DenseMap<BasicBlock *, BasicBlock*> BB2BBMap;
5150

5251
// The name for newly created blocks.
53-
5452
static const char *const FlowBlockName = "Flow";
5553

56-
/// @brief Find the nearest common dominator for multiple BasicBlocks
54+
/// Finds the nearest common dominator of a set of BasicBlocks.
5755
///
58-
/// Helper class for StructurizeCFG
59-
/// TODO: Maybe move into common code
56+
/// For every BB you add to the set, you can specify whether we "remember" the
57+
/// block. When you get the common dominator, you can also ask whether it's one
58+
/// of the blocks we remembered.
6059
class NearestCommonDominator {
6160
DominatorTree *DT;
61+
BasicBlock *Result = nullptr;
62+
bool ResultIsRemembered = false;
6263

63-
DTN2UnsignedMap IndexMap;
64-
65-
BasicBlock *Result;
66-
unsigned ResultIndex;
67-
bool ExplicitMentioned;
68-
69-
public:
70-
/// \brief Start a new query
71-
NearestCommonDominator(DominatorTree *DomTree) {
72-
DT = DomTree;
73-
Result = nullptr;
74-
}
75-
76-
/// \brief Add BB to the resulting dominator
77-
void addBlock(BasicBlock *BB, bool Remember = true) {
78-
DomTreeNode *Node = DT->getNode(BB);
79-
64+
/// Add BB to the resulting dominator.
65+
void addBlock(BasicBlock *BB, bool Remember) {
8066
if (!Result) {
81-
unsigned Numbering = 0;
82-
for (;Node;Node = Node->getIDom())
83-
IndexMap[Node] = ++Numbering;
8467
Result = BB;
85-
ResultIndex = 1;
86-
ExplicitMentioned = Remember;
68+
ResultIsRemembered = Remember;
8769
return;
8870
}
8971

90-
for (;Node;Node = Node->getIDom())
91-
if (IndexMap.count(Node))
92-
break;
93-
else
94-
IndexMap[Node] = 0;
72+
BasicBlock *NewResult = DT->findNearestCommonDominator(Result, BB);
73+
if (NewResult != Result)
74+
ResultIsRemembered = false;
75+
if (NewResult == BB)
76+
ResultIsRemembered |= Remember;
77+
Result = NewResult;
78+
}
9579

96-
assert(Node && "Dominator tree invalid!");
80+
public:
81+
explicit NearestCommonDominator(DominatorTree *DomTree) : DT(DomTree) {}
9782

98-
unsigned Numbering = IndexMap[Node];
99-
if (Numbering > ResultIndex) {
100-
Result = Node->getBlock();
101-
ResultIndex = Numbering;
102-
ExplicitMentioned = Remember && (Result == BB);
103-
} else if (Numbering == ResultIndex) {
104-
ExplicitMentioned |= Remember;
105-
}
83+
void addBlock(BasicBlock *BB) {
84+
addBlock(BB, /* Remember = */ false);
10685
}
10786

108-
/// \brief Is "Result" one of the BBs added with "Remember" = True?
109-
bool wasResultExplicitMentioned() {
110-
return ExplicitMentioned;
87+
void addAndRememberBlock(BasicBlock *BB) {
88+
addBlock(BB, /* Remember = */ true);
11189
}
11290

113-
/// \brief Get the query result
114-
BasicBlock *getResult() {
115-
return Result;
116-
}
91+
/// Get the nearest common dominator of all the BBs added via addBlock() and
92+
/// addAndRememberBlock().
93+
BasicBlock *result() { return Result; }
94+
95+
/// Is the BB returned by getResult() one of the blocks we added to the set
96+
/// with addAndRememberBlock()?
97+
bool resultIsRememberedBlock() { return ResultIsRemembered; }
11798
};
11899

119100
/// @brief Transforms the control flow graph on one single entry/exit region
@@ -517,7 +498,7 @@ void StructurizeCFG::insertConditions(bool Loops) {
517498
BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
518499

519500
NearestCommonDominator Dominator(DT);
520-
Dominator.addBlock(Parent, false);
501+
Dominator.addBlock(Parent);
521502

522503
Value *ParentValue = nullptr;
523504
for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
@@ -528,14 +509,14 @@ void StructurizeCFG::insertConditions(bool Loops) {
528509
break;
529510
}
530511
PhiInserter.AddAvailableValue(PI->first, PI->second);
531-
Dominator.addBlock(PI->first);
512+
Dominator.addAndRememberBlock(PI->first);
532513
}
533514

534515
if (ParentValue) {
535516
Term->setCondition(ParentValue);
536517
} else {
537-
if (!Dominator.wasResultExplicitMentioned())
538-
PhiInserter.AddAvailableValue(Dominator.getResult(), Default);
518+
if (!Dominator.resultIsRememberedBlock())
519+
PhiInserter.AddAvailableValue(Dominator.result(), Default);
539520

540521
Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent));
541522
}
@@ -590,15 +571,15 @@ void StructurizeCFG::setPhiValues() {
590571
Updater.AddAvailableValue(To, Undef);
591572

592573
NearestCommonDominator Dominator(DT);
593-
Dominator.addBlock(To, false);
574+
Dominator.addBlock(To);
594575
for (const auto &VI : PI.second) {
595576

596577
Updater.AddAvailableValue(VI.first, VI.second);
597-
Dominator.addBlock(VI.first);
578+
Dominator.addAndRememberBlock(VI.first);
598579
}
599580

600-
if (!Dominator.wasResultExplicitMentioned())
601-
Updater.AddAvailableValue(Dominator.getResult(), Undef);
581+
if (!Dominator.resultIsRememberedBlock())
582+
Updater.AddAvailableValue(Dominator.result(), Undef);
602583

603584
for (BasicBlock *FI : From) {
604585

0 commit comments

Comments
 (0)
Please sign in to comment.