Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 36c02fa

Browse files
committed
Improve SSA dominator computation memory usage
1 parent 6aa9823 commit 36c02fa

File tree

7 files changed

+84
-46
lines changed

7 files changed

+84
-46
lines changed

src/jit/block.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,9 +1202,15 @@ struct JitPtrKeyFuncs<BasicBlock> : public JitKeyFuncsDefEquals<const BasicBlock
12021202
// A set of blocks.
12031203
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, bool> BlkSet;
12041204

1205+
// A vector of blocks.
1206+
typedef jitstd::vector<BasicBlock*> BlkVector;
1207+
12051208
// A map of block -> set of blocks, can be used as sparse block trees.
12061209
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, BlkSet*> BlkToBlkSetMap;
12071210

1211+
// A map of block -> vector of blocks, can be used as sparse block trees.
1212+
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, BlkVector> BlkToBlkVectorMap;
1213+
12081214
// Map from Block to Block. Used for a variety of purposes.
12091215
typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, BasicBlock*> BlockToBlockMap;
12101216

src/jit/compiler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2525
#include "jit.h"
2626
#include "opcode.h"
2727
#include "varset.h"
28+
#include "jitstd.h"
29+
#include "jithashtable.h"
2830
#include "gentree.h"
2931
#include "lir.h"
3032
#include "block.h"
@@ -33,10 +35,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3335
#include "instr.h"
3436
#include "regalloc.h"
3537
#include "sm.h"
36-
#include "jithashtable.h"
3738
#include "cycletimer.h"
3839
#include "blockset.h"
39-
#include "jitstd.h"
4040
#include "arraystack.h"
4141
#include "hashbv.h"
4242
#include "fp.h"

src/jit/copyprop.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ void Compiler::optVnCopyProp()
412412
CompAllocator allocator(this, CMK_CopyProp);
413413

414414
// Compute the domTree to use.
415-
BlkToBlkSetMap* domTree = new (&allocator) BlkToBlkSetMap(&allocator);
415+
BlkToBlkVectorMap* domTree = new (&allocator) BlkToBlkVectorMap(&allocator);
416416
domTree->Reallocate(fgBBcount * 3 / 2); // Prime the allocation
417417
SsaBuilder::ComputeDominators(this, domTree);
418418

@@ -455,12 +455,12 @@ void Compiler::optVnCopyProp()
455455
optBlockCopyProp(block, &curSsaName);
456456

457457
// Add dom children to work on.
458-
BlkSet* pBlkSet;
459-
if (domTree->Lookup(block, &pBlkSet))
458+
BlkVector* domChildren = domTree->LookupPointer(block);
459+
if (domChildren != nullptr)
460460
{
461-
for (BlkSet::KeyIterator child = pBlkSet->Begin(); !child.Equal(pBlkSet->End()); ++child)
461+
for (BasicBlock* child : *domChildren)
462462
{
463-
worklist->push_back(BlockWork(child.Get()));
463+
worklist->push_back(BlockWork(child));
464464
}
465465
}
466466
}

src/jit/gentree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2424
#include "ssaconfig.h" // For "SsaConfig::RESERVED_SSA_NUM"
2525
#include "reglist.h"
2626
#include "valuenumtype.h"
27+
#include "jitstd.h"
2728
#include "jithashtable.h"
2829
#include "nodeinfo.h"
2930
#include "simd.h"

src/jit/jithashtable.h

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,47 @@ class JitHashTable
264264
}
265265
else
266266
{
267-
Node* pNewNode = new (m_alloc) Node(k, v, m_table[index]);
267+
Node* pNewNode = new (m_alloc) Node(m_table[index], k, v);
268268
m_table[index] = pNewNode;
269269
m_tableCount++;
270270
return false;
271271
}
272272
}
273273

