Skip to content

Commit 553f885

Browse files
authored
[DomTree] Reduce number of hash table lookups (NFC) (llvm#73097)
Inside runSemiNCA(), create a direct mapping from node number of node info, so we can save the node number -> node pointer -> node info lookup in many cases. To allow this in more cases, change Label to a node number instead of node pointer. I've limited this to runSemiNCA() for now, because we have the convenient property there that no new node infos will be added, so we don't have to worry about pointer invalidation. This gives a pretty nice compile-time improvement of about 0.4%.
1 parent 295edaa commit 553f885

File tree

1 file changed

+15
-15
lines changed

1 file changed

+15
-15
lines changed

llvm/include/llvm/Support/GenericDomTreeConstruction.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct SemiNCAInfo {
6565
unsigned DFSNum = 0;
6666
unsigned Parent = 0;
6767
unsigned Semi = 0;
68-
NodePtr Label = nullptr;
68+
unsigned Label = 0;
6969
NodePtr IDom = nullptr;
7070
SmallVector<NodePtr, 2> ReverseChildren;
7171
};
@@ -189,8 +189,7 @@ struct SemiNCAInfo {
189189

190190
// Visited nodes always have positive DFS numbers.
191191
if (BBInfo.DFSNum != 0) continue;
192-
BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
193-
BBInfo.Label = BB;
192+
BBInfo.DFSNum = BBInfo.Semi = BBInfo.Label = ++LastNum;
194193
NumToNode.push_back(BB);
195194

196195
constexpr bool Direction = IsReverse != IsPostDom; // XOR.
@@ -237,8 +236,9 @@ struct SemiNCAInfo {
237236
//
238237
// For each vertex V, its Label points to the vertex with the minimal sdom(U)
239238
// (Semi) in its path from V (included) to NodeToInfo[V].Parent (excluded).
240-
NodePtr eval(NodePtr V, unsigned LastLinked,
241-
SmallVectorImpl<InfoRec *> &Stack) {
239+
unsigned eval(NodePtr V, unsigned LastLinked,
240+
SmallVectorImpl<InfoRec *> &Stack,
241+
ArrayRef<InfoRec *> NumToInfo) {
242242
InfoRec *VInfo = &NodeToInfo[V];
243243
if (VInfo->Parent < LastLinked)
244244
return VInfo->Label;
@@ -247,17 +247,17 @@ struct SemiNCAInfo {
247247
assert(Stack.empty());
248248
do {
249249
Stack.push_back(VInfo);
250-
VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
250+
VInfo = NumToInfo[VInfo->Parent];
251251
} while (VInfo->Parent >= LastLinked);
252252

253253
// Path compression. Point each vertex's Parent to the root and update its
254254
// Label if any of its ancestors (PInfo->Label) has a smaller Semi.
255255
const InfoRec *PInfo = VInfo;
256-
const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
256+
const InfoRec *PLabelInfo = NumToInfo[PInfo->Label];
257257
do {
258258
VInfo = Stack.pop_back_val();
259259
VInfo->Parent = PInfo->Parent;
260-
const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
260+
const InfoRec *VLabelInfo = NumToInfo[VInfo->Label];
261261
if (PLabelInfo->Semi < VLabelInfo->Semi)
262262
VInfo->Label = PInfo->Label;
263263
else
@@ -270,18 +270,20 @@ struct SemiNCAInfo {
270270
// This function requires DFS to be run before calling it.
271271
void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
272272
const unsigned NextDFSNum(NumToNode.size());
273+
SmallVector<InfoRec *, 8> NumToInfo = {nullptr};
274+
NumToInfo.reserve(NextDFSNum);
273275
// Initialize IDoms to spanning tree parents.
274276
for (unsigned i = 1; i < NextDFSNum; ++i) {
275277
const NodePtr V = NumToNode[i];
276278
auto &VInfo = NodeToInfo[V];
277279
VInfo.IDom = NumToNode[VInfo.Parent];
280+
NumToInfo.push_back(&VInfo);
278281
}
279282

280283
// Step #1: Calculate the semidominators of all vertices.
281284
SmallVector<InfoRec *, 32> EvalStack;
282285
for (unsigned i = NextDFSNum - 1; i >= 2; --i) {
283-
NodePtr W = NumToNode[i];
284-
auto &WInfo = NodeToInfo[W];
286+
auto &WInfo = *NumToInfo[i];
285287

286288
// Initialize the semi dominator to point to the parent node.
287289
WInfo.Semi = WInfo.Parent;
@@ -294,7 +296,7 @@ struct SemiNCAInfo {
294296
if (TN && TN->getLevel() < MinLevel)
295297
continue;
296298

297-
unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
299+
unsigned SemiU = NumToInfo[eval(N, i + 1, EvalStack, NumToInfo)]->Semi;
298300
if (SemiU < WInfo.Semi) WInfo.Semi = SemiU;
299301
}
300302
}
@@ -304,8 +306,7 @@ struct SemiNCAInfo {
304306
// Note that the parents were stored in IDoms and later got invalidated
305307
// during path compression in Eval.
306308
for (unsigned i = 2; i < NextDFSNum; ++i) {
307-
const NodePtr W = NumToNode[i];
308-
auto &WInfo = NodeToInfo[W];
309+
auto &WInfo = *NumToInfo[i];
309310
const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
310311
NodePtr WIDomCandidate = WInfo.IDom;
311312
while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
@@ -325,8 +326,7 @@ struct SemiNCAInfo {
325326
assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed");
326327

327328
auto &BBInfo = NodeToInfo[nullptr];
328-
BBInfo.DFSNum = BBInfo.Semi = 1;
329-
BBInfo.Label = nullptr;
329+
BBInfo.DFSNum = BBInfo.Semi = BBInfo.Label = 1;
330330

331331
NumToNode.push_back(nullptr); // NumToNode[1] = nullptr;
332332
}

0 commit comments

Comments
 (0)