summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Sullivan <briansul@microsoft.com>2016-06-09 10:46:57 -0700
committerBrian Sullivan <briansul@microsoft.com>2016-06-09 13:34:58 -0700
commit15690118463f18adc6411c3c4fb839e824e61a61 (patch)
tree0861efd63c746656894c504d89665f64010efc9e
parentce40049d1a4d94a63581694cbb3fd18222e318aa (diff)
downloadcoreclr-15690118463f18adc6411c3c4fb839e824e61a61.tar.gz
coreclr-15690118463f18adc6411c3c4fb839e824e61a61.tar.bz2
coreclr-15690118463f18adc6411c3c4fb839e824e61a61.zip
Code review cleanup items and moved some items into LEGACY_BACKEND ifdefs
From Codereview feedback: Use BAD_VAR_NUM in a couple places instead of (unsigned)-1 In struct InitVarDscInfo Renamed hasRetBuf to hasRetBufArg In struct RegState: Moved field rsCurRegArmNum into LEGACY_BACKEND ifdef Removed instance field RegState::rsMaxRegArgNum as it is unnecessary Reordered the fields from largest to smallest In struct GenTreeCall node: Moved field gtCallRegUsedMask into LEGACY_BACKEND ifdef Changes to genRegArgNext to work correct for X64/UNIX (where it is not currently used) Document the behavaior when given REG_ARG_LAST
-rwxr-xr-xsrc/jit/codegencommon.cpp19
-rw-r--r--src/jit/codegeninterface.h9
-rw-r--r--src/jit/compiler.hpp9
-rw-r--r--src/jit/gentree.cpp10
-rw-r--r--src/jit/gentree.h2
-rw-r--r--src/jit/lclvars.cpp2
-rw-r--r--src/jit/lsra.cpp11
-rw-r--r--src/jit/morph.cpp11
-rw-r--r--src/jit/regalloc.cpp2
-rw-r--r--src/jit/register_arg_convention.h10
-rw-r--r--src/jit/regset.cpp45
11 files changed, 92 insertions, 38 deletions
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index ae590e3924..aa2e8de45d 100755
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -129,10 +129,12 @@ CodeGen::CodeGen(Compiler * theCompiler) :
instInit();
+#ifdef LEGACY_BACKEND
// TODO-Cleanup: These used to be set in rsInit() - should they be moved to RegSet??
// They are also accessed by the register allocators and fgMorphLclVar().
intRegState.rsCurRegArgNum = 0;
floatRegState.rsCurRegArgNum = 0;
+#endif // LEGACY_BACKEND
#ifdef LATE_DISASM
getDisAssembler().disInit(compiler);
@@ -3765,7 +3767,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg,
// No need further action.
return;
}
-#endif
+#endif
unsigned argMax; // maximum argNum value plus 1, (including the RetBuffArg)
unsigned argNum; // current argNum, always in [0..argMax-1]
@@ -4086,12 +4088,14 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg,
#ifdef _TARGET_ARM_
int lclSize = compiler->lvaLclSize(varNum);
+
if (lclSize > REGSIZE_BYTES)
{
+ unsigned maxRegArgNum = doingFloat ? MAX_FLOAT_REG_ARG : MAX_REG_ARG;
slots = lclSize / REGSIZE_BYTES;
- if (regArgNum + slots > regState->rsMaxRegArgNum)
+ if (regArgNum + slots > maxRegArgNum)
{
- slots = regState->rsMaxRegArgNum - regArgNum;
+ slots = maxRegArgNum - regArgNum;
}
}
C_ASSERT((char)MAX_REG_ARG == MAX_REG_ARG);
@@ -10434,11 +10438,6 @@ void CodeGen::genRestoreCalleeSavedFltRegs(unsigned lclFrameSize)
}
#endif // defined(_TARGET_XARCH_) && !FEATURE_STACK_FP_X87
-
-//------------------------------------------------------------------------
-// Methods used to support FEATURE_MULTIREG_ARGS_OR_RET and HFA support for ARM32
-//------------------------------------------------------------------------
-
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
bool Compiler::IsRegisterPassable(CORINFO_CLASS_HANDLE hClass)
{
@@ -10478,6 +10477,10 @@ bool Compiler::IsMultiRegReturnedType(CORINFO_CLASS_HANDLE hClass)
}
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+//----------------------------------------------
+// Methods that support HFA's for ARM32/ARM64
+//----------------------------------------------
+
bool Compiler::IsHfa(CORINFO_CLASS_HANDLE hClass)
{
#ifdef FEATURE_HFA
diff --git a/src/jit/codegeninterface.h b/src/jit/codegeninterface.h
index 1b1196d2be..cb4774d240 100644
--- a/src/jit/codegeninterface.h
+++ b/src/jit/codegeninterface.h
@@ -35,11 +35,12 @@ class emitter;
struct RegState
{
- unsigned rsCurRegArgNum; // current argument register (for caller)
- unsigned rsCalleeRegArgCount; // total number of incoming register arguments
regMaskTP rsCalleeRegArgMaskLiveIn; // mask of register arguments (live on entry to method)
- bool rsIsFloat;
- unsigned rsMaxRegArgNum; // maximum register argument number + 1 (that is, exclusive of end of range)
+#ifdef LEGACY_BACKEND
+ unsigned rsCurRegArgNum; // current argument number (for caller)
+#endif
+ unsigned rsCalleeRegArgCount; // total number of incoming register arguments of this kind (int or float)
+ bool rsIsFloat; // true for float argument registers, false for integer argument registers
};
//-------------------- CodeGenInterface ---------------------------------
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp
index 734e051e14..fd0154d35e 100644
--- a/src/jit/compiler.hpp
+++ b/src/jit/compiler.hpp
@@ -3278,7 +3278,7 @@ unsigned genMapIntRegNumToRegArgNum(regNumber regNum)
#endif
default:
assert(!"invalid register arg register");
- return (unsigned)-1;
+ return BAD_VAR_NUM;
}
}
@@ -3311,10 +3311,13 @@ unsigned genMapFloatRegNumToRegArgNum(regNumber regNum)
#endif
#endif
#endif
- default: assert(!"invalid register arg register"); return (unsigned)-1;
+ default:
+ assert(!"invalid register arg register");
+ return BAD_VAR_NUM;
}
#else
- assert(!"flt reg args not allowed"); return (unsigned)-1;
+ assert(!"flt reg args not allowed");
+ return BAD_VAR_NUM;
#endif
#endif // !arm
}
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index 92b39a9e55..304f34b888 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -5563,9 +5563,12 @@ GenTreeCall* Compiler::gtNewCallNode(gtCallTypes callType,
node->gtInlineCandidateInfo = NULL;
}
node->gtCallLateArgs = nullptr;
- node->gtCallRegUsedMask = RBM_NONE;
node->gtReturnType = type;
+#ifdef LEGACY_BACKEND
+ node->gtCallRegUsedMask = RBM_NONE;
+#endif // LEGACY_BACKEND
+
#ifdef FEATURE_READYTORUN_COMPILER
node->gtCall.gtEntryPoint.addr = nullptr;
#endif
@@ -6715,7 +6718,6 @@ GenTreePtr Compiler::gtCloneExpr(GenTree * tree,
// because the inlinee still uses the inliner's memory allocator anyway.)
copy->gtCall.callSig = tree->gtCall.callSig;
- copy->gtCall.gtCallRegUsedMask = tree->gtCall.gtCallRegUsedMask;
copy->gtCall.gtCallType = tree->gtCall.gtCallType;
copy->gtCall.gtReturnType = tree->gtCall.gtReturnType;
copy->gtCall.gtControlExpr = tree->gtCall.gtControlExpr;
@@ -6752,6 +6754,10 @@ GenTreePtr Compiler::gtCloneExpr(GenTree * tree,
copy->gtCall.gtReturnTypeDesc = tree->gtCall.gtReturnTypeDesc;
#endif
+#ifdef LEGACY_BACKEND
+ copy->gtCall.gtCallRegUsedMask = tree->gtCall.gtCallRegUsedMask;
+#endif // LEGACY_BACKEND
+
#ifdef FEATURE_READYTORUN_COMPILER
copy->gtCall.setEntryPoint(tree->gtCall.gtEntryPoint);
#endif
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index 862558eead..48c77b521e 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -2519,7 +2519,9 @@ struct GenTreeCall final : public GenTree
// FEATURE_FIXED_OUT_ARGS was enabled, so this makes GenTreeCall 4 bytes bigger on x86).
CORINFO_SIG_INFO* callSig; // Used by tail calls and to register callsites with the EE
+#ifdef LEGACY_BACKEND
regMaskTP gtCallRegUsedMask; // mask of registers used to pass parameters
+#endif // LEGACY_BACKEND
// State required to support multi-reg returning call nodes.
// For now it is enabled only for x64 unix.
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index 8160950f1a..72d7672225 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -453,7 +453,7 @@ void Compiler::lvaInitRetBuffArg(InitVarDscInfo * varDscInfo)
bool hasRetBuffArg = impMethodInfo_hasRetBuffArg(info.compMethodInfo);
// These two should always match
- noway_assert(hasRetBuffArg == varDscInfo->hasRetBuf);
+ noway_assert(hasRetBuffArg == varDscInfo->hasRetBufArg);
if (hasRetBuffArg)
{
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp
index 09d6d5efdc..07ef30d521 100644
--- a/src/jit/lsra.cpp
+++ b/src/jit/lsra.cpp
@@ -1026,8 +1026,6 @@ LinearScan::LinearScan(Compiler * theCompiler)
compiler->codeGen->intRegState.rsIsFloat = false;
compiler->codeGen->floatRegState.rsIsFloat = true;
- compiler->codeGen->intRegState.rsMaxRegArgNum = MAX_REG_ARG;
- compiler->codeGen->floatRegState.rsMaxRegArgNum = MAX_FLOAT_REG_ARG;
// Block sequencing (the order in which we schedule).
// Note that we don't initialize the bbVisitedSet until we do the first traversal
@@ -3463,8 +3461,8 @@ LinearScan::updateRegStateForArg(LclVarDsc* argDsc)
else
#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
{
- RegState * intRegState = &compiler->codeGen->intRegState;
- RegState * floatRegState = &compiler->codeGen->floatRegState;
+ RegState* intRegState = &compiler->codeGen->intRegState;
+ RegState* floatRegState = &compiler->codeGen->floatRegState;
// In the case of AMD64 we'll still use the floating point registers
// to model the register usage for argument on vararg calls, so
// we will ignore the varargs condition to determine whether we use
@@ -3684,7 +3682,10 @@ LinearScan::buildIntervals()
continue;
}
- if (argDsc->lvIsRegArg) updateRegStateForArg(argDsc);
+ if (argDsc->lvIsRegArg)
+ {
+ updateRegStateForArg(argDsc);
+ }
if (isCandidateVar(argDsc))
{
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index 37798a5994..5e6493b55f 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -210,11 +210,14 @@ GenTreePtr Compiler::fgMorphIntoHelperCall(GenTreePtr tree,
tree->gtCall.gtCallLateArgs = NULL;
tree->gtCall.fgArgInfo = NULL;
tree->gtCall.gtRetClsHnd = NULL;
- tree->gtCall.gtCallRegUsedMask = RBM_NONE;
tree->gtCall.gtCallMoreFlags = 0;
tree->gtCall.gtInlineCandidateInfo = NULL;
tree->gtCall.gtControlExpr = NULL;
+#ifdef LEGACY_BACKEND
+ tree->gtCall.gtCallRegUsedMask = RBM_NONE;
+#endif // LEGACY_BACKEND
+
#ifdef FEATURE_READYTORUN_COMPILER
tree->gtCall.gtEntryPoint.addr = nullptr;
#endif
@@ -2340,7 +2343,9 @@ void fgArgInfo::EvalArgsToTemps()
argReg = genRegArgNext(argReg);
allUsedRegs |= genRegMask(argReg);
}
+#ifdef LEGACY_BACKEND
callTree->gtCall.gtCallRegUsedMask |= allUsedRegs;
+#endif // LEGACY_BACKEND
}
#endif // _TARGET_ARM_
}
@@ -4043,13 +4048,15 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
if (!lateArgsComputed)
{
call->fgArgInfo->ArgsComplete();
+#ifdef LEGACY_BACKEND
call->gtCallRegUsedMask = genIntAllRegArgMask(intArgRegNum) & ~argSkippedRegMask;
if (fltArgRegNum > 0)
{
-#if defined(_TARGET_ARM_) || defined(_TARGET_AMD64_)
+#if defined(_TARGET_ARM_)
call->gtCallRegUsedMask |= genFltAllRegArgMask(fltArgRegNum) & ~fltArgSkippedRegMask;
#endif
}
+#endif // LEGACY_BACKEND
}
if (call->gtCallArgs)
diff --git a/src/jit/regalloc.cpp b/src/jit/regalloc.cpp
index b491747da3..0c7ae21702 100644
--- a/src/jit/regalloc.cpp
+++ b/src/jit/regalloc.cpp
@@ -78,8 +78,6 @@ void Compiler::raInit()
#endif
codeGen->intRegState.rsIsFloat = false;
codeGen->floatRegState.rsIsFloat = true;
- codeGen->intRegState.rsMaxRegArgNum = MAX_REG_ARG;
- codeGen->floatRegState.rsMaxRegArgNum = MAX_FLOAT_REG_ARG;
rpReverseEBPenreg = false;
rpAsgVarNum = -1;
diff --git a/src/jit/register_arg_convention.h b/src/jit/register_arg_convention.h
index 41d829619d..40db9b8136 100644
--- a/src/jit/register_arg_convention.h
+++ b/src/jit/register_arg_convention.h
@@ -18,7 +18,7 @@ struct InitVarDscInfo
unsigned maxIntRegArgNum;
unsigned maxFloatRegArgNum;
- bool hasRetBuf;
+ bool hasRetBufArg;
#ifdef _TARGET_ARM_
// Support back-filling of FP parameters. This is similar to code in gtMorphArgs() that
@@ -30,11 +30,11 @@ struct InitVarDscInfo
public:
// set to initial values
- void Init(LclVarDsc *lvaTable, bool _hasRetBuf)
+ void Init(LclVarDsc *lvaTable, bool _hasRetBufArg)
{
- hasRetBuf = _hasRetBuf;
- varDsc = lvaTable;
- varNum = 0;
+ hasRetBufArg = _hasRetBufArg;
+ varDsc = &lvaTable[0]; // the first argument LclVar 0
+ varNum = 0; // the first argument varNum 0
intRegArgNum = 0;
floatRegArgNum = 0;
maxIntRegArgNum = MAX_REG_ARG;
diff --git a/src/jit/regset.cpp b/src/jit/regset.cpp
index a188461450..79846e92c5 100644
--- a/src/jit/regset.cpp
+++ b/src/jit/regset.cpp
@@ -3458,19 +3458,52 @@ bool genIsProperRegPair(regPairNo regPair)
*
* Given a register that is an argument register
* returns the next argument register
+ *
+ * Note: that this method will return a non arg register
+ * when given REG_ARG_LAST
+ *
*/
regNumber genRegArgNext(regNumber argReg)
{
- assert(isValidIntArgReg(argReg));
+ assert(isValidIntArgReg(argReg));
+
+ regNumber result = REG_NA;
#ifdef _TARGET_AMD64_
- if (argReg == REG_ARG_1)
- return REG_ARG_2;
-#endif
+#ifdef UNIX_AMD64_ABI
+ // Windows X64 ABI:
+ // REG_EDI, REG_ESI, REG_ECX, REG_EDX, REG_R8, REG_R9
+ //
+ if (argReg == REG_ARG_1) // REG_ESI
+ {
+ result = REG_ARG_2; // REG_ECX
+ }
+ else if (argReg == REG_ARG_3) // REG_EDX
+ {
+ result = REG_ARG_4; // REG_R8
+ }
+#else // Windows ABI
+ // Windows X64 ABI:
+ // REG_ECX, REG_EDX, REG_R8, REG_R9
+ //
+ if (argReg == REG_ARG_1) // REG_EDX
+ {
+ result = REG_ARG_2; // REG_R8
+ }
+#endif // UNIX or Windows ABI
+#endif _TARGET_AMD64_
- // Otherwise we can iterate the argument registers by using +1
- return REG_NEXT(argReg);
+ // If we didn't set 'result' to valid register above
+ // then we will just iterate 'argReg' using REG_NEXT
+ //
+ if (result == REG_NA)
+ {
+ // Otherwise we just iterate the argument registers by using REG_NEXT
+ result = REG_NEXT(argReg);
+ }
+
+ return result;
}
#if !defined(_TARGET_X86_)