From d9f6b98de38081b71fa9b5a463f302288546435d Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 13 Jul 2023 05:06:28 +0200 Subject: [PATCH] JIT: Always consider empty remainders to be dying in physical promotion (#88665) Liveness takes a few shortcuts that means it doesn't always handle the case where there is no remainder as the remainder dying, so add a special case in StructDeaths::IsRemainderDying to take care of this case. Some minor improvements from more last-use copy omission are expected. --- src/coreclr/jit/promotion.h | 6 +++--- src/coreclr/jit/promotionliveness.cpp | 14 +++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/promotion.h b/src/coreclr/jit/promotion.h index e24a606..0efde03 100644 --- a/src/coreclr/jit/promotion.h +++ b/src/coreclr/jit/promotion.h @@ -208,13 +208,13 @@ public: // Class to represent liveness information for a struct local's fields and remainder. class StructDeaths { - BitVec m_deaths; - unsigned m_numFields = 0; + BitVec m_deaths; + AggregateInfo* m_aggregate = nullptr; friend class PromotionLiveness; private: - StructDeaths(BitVec deaths, unsigned numFields) : m_deaths(deaths), m_numFields(numFields) + StructDeaths(BitVec deaths, AggregateInfo* agg) : m_deaths(deaths), m_aggregate(agg) { } diff --git a/src/coreclr/jit/promotionliveness.cpp b/src/coreclr/jit/promotionliveness.cpp index daddd1d..9791bd0 100644 --- a/src/coreclr/jit/promotionliveness.cpp +++ b/src/coreclr/jit/promotionliveness.cpp @@ -808,7 +808,7 @@ StructDeaths PromotionLiveness::GetDeathsForStructLocal(GenTreeLclVarCommon* lcl unsigned lclNum = lcl->GetLclNum(); AggregateInfo* aggInfo = m_aggregates.Lookup(lclNum); - return StructDeaths(aggDeaths, (unsigned)aggInfo->Replacements.size()); + return StructDeaths(aggDeaths, aggInfo); } //------------------------------------------------------------------------ @@ -820,7 +820,13 @@ StructDeaths PromotionLiveness::GetDeathsForStructLocal(GenTreeLclVarCommon* lcl // bool StructDeaths::IsRemainderDying() const { - BitVecTraits traits(1 + m_numFields, nullptr); + if (m_aggregate->UnpromotedMax <= m_aggregate->UnpromotedMin) + { + // No remainder. + return true; + } + + BitVecTraits traits(1 + (unsigned)m_aggregate->Replacements.size(), nullptr); return BitVecOps::IsMember(&traits, m_deaths, 0); } @@ -833,7 +839,9 @@ bool StructDeaths::IsRemainderDying() const // bool StructDeaths::IsReplacementDying(unsigned index) const { - BitVecTraits traits(1 + m_numFields, nullptr); + assert(index < m_aggregate->Replacements.size()); + + BitVecTraits traits(1 + (unsigned)m_aggregate->Replacements.size(), nullptr); return BitVecOps::IsMember(&traits, m_deaths, 1 + index); } -- 2.7.4