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

Commit e25cb34

Browse files
committed
Improve SSA IDF computation memory usage
Like DF(b), IDF(b) can be stored in a vector if duplicates are avoided. This can be done by using a BitVector like TopologicalSort and ComputeImmediateDom already do. It's cheaper than using a hashtable (even though it requires a "clear" for every block that has a frontier). Also, storing IDF(b) into a vector makes it easier to track newly added blocks - they're at the end of the vector. Using a separate "delta" set is no longer needed.
1 parent 86eb9c9 commit e25cb34

File tree

2 files changed

+44
-43
lines changed

2 files changed

+44
-43
lines changed

src/jit/ssabuilder.cpp

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ void SsaBuilder::DisplayDominators(BlkToBlkSetMap* domTree)
511511
// See "A simple, fast dominance algorithm", by Cooper, Harvey, and Kennedy.
512512
// First we compute the dominance frontier for each block, then we convert these to iterated
513513
// dominance frontiers by a closure operation.
514-
BlkToBlkSetMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** postOrder, int count)
514+
BlkToBlkVectorMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** postOrder, int count)
515515
{
516516
BlkToBlkVectorMap mapDF(&m_allocator);
517517

@@ -600,38 +600,41 @@ BlkToBlkSetMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** postOr
600600
#endif
601601

602602
// Now do the closure operation to make the dominance frontier into an IDF.
603-
// There's probably a better way to do this...
604-
BlkToBlkSetMap* idf = new (&m_allocator) BlkToBlkSetMap(&m_allocator);
605-
for (BlkToBlkVectorMap::KeyIterator kiFrontBlks = mapDF.Begin(); !kiFrontBlks.Equal(mapDF.End()); kiFrontBlks++)
606-
{
607-
// Create IDF(b)
608-
BlkSet* blkIdf = new (&m_allocator) BlkSet(&m_allocator);
609-
idf->Set(kiFrontBlks.Get(), blkIdf);
603+
BlkToBlkVectorMap* mapIDF = new (&m_allocator) BlkToBlkVectorMap(&m_allocator);
604+
mapIDF->Reallocate(mapDF.GetCount());
610605

611-
// Keep track of what got newly added to the IDF, so we can go after their DFs.
612-
BlkSet* delta = new (&m_allocator) BlkSet(&m_allocator);
613-
delta->Set(kiFrontBlks.Get(), true);
606+
for (BlkToBlkVectorMap::KeyIterator ki = mapDF.Begin(); !ki.Equal(mapDF.End()); ki++)
607+
{
608+
// Compute IDF(b) - start by adding DF(b) to IDF(b).
609+
BasicBlock* b = ki.Get();
610+
BlkVector& bDF = ki.GetValue();
611+
BlkVector& bIDF = *mapIDF->Emplace(b, &m_allocator);
612+
bIDF.reserve(bDF.size());
613+
BitVecOps::ClearD(&m_visitedTraits, m_visited);
614+
615+
for (BasicBlock* f : bDF)
616+
{
617+
BitVecOps::AddElemD(&m_visitedTraits, m_visited, f->bbNum);
618+
bIDF.push_back(f);
619+
}
614620

615-
// Now transitively add DF+(delta) to IDF(b), each step gathering new "delta."
616-
while (delta->GetCount() > 0)
621+
// Now for each block f from IDF(b) add DF(f) to IDF(b). This may result in new
622+
// blocks being added to IDF(b) and the process repeats until no more new blocks
623+
// are added. Note that since we keep adding to bIDF we can't use iterators as
624+
// they may get invalidated. This happens to be a convenient way to avoid having
625+
// to track newly added blocks in a separate set.
626+
for (size_t newIndex = 0; newIndex < bIDF.size(); newIndex++)
617627
{
618-
// Extract a block x to be worked on.
619-
BlkSet::KeyIterator ki = delta->Begin();
620-
BasicBlock* curBlk = ki.Get();
621-
// TODO-Cleanup: Remove(ki) doesn't work correctly in SimplerHash.
622-
delta->Remove(curBlk);
623-
624-
// Get DF(x).
625-
BlkVector* blkDf = mapDF.LookupPointer(curBlk);
626-
if (blkDf != nullptr)
628+
BasicBlock* f = bIDF[newIndex];
629+
BlkVector* fDF = mapDF.LookupPointer(f);
630+
631+
if (fDF != nullptr)
627632
{
628-
// Add DF(x) to IDF(b) and update "delta" i.e., new additions to IDF(b).
629-
for (BasicBlock* f : *blkDf)
633+
for (BasicBlock* ff : *fDF)
630634
{
631-
if (!blkIdf->Lookup(f))
635+
if (BitVecOps::TryAddElemD(&m_visitedTraits, m_visited, ff->bbNum))
632636
{
633-
delta->Set(f, true);
634-
blkIdf->Set(f, true);
637+
bIDF.push_back(ff);
635638
}
636639
}
637640
}
@@ -644,20 +647,20 @@ BlkToBlkSetMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** postOr
644647
printf("\nComputed IDF:\n");
645648
for (int i = 0; i < count; ++i)
646649
{
647-
BasicBlock* block = postOrder[i];
648-
printf("Block BB%02u := {", block->bbNum);
650+
BasicBlock* b = postOrder[i];
651+
printf("Block BB%02u := {", b->bbNum);
649652

650-
bool first = true;
651-
BlkSet* blkIdf;
652-
if (idf->Lookup(block, &blkIdf))
653+
bool first = true;
654+
BlkVector* bIDF = mapIDF->LookupPointer(b);
655+
if (bIDF != nullptr)
653656
{
654-
for (BlkSet::KeyIterator ki = blkIdf->Begin(); !ki.Equal(blkIdf->End()); ki++)
657+
for (BasicBlock* f : *bIDF)
655658
{
656659
if (!first)
657660
{
658661
printf(",");
659662
}
660-
printf("BB%02u", ki.Get()->bbNum);
663+
printf("BB%02u", f->bbNum);
661664
first = false;
662665
}
663666
}
@@ -666,7 +669,7 @@ BlkToBlkSetMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** postOr
666669
}
667670
#endif
668671

669-
return idf;
672+
return mapIDF;
670673
}
671674

672675
/**
@@ -720,7 +723,7 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
720723
EndPhase(PHASE_BUILD_SSA_LIVENESS);
721724

722725
// Compute dominance frontier.
723-
BlkToBlkSetMap* frontier = ComputeIteratedDominanceFrontier(postOrder, count);
726+
BlkToBlkVectorMap* mapIDF = ComputeIteratedDominanceFrontier(postOrder, count);
724727
EndPhase(PHASE_BUILD_SSA_IDF);
725728

726729
JITDUMP("Inserting phi functions:\n");
@@ -731,8 +734,8 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
731734
DBG_SSA_JITDUMP("Considering dominance frontier of block BB%02u:\n", block->bbNum);
732735

733736
// If the block's dominance frontier is empty, go on to the next block.
734-
BlkSet* blkIdf;
735-
if (!frontier->Lookup(block, &blkIdf))
737+
BlkVector* blkIdf = mapIDF->LookupPointer(block);
738+
if (blkIdf == nullptr)
736739
{
737740
continue;
738741
}
@@ -752,9 +755,8 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
752755
}
753756

754757
// For each block "bbInDomFront" that is in the dominance frontier of "block"...
755-
for (BlkSet::KeyIterator iterBlk = blkIdf->Begin(); !iterBlk.Equal(blkIdf->End()); ++iterBlk)
758+
for (BasicBlock* bbInDomFront : *blkIdf)
756759
{
757-
BasicBlock* bbInDomFront = iterBlk.Get();
758760
DBG_SSA_JITDUMP(" Considering BB%02u in dom frontier of BB%02u:\n", bbInDomFront->bbNum,
759761
block->bbNum);
760762

@@ -794,9 +796,8 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
794796
if (block->bbMemoryDef != 0)
795797
{
796798
// For each block "bbInDomFront" that is in the dominance frontier of "block".
797-
for (BlkSet::KeyIterator iterBlk = blkIdf->Begin(); !iterBlk.Equal(blkIdf->End()); ++iterBlk)
799+
for (BasicBlock* bbInDomFront : *blkIdf)
798800
{
799-
BasicBlock* bbInDomFront = iterBlk.Get();
800801
DBG_SSA_JITDUMP(" Considering BB%02u in dom frontier of BB%02u for Memory phis:\n",
801802
bbInDomFront->bbNum, block->bbNum);
802803

src/jit/ssabuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class SsaBuilder
112112
// need not be strict -- B2 and B may be the same node. The iterated dominance frontier is formed by a closure
113113
// operation: the IDF of B is the smallest set that includes B's dominance frontier, and also includes the dominance
114114
// frontier of all elements of the set.)
115-
BlkToBlkSetMap* ComputeIteratedDominanceFrontier(BasicBlock** postOrder, int count);
115+
BlkToBlkVectorMap* ComputeIteratedDominanceFrontier(BasicBlock** postOrder, int count);
116116

117117
// Requires "postOrder" to hold the blocks of the flowgraph in topologically sorted order. Requires
118118
// count to be the valid entries in the "postOrder" array. Inserts GT_PHI nodes at the beginning

0 commit comments

Comments
 (0)