From 2e940855ba936a78b6a29ce3d5e57021a90b734d Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Tue, 26 Nov 2024 10:39:20 +0100 Subject: [PATCH] JIT: Use any reaching def for unreachable uses in incremental SSA builder (#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 #109971 --- src/coreclr/jit/optcse.cpp | 5 +---- src/coreclr/jit/ssabuilder.cpp | 24 ++++++++++-------------- src/coreclr/jit/ssabuilder.h | 2 +- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index 8d91f03801e0a..c2906e43eb16e 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -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()); diff --git a/src/coreclr/jit/ssabuilder.cpp b/src/coreclr/jit/ssabuilder.cpp index 8f4561ecfc866..b36529cc1a686 100644 --- a/src/coreclr/jit/ssabuilder.cpp +++ b/src/coreclr/jit/ssabuilder.cpp @@ -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); @@ -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); @@ -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()); @@ -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; } diff --git a/src/coreclr/jit/ssabuilder.h b/src/coreclr/jit/ssabuilder.h index 8d738ed790553..73157291a46e7 100644 --- a/src/coreclr/jit/ssabuilder.h +++ b/src/coreclr/jit/ssabuilder.h @@ -151,5 +151,5 @@ class IncrementalSsaBuilder void InsertDef(const UseDefLocation& def); bool FinalizeDefs(); - bool InsertUse(const UseDefLocation& use); + void InsertUse(const UseDefLocation& use); };