274+
//------------------------------------------------------------------------
275+
// Emplace: Associates the specified key with a value constructed in-place
276+
// using the supplies args if the key is not already present.
277+
//
278+
// Arguments:
279+
// k - the key
280+
// args - the args used to construct the value
281+
//
282+
// Return Value:
283+
// A pointer to the existing or newly constructed value.
284+
//
285+
template <class... Args>
286+
Value* Emplace(Key k, Args&&... args)
287+
{
288+
CheckGrowth();
289+
290+
assert(m_tableSizeInfo.prime != 0);
291+
292+
unsigned index = GetIndexForKey(k);
293+
294+
Node* pN = m_table[index];
295+
while ((pN != nullptr) && !KeyFuncs::Equals(k, pN->m_key))
296+
{
297+
pN = pN->m_next;
298+
}
299+
if (pN == nullptr)
300+
{
301+
pN = new (m_alloc) Node(m_table[index], k, jitstd::forward<Args>(args)...);
302+
m_table[index] = pN;
303+
m_tableCount++;
304+
}
305+
return &pN->m_val;
306+
}
307+
274308
//------------------------------------------------------------------------
275309
// Remove: Remove the specified key and its associated value.
276310
//
@@ -592,7 +626,7 @@ class JitHashTable
592626
// Assumptions:
593627
// This must not be the "end" iterator.
594628
//
595-
const Value& GetValue() const
629+
Value& GetValue() const
596630
{
597631
assert(m_node != nullptr);
598632

@@ -721,7 +755,8 @@ class JitHashTable
721755
Key m_key;
722756
Value m_val;
723757

724-
Node(Key k, Value v, Node* next) : m_next(next), m_key(k), m_val(v)
758+
template <class... Args>
759+
Node(Node* next, Key k, Args&&... args) : m_next(next), m_key(k), m_val(jitstd::forward<Args>(args)...)
725760
{
726761
}
727762

src/jit/ssabuilder.cpp

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -359,22 +359,22 @@ void SsaBuilder::ComputeImmediateDom(BasicBlock** postOrder, int count)
359359
* @remarks This would help us answer queries such as "a dom b?" in constant time.
360360
* For example, if a dominated b, then Pre[a] < Pre[b] but Post[a] > Post[b]
361361
*/
362-
void SsaBuilder::DomTreeWalk(BasicBlock* curBlock, BlkToBlkSetMap* domTree, int* preIndex, int* postIndex)
362+
void SsaBuilder::DomTreeWalk(BasicBlock* curBlock, BlkToBlkVectorMap* domTree, int* preIndex, int* postIndex)
363363
{
364364
JITDUMP("[SsaBuilder::DomTreeWalk] block %s:\n", curBlock->dspToString());
365365

366366
// Store the order number at the block number in the pre order list.
367367
m_pDomPreOrder[curBlock->bbNum] = *preIndex;
368368
++(*preIndex);
369369

370-
BlkSet* pBlkSet;
371-
if (domTree->Lookup(curBlock, &pBlkSet))
370+
BlkVector* domChildren = domTree->LookupPointer(curBlock);
371+
if (domChildren != nullptr)
372372
{
373-
for (BlkSet::KeyIterator ki = pBlkSet->Begin(); !ki.Equal(pBlkSet->End()); ++ki)
373+
for (BasicBlock* child : *domChildren)
374374
{
375-
if (curBlock != ki.Get())
375+
if (curBlock != child)
376376
{
377-
DomTreeWalk(ki.Get(), domTree, preIndex, postIndex);
377+
DomTreeWalk(child, domTree, preIndex, postIndex);
378378
}
379379
}
380380
}
@@ -393,7 +393,7 @@ void SsaBuilder::DomTreeWalk(BasicBlock* curBlock, BlkToBlkSetMap* domTree, int*
393393
*
394394
*/
395395
/* static */
396-
void SsaBuilder::ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block, BlkToBlkSetMap* domTree)
396+
void SsaBuilder::ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block, BlkToBlkVectorMap* domTree)
397397
{
398398
BasicBlock* bbIDom = block->bbIDom;
399399

@@ -404,16 +404,11 @@ void SsaBuilder::ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block
404404
}
405405

406406
// If the bbIDom map key doesn't exist, create one.
407-
BlkSet* pBlkSet;
408-
if (!domTree->Lookup(bbIDom, &pBlkSet))
409-
{
410-
pBlkSet = new (domTree->GetAllocator()) BlkSet(domTree->GetAllocator());
411-
domTree->Set(bbIDom, pBlkSet);
412-
}
407+
BlkVector* domChildren = domTree->Emplace(bbIDom, domTree->GetAllocator());
413408

414409
DBG_SSA_JITDUMP("Inserting BB%02u as dom child of BB%02u.\n", block->bbNum, bbIDom->bbNum);
415410
// Insert the block into the block's set.
416-
pBlkSet->Set(block, true);
411+
domChildren->push_back(block);
417412
}
418413

