// node, else NULL.
static GenTree* fgIsIndirOfAddrOfLocal(GenTree* tree);
- // This is indexed by GT_OBJ nodes that are address of promoted struct variables, which
+ // This map is indexed by GT_OBJ nodes that are address of promoted struct variables, which
// have been annotated with the GTF_VAR_DEATH flag. If such a node is *not* mapped in this
- // table, one may assume that all the (tracked) field vars die at this point. Otherwise,
+ // table, one may assume that all the (tracked) field vars die at this GT_OBJ. Otherwise,
// the node maps to a pointer to a VARSET_TP, containing set bits for each of the tracked field
// vars of the promoted struct local that go dead at the given node (the set bits are the bits
// for the tracked var indices of the field vars, as in a live var set).
+ //
+ // The map is allocated on demand so all map operations should use one of the following three
+ // wrapper methods.
+
NodeToVarsetPtrMap* m_promotedStructDeathVars;
NodeToVarsetPtrMap* GetPromotedStructDeathVars()
return m_promotedStructDeathVars;
}
+ void ClearPromotedStructDeathVars()
+ {
+ if (m_promotedStructDeathVars != nullptr)
+ {
+ m_promotedStructDeathVars->RemoveAll();
+ }
+ }
+
+ bool LookupPromotedStructDeathVars(GenTree* tree, VARSET_TP** bits)
+ {
+ bits = nullptr;
+ bool result = false;
+
+ if (m_promotedStructDeathVars != nullptr)
+ {
+ result = m_promotedStructDeathVars->Lookup(tree, bits);
+ }
+
+ return result;
+ }
+
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
EndPhase(PHASE_LCLVARLIVENESS_INIT);
// Make sure we haven't noted any partial last uses of promoted structs.
- GetPromotedStructDeathVars()->RemoveAll();
+ ClearPromotedStructDeathVars();
// Initialize the per-block var sets.
fgInitBlockVarSets();
// We maintain the invariant that if the lclVarTree is a promoted struct, but the
// the lookup fails, then all the field vars (i.e., "varBits") are dying.
VARSET_TP* deadVarBits = nullptr;
- if (varTypeIsStruct(lclVarTree) && GetPromotedStructDeathVars()->Lookup(lclVarTree, &deadVarBits))
+ if (varTypeIsStruct(lclVarTree) && LookupPromotedStructDeathVars(lclVarTree, &deadVarBits))
{
VarSetOps::DiffD(this, newLiveSet, *deadVarBits);
}
if (isBorn || isDying)
{
- bool hasDeadTrackedFieldVars = false; // If this is true, then, for a LDOBJ(ADDR(<promoted struct local>)),
- VARSET_TP* deadTrackedFieldVars =
- nullptr; // *deadTrackedFieldVars indicates which tracked field vars are dying.
VarSetOps::ClearD(compiler, varDeltaSet);
if (varDsc->lvTracked)
}
else if (varDsc->lvPromoted)
{
+ // If hasDeadTrackedFieldVars is true, then, for a LDOBJ(ADDR(<promoted struct local>)),
+ // *deadTrackedFieldVars indicates which tracked field vars are dying.
+ bool hasDeadTrackedFieldVars = false;
+
if (indirAddrLocal != nullptr && isDying)
{
assert(!isBorn); // GTF_VAR_DEATH only set for LDOBJ last use.
+ VARSET_TP* deadTrackedFieldVars = nullptr;
hasDeadTrackedFieldVars =
- compiler->GetPromotedStructDeathVars()->Lookup(indirAddrLocal, &deadTrackedFieldVars);
+ compiler->LookupPromotedStructDeathVars(indirAddrLocal, &deadTrackedFieldVars);
if (hasDeadTrackedFieldVars)
{
VarSetOps::Assign(compiler, varDeltaSet, *deadTrackedFieldVars);