* fix a condition.
* Move `PromoteLongVars` to `DecomposeLongs`.
* response review
StructPromotionHelper* structPromotionHelper;
-#if !defined(TARGET_64BIT)
- void lvaPromoteLongVars();
-#endif // !defined(TARGET_64BIT)
unsigned lvaGetFieldLocal(const LclVarDsc* varDsc, unsigned int fldOffset);
lvaPromotionType lvaGetPromotionType(const LclVarDsc* varDsc);
lvaPromotionType lvaGetPromotionType(unsigned varNum);
//
void DecomposeLongs::PrepareForDecomposition()
{
- m_compiler->lvaPromoteLongVars();
+ PromoteLongVars();
}
//------------------------------------------------------------------------
}
}
-#endif // !TARGET_64BIT
+//------------------------------------------------------------------------
+// PromoteLongVars: "Struct promote" all register candidate longs as if they are structs of two ints.
+//
+// Arguments:
+// None.
+//
+// Return Value:
+// None.
+//
+void DecomposeLongs::PromoteLongVars()
+{
+ if ((m_compiler->opts.compFlags & CLFLG_REGVAR) == 0)
+ {
+ return;
+ }
+
+ // The lvaTable might grow as we grab temps. Make a local copy here.
+ unsigned startLvaCount = m_compiler->lvaCount;
+ for (unsigned lclNum = 0; lclNum < startLvaCount; lclNum++)
+ {
+ LclVarDsc* varDsc = m_compiler->lvaGetDesc(lclNum);
+ if (!varTypeIsLong(varDsc))
+ {
+ continue;
+ }
+ if (varDsc->lvDoNotEnregister)
+ {
+ continue;
+ }
+ if (varDsc->lvRefCnt() == 0)
+ {
+ continue;
+ }
+ if (varDsc->lvIsStructField)
+ {
+ continue;
+ }
+ if (m_compiler->fgNoStructPromotion)
+ {
+ continue;
+ }
+ if (m_compiler->fgNoStructParamPromotion && varDsc->lvIsParam)
+ {
+ continue;
+ }
+
+ assert(!varDsc->lvIsMultiRegArgOrRet());
+ varDsc->lvFieldCnt = 2;
+ varDsc->lvFieldLclStart = m_compiler->lvaCount;
+ varDsc->lvPromoted = true;
+ varDsc->lvContainsHoles = false;
+
+ JITDUMP("\nPromoting long local V%02u:", lclNum);
+
+ bool isParam = varDsc->lvIsParam;
+
+ for (unsigned index = 0; index < 2; ++index)
+ {
+ // Grab the temp for the field local.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef DEBUG
+ char buf[200];
+ sprintf_s(buf, sizeof(buf), "%s V%02u.%s (fldOffset=0x%x)", "field", lclNum, index == 0 ? "lo" : "hi",
+ index * 4);
+
+ // We need to copy 'buf' as lvaGrabTemp() below caches a copy to its argument.
+ size_t len = strlen(buf) + 1;
+ char* bufp = m_compiler->getAllocator(CMK_DebugOnly).allocate<char>(len);
+ strcpy_s(bufp, len, buf);
+#endif
+
+ unsigned varNum =
+ m_compiler->lvaGrabTemp(false DEBUGARG(bufp)); // Lifetime of field locals might span multiple BBs, so
+ // they are long lifetime temps.
+
+ LclVarDsc* fieldVarDsc = m_compiler->lvaGetDesc(varNum);
+ fieldVarDsc->lvType = TYP_INT;
+ fieldVarDsc->lvExactSize = genTypeSize(TYP_INT);
+ fieldVarDsc->lvIsStructField = true;
+ fieldVarDsc->lvFldOffset = (unsigned char)(index * genTypeSize(TYP_INT));
+ fieldVarDsc->lvFldOrdinal = (unsigned char)index;
+ fieldVarDsc->lvParentLcl = lclNum;
+ // Currently we do not support enregistering incoming promoted aggregates with more than one field.
+ if (isParam)
+ {
+ fieldVarDsc->lvIsParam = true;
+ m_compiler->lvaSetVarDoNotEnregister(varNum DEBUGARG(Compiler::DNER_LongParamField));
+ }
+ }
+ }
+
+#ifdef DEBUG
+ if (m_compiler->verbose)
+ {
+ printf("\nlvaTable after PromoteLongVars\n");
+ m_compiler->lvaTableDump();
+ }
+#endif // DEBUG
+}
+#endif // !defined(TARGET_64BIT)
return *m_range;
}
+ void PromoteLongVars();
+
// Driver functions
void DecomposeRangeHelper();
GenTree* DecomposeNode(GenTree* tree);
#ifdef DEBUG
if (!compIsForInlining())
{
- if ((JitConfig.JitNoStructPromotion() & 1) == 1)
+ const int noStructPromotionValue = JitConfig.JitNoStructPromotion();
+ assert(0 <= noStructPromotionValue && noStructPromotionValue <= 2);
+ if (noStructPromotionValue == 1)
{
fgNoStructPromotion = true;
}
- if ((JitConfig.JitNoStructPromotion() & 2) == 2)
+ if (noStructPromotionValue == 2)
{
fgNoStructParamPromotion = true;
}
CONFIG_INTEGER(JitNoInline, W("JitNoInline"), 0) // Disables inlining of all methods
CONFIG_INTEGER(JitNoMemoryBarriers, W("JitNoMemoryBarriers"), 0) // If 1, don't generate memory barriers
CONFIG_INTEGER(JitNoRegLoc, W("JitNoRegLoc"), 0)
-CONFIG_INTEGER(JitNoStructPromotion, W("JitNoStructPromotion"), 0) // Disables struct promotion in Jit32
+CONFIG_INTEGER(JitNoStructPromotion, W("JitNoStructPromotion"), 0) // Disables struct promotion 1 - for all, 2 - for
+ // params.
CONFIG_INTEGER(JitNoUnroll, W("JitNoUnroll"), 0)
CONFIG_INTEGER(JitOrder, W("JitOrder"), 0)
CONFIG_INTEGER(JitQueryCurrentStaticFieldClass, W("JitQueryCurrentStaticFieldClass"), 1)
}
}
-#if !defined(TARGET_64BIT)
-//------------------------------------------------------------------------
-// lvaPromoteLongVars: "Struct promote" all register candidate longs as if they are structs of two ints.
-//
-// Arguments:
-// None.
-//
-// Return Value:
-// None.
-//
-void Compiler::lvaPromoteLongVars()
-{
- if ((opts.compFlags & CLFLG_REGVAR) == 0)
- {
- return;
- }
-
- // The lvaTable might grow as we grab temps. Make a local copy here.
- unsigned startLvaCount = lvaCount;
- for (unsigned lclNum = 0; lclNum < startLvaCount; lclNum++)
- {
- LclVarDsc* varDsc = &lvaTable[lclNum];
- if (!varTypeIsLong(varDsc) || varDsc->lvDoNotEnregister || (varDsc->lvRefCnt() == 0) ||
- varDsc->lvIsStructField || (fgNoStructPromotion && varDsc->lvIsParam))
- {
- continue;
- }
-
- assert(!varDsc->lvIsMultiRegArgOrRet());
- varDsc->lvFieldCnt = 2;
- varDsc->lvFieldLclStart = lvaCount;
- varDsc->lvPromoted = true;
- varDsc->lvContainsHoles = false;
-
-#ifdef DEBUG
- if (verbose)
- {
- printf("\nPromoting long local V%02u:", lclNum);
- }
-#endif
-
- bool isParam = varDsc->lvIsParam;
-
- for (unsigned index = 0; index < 2; ++index)
- {
- // Grab the temp for the field local.
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#ifdef DEBUG
- char buf[200];
- sprintf_s(buf, sizeof(buf), "%s V%02u.%s (fldOffset=0x%x)", "field", lclNum, index == 0 ? "lo" : "hi",
- index * 4);
-
- // We need to copy 'buf' as lvaGrabTemp() below caches a copy to its argument.
- size_t len = strlen(buf) + 1;
- char* bufp = getAllocator(CMK_DebugOnly).allocate<char>(len);
- strcpy_s(bufp, len, buf);
-#endif
-
- unsigned varNum = lvaGrabTemp(false DEBUGARG(bufp)); // Lifetime of field locals might span multiple BBs, so
- // they are long lifetime temps.
-
- LclVarDsc* fieldVarDsc = &lvaTable[varNum];
- fieldVarDsc->lvType = TYP_INT;
- fieldVarDsc->lvExactSize = genTypeSize(TYP_INT);
- fieldVarDsc->lvIsStructField = true;
- fieldVarDsc->lvFldOffset = (unsigned char)(index * genTypeSize(TYP_INT));
- fieldVarDsc->lvFldOrdinal = (unsigned char)index;
- fieldVarDsc->lvParentLcl = lclNum;
- // Currently we do not support enregistering incoming promoted aggregates with more than one field.
- if (isParam)
- {
- fieldVarDsc->lvIsParam = true;
- lvaSetVarDoNotEnregister(varNum DEBUGARG(DNER_LongParamField));
- }
- }
- }
-
-#ifdef DEBUG
- if (verbose)
- {
- printf("\nlvaTable after lvaPromoteLongVars\n");
- lvaTableDump();
- }
-#endif // DEBUG
-}
-#endif // !defined(TARGET_64BIT)
-
//--------------------------------------------------------------------------------------------
// lvaGetFieldLocal - returns the local var index for a promoted field in a promoted struct var.
//