419414
/**
@@ -426,7 +421,7 @@ void SsaBuilder::ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block
426421
*
427422
*/
428423
/* static */
429-
void SsaBuilder::ComputeDominators(Compiler* pCompiler, BlkToBlkSetMap* domTree)
424+
void SsaBuilder::ComputeDominators(Compiler* pCompiler, BlkToBlkVectorMap* domTree)
430425
{
431426
JITDUMP("*************** In SsaBuilder::ComputeDominators(Compiler*, ...)\n");
432427

@@ -450,7 +445,7 @@ void SsaBuilder::ComputeDominators(Compiler* pCompiler, BlkToBlkSetMap* domTree)
450445
* @param domTree A map of (block -> set of blocks) tree representation that is empty.
451446
*
452447
*/
453-
void SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, BlkToBlkSetMap* domTree)
448+
void SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, BlkToBlkVectorMap* domTree)
454449
{
455450
JITDUMP("*************** In SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, ...)\n");
456451

@@ -486,21 +481,22 @@ void SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, BlkToBlkSe
486481
* @param domTree A map of (block -> set of blocks) tree representation.
487482
*/
488483
/* static */
489-
void SsaBuilder::DisplayDominators(BlkToBlkSetMap* domTree)
484+
void SsaBuilder::DisplayDominators(BlkToBlkVectorMap* domTree)
490485
{
491486
printf("After computing dominator tree: \n");
492-
for (BlkToBlkSetMap::KeyIterator nodes = domTree->Begin(); !nodes.Equal(domTree->End()); ++nodes)
487+
for (BlkToBlkVectorMap::KeyIterator nodes = domTree->Begin(); !nodes.Equal(domTree->End()); ++nodes)
493488
{
494489
printf("BB%02u := {", nodes.Get()->bbNum);
490+
bool first = true;
495491

496-
BlkSet* pBlkSet = nodes.GetValue();
497-
for (BlkSet::KeyIterator ki = pBlkSet->Begin(); !ki.Equal(pBlkSet->End()); ++ki)
492+
for (BasicBlock* child : nodes.GetValue())
498493
{
499-
if (!ki.Equal(pBlkSet->Begin()))
494+
if (!first)
500495
{
501496
printf(",");
502497
}
503-
printf("BB%02u", ki.Get()->bbNum);
498+
first = false;
499+
printf("BB%02u", child->bbNum);
504500
}
505501
printf("}\n");
506502
}
@@ -1657,7 +1653,7 @@ void SsaBuilder::BlockPopStacks(BasicBlock* block, SsaRenameState* pRenameState)
16571653
* and Destruction of Static Single Assignment Form."
16581654
*/
16591655

1660-
void SsaBuilder::RenameVariables(BlkToBlkSetMap* domTree, SsaRenameState* pRenameState)
1656+
void SsaBuilder::RenameVariables(BlkToBlkVectorMap* domTree, SsaRenameState* pRenameState)
16611657
{
16621658
JITDUMP("*************** In SsaBuilder::RenameVariables()\n");
16631659

@@ -1750,13 +1746,13 @@ void SsaBuilder::RenameVariables(BlkToBlkSetMap* domTree, SsaRenameState* pRenam
17501746
AssignPhiNodeRhsVariables(block, pRenameState);
17511747

17521748
// Recurse with the block's DOM children.
1753-
BlkSet* pBlkSet;
1754-
if (domTree->Lookup(block, &pBlkSet))
1749+
BlkVector* domChildren = domTree->LookupPointer(block);
1750+
if (domChildren != nullptr)
17551751
{
1756-
for (BlkSet::KeyIterator child = pBlkSet->Begin(); !child.Equal(pBlkSet->End()); ++child)
1752+
for (BasicBlock* child : *domChildren)
17571753
{
1758-
DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables](pushing dom child BB%02u)\n", child.Get()->bbNum);
1759-
blocksToDo->push_back(BlockWork(child.Get()));
1754+
DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables](pushing dom child BB%02u)\n", child->bbNum);
1755+
blocksToDo->push_back(BlockWork(child));
17601756
}
17611757
}
17621758
}
@@ -1867,7 +1863,7 @@ void SsaBuilder::Build()
18671863
ComputeImmediateDom(postOrder, count);
18681864

18691865
// Compute the dominator tree.
1870-
BlkToBlkSetMap* domTree = new (&m_allocator) BlkToBlkSetMap(&m_allocator);
1866+
BlkToBlkVectorMap* domTree = new (&m_allocator) BlkToBlkVectorMap(&m_allocator);
18711867
ComputeDominators(postOrder, count, domTree);
18721868
EndPhase(PHASE_BUILD_SSA_DOMS);
18731869

src/jit/ssabuilder.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class SsaBuilder
6262
// Using IDom of each basic block, compute the whole domTree. If a block "b" has IDom "i",
6363
// then, block "b" is dominated by "i". The mapping then is i -> { ..., b, ... }, in
6464
// other words, "domTree" is a tree represented by nodes mapped to their children.
65-
static void ComputeDominators(Compiler* pCompiler, BlkToBlkSetMap* domTree);
65+
static void ComputeDominators(Compiler* pCompiler, BlkToBlkVectorMap* domTree);
6666

6767
private:
6868
// Ensures that the basic block graph has a root for the dominator graph, by ensuring
@@ -88,21 +88,21 @@ class SsaBuilder
8888
// as children.) Requires "preIndex" and "postIndex" to be initialized to 0 at entry into recursion.
8989
// Computes arrays "m_pDomPreOrder" and "m_pDomPostOrder" of block indices such that the blocks of a
9090
// "domTree" are in pre and postorder respectively.
91-
void DomTreeWalk(BasicBlock* curBlock, BlkToBlkSetMap* domTree, int* preIndex, int* postIndex);
91+
void DomTreeWalk(BasicBlock* curBlock, BlkToBlkVectorMap* domTree, int* preIndex, int* postIndex);
9292
#endif
9393

94-
// Requires all blocks to have computed "bbIDom." Requires "domTree" to be a preallocated BlkToBlkSetMap.
94+
// Requires all blocks to have computed "bbIDom." Requires "domTree" to be a preallocated BlkToBlkVectorMap.
9595
// Helper to compute "domTree" from the pre-computed bbIDom of the basic blocks.
96-
static void ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block, BlkToBlkSetMap* domTree);
96+
static void ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block, BlkToBlkVectorMap* domTree);
9797

