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

Do not compute the IDF for all blocks in advance #15146

Merged
merged 1 commit into from
Mar 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/jit/compphases.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ CompPhaseNameMacro(PHASE_BUILD_SSA, "Build SSA representation",
CompPhaseNameMacro(PHASE_BUILD_SSA_TOPOSORT, "SSA: topological sort", "SSA-SORT", false, PHASE_BUILD_SSA, false)
CompPhaseNameMacro(PHASE_BUILD_SSA_DOMS, "SSA: Doms1", "SSA-DOMS", false, PHASE_BUILD_SSA, false)
CompPhaseNameMacro(PHASE_BUILD_SSA_LIVENESS, "SSA: liveness", "SSA-LIVE", false, PHASE_BUILD_SSA, false)
CompPhaseNameMacro(PHASE_BUILD_SSA_IDF, "SSA: IDF", "SSA-IDF", false, PHASE_BUILD_SSA, false)
CompPhaseNameMacro(PHASE_BUILD_SSA_DF, "SSA: DF", "SSA-DF", false, PHASE_BUILD_SSA, false)
CompPhaseNameMacro(PHASE_BUILD_SSA_INSERT_PHIS, "SSA: insert phis", "SSA-PHI", false, PHASE_BUILD_SSA, false)
CompPhaseNameMacro(PHASE_BUILD_SSA_RENAME, "SSA: rename", "SSA-REN", false, PHASE_BUILD_SSA, false)

Expand Down
3 changes: 0 additions & 3 deletions src/jit/jitstd/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,7 @@ void vector<T, Allocator>::clear()
{
m_pArray[i].~T();
}
m_allocator.deallocate(m_pArray, m_nCapacity);
m_pArray = NULL;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vector::clear() is not required to release the memory. Doing this prevents memory reuse.

m_nSize = 0;
m_nCapacity = 0;
}

template <typename T, typename Allocator>
Expand Down
128 changes: 68 additions & 60 deletions src/jit/ssabuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,15 +507,26 @@ void SsaBuilder::DisplayDominators(BlkToBlkSetMap* domTree)

#endif // DEBUG

