// fp callee save registers will be needed, such as loops or many fp vars.
// We keep two sets of vars, since we collect some of the information to determine which set to
// use as we iterate over the vars.
- // When we are generating AVX code, we maintain an additional set of LargeVectorType vars, and
- // there is a separate threshold defined for those. It is assumed that if we encounter these
- // that we should consider this a "high use" scenario, so we don't maintain two sets of these vars.
+ // When we are generating AVX code on non-Unix (FEATURE_PARTIAL_SIMD_CALLEE_SAVE), we maintain an
+ // additional set of LargeVectorType vars, and there is a separate threshold defined for those.
+ // It is assumed that if we encounter these, that we should consider this a "high use" scenario,
+ // so we don't maintain two sets of these vars.
// This is defined as thresholdLargeVectorRefCntWtd, as we are likely to use the same mechanism
// for vectors on Arm64, though the actual value may differ.
unsigned int floatVarCount = 0;
unsigned int thresholdFPRefCntWtd = 4 * BB_UNITY_WEIGHT;
unsigned int maybeFPRefCntWtd = 2 * BB_UNITY_WEIGHT;
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
VarSetOps::AssignNoCopy(compiler, largeVectorVars, VarSetOps::MakeEmpty(compiler));
VarSetOps::AssignNoCopy(compiler, largeVectorCalleeSaveCandidateVars, VarSetOps::MakeEmpty(compiler));
unsigned int largeVectorVarCount = 0;
unsigned int thresholdLargeVectorRefCntWtd = 4 * BB_UNITY_WEIGHT;
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
for (lclNum = 0, varDsc = compiler->lvaTable;
lclNum < compiler->lvaCount;
// We maintain two sets of FP vars - those that meet the first threshold of weighted ref Count,
// and those that meet the second (see the definitions of thresholdFPRefCntWtd and maybeFPRefCntWtd
// above).
- // Additionally, when we are generating AVX code, we keep a separate set of the LargeVectorType vars.
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
+ // Additionally, when we are generating AVX on non-UNIX amd64, we keep a separate set of the LargeVectorType vars.
if (varDsc->lvType == LargeVectorType)
{
largeVectorVarCount++;
}
}
else
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
if (regType(newInt->registerType) == FloatRegisterType)
{
floatVarCount++;
{
unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
LclVarDsc *varDsc = compiler->lvaTable + varNum;
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
if (varDsc->lvType == LargeVectorType)
{
if (!VarSetOps::IsMember(compiler, largeVectorCalleeSaveCandidateVars, varIndex))
}
}
else
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
if (varTypeIsFloating(varDsc) && !VarSetOps::IsMember(compiler, fpCalleeSaveCandidateVars, varIndex))
{
continue;
return RBM_NONE;
}
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
VARSET_VALRET_TP
LinearScan::buildUpperVectorSaveRefPositions(GenTree *tree,
LsraLocation currentLoc)
}
}
}
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
void
LinearScan::buildRefPositionsForNode(GenTree *tree,
assert(!varTypeIsMultiReg(tree->TypeGet()));
#endif // _TARGET_xxx_
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
VARSET_TP VARSET_INIT_NOCOPY(liveLargeVectors, VarSetOps::UninitVal());
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
// push defs
if (produce == 0)
{
buildKillPositionsForNode(tree, currentLoc + 1);
-#ifdef FEATURE_SIMD
- // Build RefPositions for saving any live large vectors.
- // This must be done after the kills, so that we know which large vectors are still live.
- VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc));
-#endif // FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
+ if (RBM_FLT_CALLEE_SAVED != RBM_NONE)
+ {
+ // Build RefPositions for saving any live large vectors.
+ // This must be done after the kills, so that we know which large vectors are still live.
+ VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc));
+ }
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
}
for (int i=0; i < produce; i++)
{
generatedKills = buildKillPositionsForNode(tree, lastDefLocation);
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
// Build RefPositions for saving any live large vectors.
// This must be done after the kills, so that we know which large vectors are still live.
VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc));
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
}
regMaskTP currCandidates = candidates;
interval->updateRegisterPreferences(currCandidates);
interval->updateRegisterPreferences(useCandidates);
}
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
buildUpperVectorRestoreRefPositions(tree, currentLoc, liveLargeVectors);
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
}
// make an interval for each physical register
tree->InsertAfterSelf(newNode);
}
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
//------------------------------------------------------------------------
// insertUpperVectorSaveAndReload: Insert code to save and restore the upper half of a vector that lives
// in a callee-save register at the point of a kill (the upper half is
compiler->fgInsertTreeAfterAsEmbedded(simdNode, tree, stmt->AsStmt(), block);
}
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
//------------------------------------------------------------------------
// initMaxSpill: Initializes the LinearScan members used to track the max number
// to know what they are here.
RefType refType = refPosition->refType;
var_types typ;
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
if ((refType == RefTypeUpperVectorSaveDef) || (refType == RefTypeUpperVectorSaveUse))
{
typ = LargeVectorSaveType;
}
else
-#endif // !FEATURE_SIMD
+#endif // !FEATURE_PARTIAL_SIMD_CALLEE_SAVE
{
GenTreePtr treeNode = refPosition->treeNode;
if (treeNode == nullptr)
updateMaxSpill(currentRefPosition);
GenTree *treeNode = currentRefPosition->treeNode;
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
if (currentRefPosition->refType == RefTypeUpperVectorSaveDef)
{
// The treeNode must be a call, and this must be a RefPosition for a LargeVectorType LocalVar.
{
continue;
}
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
// Most uses won't actually need to be recorded (they're on the def).
// In those cases, treeNode will be nullptr.
// than the one it was spilled from
void insertCopyOrReload(GenTreePtr tree, RefPosition* refPosition);
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
// Insert code to save and restore the upper half of a vector that lives
// in a callee-save register at the point of a call (the upper half is
// not preserved).
void insertUpperVectorSaveAndReload(GenTreePtr tree, RefPosition* refPosition, BasicBlock* block);
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
// resolve along one block-block edge
enum ResolveType { ResolveSplit, ResolveJoin, ResolveCritical, ResolveSharedCritical, ResolveTypeCount };
ArrayStack<LocationInfo> *stack,
LsraLocation loc);
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
VARSET_VALRET_TP buildUpperVectorSaveRefPositions(GenTree *tree, LsraLocation currentLoc);
void buildUpperVectorRestoreRefPositions(GenTree *tree, LsraLocation currentLoc, VARSET_VALARG_TP liveLargeVectors);
-#endif //FEATURE_SIMD
+#endif //FEATURE_PARTIAL_SIMD_CALLEE_SAVE
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
// For AMD64 on SystemV machines. This method
VARSET_TP currentLiveVars;
// Set of floating point variables to consider for callee-save registers.
VARSET_TP fpCalleeSaveCandidateVars;
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
#if defined(_TARGET_AMD64_)
static const var_types LargeVectorType = TYP_SIMD32;
static const var_types LargeVectorSaveType = TYP_SIMD16;
VARSET_TP largeVectorVars;
// Set of large vector (TYP_SIMD32 on AVX) variables to consider for callee-save registers.
VARSET_TP largeVectorCalleeSaveCandidateVars;
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
};
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bool RequiresRegister()
{
return (refType == RefTypeDef || refType == RefTypeUse
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
|| refType == RefTypeUpperVectorSaveDef || refType == RefTypeUpperVectorSaveUse
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
);
}