Skip to content

Commit

Permalink
JIT: Use any reaching def for unreachable uses in incremental SSA bui…
Browse files Browse the repository at this point in the history
…lder (dotnet#110077)

There really is no correct reaching definition in this case, so any reaching
definition will do here. This matches what happens normally in the JIT when
various phases optimize control flow after SSA has been built without removing
the now-unreachable blocks.

Also give unreachable stores an SSA number.

Fix dotnet#109971
  • Loading branch information
jakobbotsch authored Nov 26, 2024
1 parent d86f770 commit 0170d78
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 19 deletions.
5 changes: 1 addition & 4 deletions src/coreclr/jit/optcse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5114,10 +5114,7 @@ void CSE_HeuristicCommon::ReplaceCSENode(Statement* stmt, GenTree* exp, GenTree*
//
void CSE_HeuristicCommon::InsertUseIntoSsa(IncrementalSsaBuilder& ssaBuilder, const UseDefLocation& useDefLoc)
{
if (!ssaBuilder.InsertUse(useDefLoc))
{
return;
}
ssaBuilder.InsertUse(useDefLoc);

GenTreeLclVar* lcl = useDefLoc.Tree;
assert(lcl->HasSsaName());
Expand Down
24 changes: 10 additions & 14 deletions src/coreclr/jit/ssabuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1737,13 +1737,11 @@ bool IncrementalSsaBuilder::FinalizeDefs()
for (int i = 0; i < m_defs.Height(); i++)
{
UseDefLocation& def = m_defs.BottomRef(i);
if (!m_comp->m_dfsTree->Contains(def.Block))
if (m_comp->m_dfsTree->Contains(def.Block))
{
continue;
BitVecOps::AddElemD(&m_poTraits, m_defBlocks, def.Block->bbPostorderNum);
}

BitVecOps::AddElemD(&m_poTraits, m_defBlocks, def.Block->bbPostorderNum);

unsigned ssaNum = dsc->lvPerSsaData.AllocSsaNum(m_comp->getAllocator(CMK_SSA), def.Block, def.Tree);
def.Tree->SetSsaNum(ssaNum);
LclSsaVarDsc* ssaDsc = dsc->GetPerSsaData(ssaNum);
Expand All @@ -1763,17 +1761,13 @@ bool IncrementalSsaBuilder::FinalizeDefs()
// Parameters:
// use - Location of the use
//
// Returns:
// True if the use was in a reachable block and thus has a reaching def;
// otherwise false.
//
// Remarks:
// All uses are required to never read an uninitialized value of the local.
// That is, this function requires that all paths through the function go
// through one of the defs in "defs" before any use in "uses" for uses that
// are statically reachable.
//
bool IncrementalSsaBuilder::InsertUse(const UseDefLocation& use)
void IncrementalSsaBuilder::InsertUse(const UseDefLocation& use)
{
assert(m_finalizedDefs);

Expand All @@ -1788,11 +1782,14 @@ bool IncrementalSsaBuilder::InsertUse(const UseDefLocation& use)
{
if (!m_comp->m_dfsTree->Contains(use.Block))
{
JITDUMP(" Use is in unreachable block " FMT_BB "\n", use.Block->bbNum);
return false;
reachingDef = m_defs.Bottom(0);
JITDUMP(" Use is in unreachable block " FMT_BB ", using first def [%06u] in " FMT_BB "\n",
use.Block->bbNum, Compiler::dspTreeID(reachingDef.Tree), reachingDef.Block->bbNum);
}
else
{
reachingDef = FindOrCreateReachingDef(use);
}

reachingDef = FindOrCreateReachingDef(use);
}

JITDUMP(" Reaching def is [%06u] d:%d\n", Compiler::dspTreeID(reachingDef.Tree), reachingDef.Tree->GetSsaNum());
Expand All @@ -1802,5 +1799,4 @@ bool IncrementalSsaBuilder::InsertUse(const UseDefLocation& use)

LclVarDsc* dsc = m_comp->lvaGetDesc(m_lclNum);
dsc->GetPerSsaData(reachingDef.Tree->GetSsaNum())->AddUse(use.Block);
return true;
}
2 changes: 1 addition & 1 deletion src/coreclr/jit/ssabuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,5 @@ class IncrementalSsaBuilder

void InsertDef(const UseDefLocation& def);
bool FinalizeDefs();
bool InsertUse(const UseDefLocation& use);
void InsertUse(const UseDefLocation& use);
};

0 comments on commit 0170d78

Please sign in to comment.