// (Spec comment at declaration.)
// See "A simple, fast dominance algorithm", by Cooper, Harvey, and Kennedy.
// First we compute the dominance frontier for each block, then we convert these to iterated
// dominance frontiers by a closure operation.
BlkToBlkVectorMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** postOrder, int count)
//------------------------------------------------------------------------
// ComputeDominanceFrontiers: Compute flow graph dominance frontiers
//
// Arguments:
// postOrder - an array containing all flow graph blocks
// count - the number of blocks in the postOrder array
// mapDF - a caller provided hashtable that will be populated
// with blocks and their dominance frontiers (only those
// blocks that have non-empty frontiers will be included)
//
// Notes:
// Recall that the dominance frontier of a block B is the set of blocks
// B3 such that there exists some B2 s.t. B3 is a successor of B2, and
// B dominates B2. Note that this dominance need not be strict -- B2
// and B may be the same node.
// See "A simple, fast dominance algorithm", by Cooper, Harvey, and Kennedy.
//
void SsaBuilder::ComputeDominanceFrontiers(BasicBlock** postOrder, int count, BlkToBlkVectorMap* mapDF)
{
BlkToBlkVectorMap mapDF(&m_allocator);

DBG_SSA_JITDUMP("Computing IDF: First computing DF.\n");
DBG_SSA_JITDUMP("Computing DF:\n");

for (int i = 0; i < count; ++i)
{
Expand Down Expand Up @@ -561,7 +572,7 @@ BlkToBlkVectorMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** pos
{
DBG_SSA_JITDUMP(" Adding BB%02u to dom frontier of pred dom BB%02u.\n", block->bbNum, b1->bbNum);

BlkVector& b1DF = *mapDF.Emplace(b1, &m_allocator);
BlkVector& b1DF = *mapDF->Emplace(b1, &m_allocator);
// It's possible to encounter the same DF multiple times, ensure that we don't add duplicates.
if (b1DF.empty() || (b1DF.back() != block))
{
Expand All @@ -580,61 +591,70 @@ BlkToBlkVectorMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** pos
BasicBlock* b = postOrder[i];
printf("Block BB%02u := {", b->bbNum);

bool first = true;
BlkVector* bDF = mapDF.LookupPointer(b);
BlkVector* bDF = mapDF->LookupPointer(b);
if (bDF != nullptr)
{
int index = 0;
for (BasicBlock* f : *bDF)
{
if (!first)
{
printf(",");
}
printf("BB%02u", f->bbNum);
first = false;
printf("%sBB%02u", (index++ == 0) ? "" : ",", f->bbNum);
}
}
printf("}\n");
}
}
#endif
}

//------------------------------------------------------------------------
// ComputeIteratedDominanceFrontier: Compute the iterated dominance frontier
// for the specified block.
//
// Arguments:
// b - the block to computed the frontier for
// mapDF - a map containing the dominance frontiers of all blocks
// bIDF - a caller provided vector where the IDF is to be stored
//
// Notes:
// The iterated dominance frontier is formed by a closure operation:
// the IDF of B is the smallest set that includes B's dominance frontier,
// and also includes the dominance frontier of all elements of the set.
//
void SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock* b, const BlkToBlkVectorMap* mapDF, BlkVector* bIDF)
{
assert(bIDF->empty());

// Now do the closure operation to make the dominance frontier into an IDF.
BlkToBlkVectorMap* mapIDF = new (&m_allocator) BlkToBlkVectorMap(&m_allocator);
mapIDF->Reallocate(mapDF.GetCount());
BlkVector* bDF = mapDF->LookupPointer(b);

for (BlkToBlkVectorMap::KeyIterator ki = mapDF.Begin(); !ki.Equal(mapDF.End()); ki++)
if (bDF != nullptr)
{
// Compute IDF(b) - start by adding DF(b) to IDF(b).
BasicBlock* b = ki.Get();
BlkVector& bDF = ki.GetValue();
BlkVector& bIDF = *mapIDF->Emplace(b, &m_allocator);
bIDF.reserve(bDF.size());
bIDF->reserve(bDF->size());
BitVecOps::ClearD(&m_visitedTraits, m_visited);

for (BasicBlock* f : bDF)
for (BasicBlock* f : *bDF)
{
BitVecOps::AddElemD(&m_visitedTraits, m_visited, f->bbNum);
bIDF.push_back(f);
bIDF->push_back(f);
}

// Now for each block f from IDF(b) add DF(f) to IDF(b). This may result in new
// blocks being added to IDF(b) and the process repeats until no more new blocks
// are added. Note that since we keep adding to bIDF we can't use iterators as
// they may get invalidated. This happens to be a convenient way to avoid having
// to track newly added blocks in a separate set.
for (size_t newIndex = 0; newIndex < bIDF.size(); newIndex++)
for (size_t newIndex = 0; newIndex < bIDF->size(); newIndex++)
{
BasicBlock* f = bIDF[newIndex];
BlkVector* fDF = mapDF.LookupPointer(f);
BasicBlock* f = (*bIDF)[newIndex];
BlkVector* fDF = mapDF->LookupPointer(f);

if (fDF != nullptr)
{
for (BasicBlock* ff : *fDF)
{
if (BitVecOps::TryAddElemD(&m_visitedTraits, m_visited, ff->bbNum))
{
bIDF.push_back(ff);
bIDF->push_back(ff);
}
}
}
Expand All @@ -644,32 +664,15 @@ BlkToBlkVectorMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** pos
#ifdef DEBUG
if (m_pCompiler->verboseSsa)
{
printf("\nComputed IDF:\n");
for (int i = 0; i < count; ++i)
printf("IDF(BB%02u) := {", b->bbNum);
int index = 0;
for (BasicBlock* f : *bIDF)
{
BasicBlock* b = postOrder[i];
printf("Block BB%02u := {", b->bbNum);

bool first = true;
BlkVector* bIDF = mapIDF->LookupPointer(b);
if (bIDF != nullptr)
{
for (BasicBlock* f : *bIDF)
{
if (!first)
{
printf(",");
}
printf("BB%02u", f->bbNum);
first = false;
}
}
printf("}\n");
printf("%sBB%02u", (index++ == 0) ? "" : ",", f->bbNum);
}
printf("}\n");
}
#endif

return mapIDF;
}

/**
Expand Down Expand Up @@ -723,8 +726,12 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
EndPhase(PHASE_BUILD_SSA_LIVENESS);

// Compute dominance frontier.
BlkToBlkVectorMap* mapIDF = ComputeIteratedDominanceFrontier(postOrder, count);
EndPhase(PHASE_BUILD_SSA_IDF);
BlkToBlkVectorMap mapDF(&m_allocator);
ComputeDominanceFrontiers(postOrder, count, &mapDF);
EndPhase(PHASE_BUILD_SSA_DF);

// Use the same IDF vector for all blocks to avoid unnecessary memory allocations
BlkVector blockIDF(&m_allocator);

JITDUMP("Inserting phi functions:\n");

Expand All @@ -733,9 +740,10 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
BasicBlock* block = postOrder[i];
DBG_SSA_JITDUMP("Considering dominance frontier of block BB%02u:\n", block->bbNum);

// If the block's dominance frontier is empty, go on to the next block.
BlkVector* blkIdf = mapIDF->LookupPointer(block);
if (blkIdf == nullptr)
blockIDF.clear();
ComputeIteratedDominanceFrontier(block, &mapDF, &blockIDF);

if (blockIDF.empty())
{
continue;
}
Expand All @@ -755,7 +763,7 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
}

// For each block "bbInDomFront" that is in the dominance frontier of "block"...
for (BasicBlock* bbInDomFront : *blkIdf)
for (BasicBlock* bbInDomFront : blockIDF)
{
DBG_SSA_JITDUMP(" Considering BB%02u in dom frontier of BB%02u:\n", bbInDomFront->bbNum,
block->bbNum);
Expand Down Expand Up @@ -796,7 +804,7 @@ void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
if (block->bbMemoryDef != 0)
{
// For each block "bbInDomFront" that is in the dominance frontier of "block".
for (BasicBlock* bbInDomFront : *blkIdf)
for (BasicBlock* bbInDomFront : blockIDF)
{
DBG_SSA_JITDUMP(" Considering BB%02u in dom frontier of BB%02u for Memory phis:\n",
bbInDomFront->bbNum, block->bbNum);
Expand Down
13 changes: 5 additions & 8 deletions src/jit/ssabuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,11 @@ class SsaBuilder
static void DisplayDominators(BlkToBlkSetMap* domTree);
#endif // DEBUG

// Requires "postOrder" to hold the blocks of the flowgraph in topologically sorted order. Requires
// count to be the valid entries in the "postOrder" array. Returns a mapping from blocks to their
// iterated dominance frontiers. (Recall that the dominance frontier of a block B is the set of blocks
// B3 such that there exists some B2 s.t. B3 is a successor of B2, and B dominates B2. Note that this dominance
// need not be strict -- B2 and B may be the same node. The iterated dominance frontier is formed by a closure
// operation: the IDF of B is the smallest set that includes B's dominance frontier, and also includes the dominance
// frontier of all elements of the set.)
BlkToBlkVectorMap* ComputeIteratedDominanceFrontier(BasicBlock** postOrder, int count);
// Compute flow graph dominance frontiers.
void ComputeDominanceFrontiers(BasicBlock** postOrder, int count, BlkToBlkVectorMap* mapDF);

// Compute the iterated dominance frontier for the specified block.
void ComputeIteratedDominanceFrontier(BasicBlock* b, const BlkToBlkVectorMap* mapDF, BlkVector* bIDF);

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