Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Andreenko <seandree@microsoft.com>2021-07-13 09:18:32 +0300
committerGitHub <noreply@github.com>2021-07-13 09:18:32 +0300
commit92ed4005e70b37d6d0093d3e68da51f3749f15be (patch)
tree07e7adf446c0f35a22cdb64a9a3a170101d48423 /src/coreclr/jit
parent7b19ccefccb4d116a64bf09c9bb1db3dd1df35e8 (diff)
Enreg structs x86 windows. (#55535)
* Mark more cases as DoNotEnreg before CSE. There are CSE metrics that take into account how many potential enreg locals do we have. * enable for x86.
Diffstat (limited to 'src/coreclr/jit')
-rw-r--r--src/coreclr/jit/gentree.h1
-rw-r--r--src/coreclr/jit/jitconfigvalues.h2
-rw-r--r--src/coreclr/jit/lclvars.cpp4
-rw-r--r--src/coreclr/jit/lsra.cpp17
4 files changed, 20 insertions, 4 deletions
diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h
index 4aeeeb9e486..4b7374573ef 100644
--- a/src/coreclr/jit/gentree.h
+++ b/src/coreclr/jit/gentree.h
@@ -6801,6 +6801,7 @@ struct GenTreeCopyOrReload : public GenTreeUnOp
GenTreeCopyOrReload(genTreeOps oper, var_types type, GenTree* op1) : GenTreeUnOp(oper, type, op1)
{
+ assert(type != TYP_STRUCT || op1->IsMultiRegNode());
SetRegNum(REG_NA);
ClearOtherRegs();
}
diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h
index b14597a8702..3220193c662 100644
--- a/src/coreclr/jit/jitconfigvalues.h
+++ b/src/coreclr/jit/jitconfigvalues.h
@@ -555,7 +555,7 @@ CONFIG_INTEGER(JitSaveFpLrWithCalleeSavedRegisters, W("JitSaveFpLrWithCalleeSave
#endif // defined(TARGET_ARM64)
#endif // DEBUG
-#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS)
+#if defined(TARGET_WINDOWS) && defined(TARGET_XARCH)
CONFIG_INTEGER(JitEnregStructLocals, W("JitEnregStructLocals"), 1) // Allow to enregister locals with struct type.
#else
CONFIG_INTEGER(JitEnregStructLocals, W("JitEnregStructLocals"), 0) // Don't allow to enregister locals with struct type
diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp
index 33c5abaa30d..75bcbfafbf2 100644
--- a/src/coreclr/jit/lclvars.cpp
+++ b/src/coreclr/jit/lclvars.cpp
@@ -3497,6 +3497,10 @@ void Compiler::lvaSortByRefCount()
{
lvaSetVarDoNotEnregister(lclNum DEBUGARG(DNER_IsStruct));
}
+ else if (!varDsc->IsEnregisterableType())
+ {
+ lvaSetVarDoNotEnregister(lclNum DEBUGARG(DNER_IsStruct));
+ }
}
if (varDsc->lvIsStructField && (lvaGetParentPromotionType(lclNum) != PROMOTION_TYPE_INDEPENDENT))
{
diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp
index 4bbb877fda8..f382b1dcf46 100644
--- a/src/coreclr/jit/lsra.cpp
+++ b/src/coreclr/jit/lsra.cpp
@@ -6180,10 +6180,21 @@ void LinearScan::insertCopyOrReload(BasicBlock* block, GenTree* tree, unsigned m
}
else
{
- // Create the new node, with "tree" as its only child.
- var_types treeType = tree->TypeGet();
+ var_types regType = tree->TypeGet();
+ if ((regType == TYP_STRUCT) && !tree->IsMultiRegNode())
+ {
+ assert(compiler->compEnregStructLocals());
+ assert(tree->IsLocal());
+ const GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
+ const LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
+ // We create struct copies with a primitive type so we don't bother copy node with parsing structHndl.
+ // Note that for multiReg node we keep each regType in the tree and don't need this.
+ regType = varDsc->GetRegisterType(lcl);
+ assert(regType != TYP_UNDEF);
+ }
- GenTreeCopyOrReload* newNode = new (compiler, oper) GenTreeCopyOrReload(oper, treeType, tree);
+ // Create the new node, with "tree" as its only child.
+ GenTreeCopyOrReload* newNode = new (compiler, oper) GenTreeCopyOrReload(oper, regType, tree);
assert(refPosition->registerAssignment != RBM_NONE);
SetLsraAdded(newNode);
newNode->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);