9898
// Requires "postOrder" to hold the blocks of the flowgraph in topologically sorted order. Requires
9999
// count to be the valid entries in the "postOrder" array. Computes "domTree" as a adjacency list
100100
// like object, i.e., a set of blocks with a set of blocks as children defining the DOM relation.
101-
void ComputeDominators(BasicBlock** postOrder, int count, BlkToBlkSetMap* domTree);
101+
void ComputeDominators(BasicBlock** postOrder, int count, BlkToBlkVectorMap* domTree);
102102

103103
#ifdef DEBUG
104104
// Display the dominator tree.
105-
static void DisplayDominators(BlkToBlkSetMap* domTree);
105+
static void DisplayDominators(BlkToBlkVectorMap* domTree);
106106
#endif // DEBUG
107107

108108
// Requires "postOrder" to hold the blocks of the flowgraph in topologically sorted order. Requires
@@ -123,7 +123,7 @@ class SsaBuilder
123123
// Requires "domTree" to be the dominator tree relation defined by a DOM b.
124124
// Requires "pRenameState" to have counts and stacks at their initial state.
125125
// Assigns gtSsaNames to all variables.
126-
void RenameVariables(BlkToBlkSetMap* domTree, SsaRenameState* pRenameState);
126+
void RenameVariables(BlkToBlkVectorMap* domTree, SsaRenameState* pRenameState);
127127

128128
// Requires "block" to be any basic block participating in variable renaming, and has at least a
129129
// definition that pushed a ssa number into the rename stack for a variable. Requires "pRenameState"

0 commit comments

Comments
 (0)