summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2018-10-25 16:25:41 -0700
committerGitHub <noreply@github.com>2018-10-25 16:25:41 -0700
commit459aa7db781797ba2dac17511a68d978ddc8a0ba (patch)
treeb4b016525dc1176dc1087e663209caf996aab611 /src/jit
parent0526f267a1bec0cc80f29a72f135ea980a4dd474 (diff)
parentada55ba08723fa2e0b2133291f2ee85820bbb75b (diff)
downloadcoreclr-459aa7db781797ba2dac17511a68d978ddc8a0ba.tar.gz
coreclr-459aa7db781797ba2dac17511a68d978ddc8a0ba.tar.bz2
coreclr-459aa7db781797ba2dac17511a68d978ddc8a0ba.zip
Merge pull request #20527 from BruceForstall/FixPspSymMove
Stop attempting to move PSPSym during localloc for arm32/arm64
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/codegenarm.cpp42
-rw-r--r--src/jit/codegenarm64.cpp73
-rw-r--r--src/jit/lsraarm.cpp26
-rw-r--r--src/jit/lsraarm64.cpp36
4 files changed, 36 insertions, 141 deletions
diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp
index b198da5a36..1e6044fc97 100644
--- a/src/jit/codegenarm.cpp
+++ b/src/jit/codegenarm.cpp
@@ -263,6 +263,7 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
void CodeGen::genLclHeap(GenTree* tree)
{
assert(tree->OperGet() == GT_LCLHEAP);
+ assert(compiler->compLocallocUsed);
GenTree* size = tree->gtOp.gtOp1;
noway_assert((genActualType(size->gtType) == TYP_INT) || (genActualType(size->gtType) == TYP_I_IMPL));
@@ -271,11 +272,9 @@ void CodeGen::genLclHeap(GenTree* tree)
// Also it used as temporary register in code generation
// for storing allocation size
regNumber regCnt = tree->gtRegNum;
- regNumber pspSymReg = REG_NA;
var_types type = genActualType(size->gtType);
emitAttr easz = emitTypeSize(type);
BasicBlock* endLabel = nullptr;
- BasicBlock* loop = nullptr;
unsigned stackAdjustment = 0;
#ifdef DEBUG
@@ -298,14 +297,6 @@ void CodeGen::genLclHeap(GenTree* tree)
noway_assert(isFramePointerUsed()); // localloc requires Frame Pointer to be established since SP changes
noway_assert(genStackLevel == 0); // Can't have anything on the stack
- // Whether method has PSPSym.
- bool hasPspSym;
-#if FEATURE_EH_FUNCLETS
- hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
-#else
- hasPspSym = false;
-#endif
-
// Check to 0 size allocations
// size_t amount = 0;
if (size->IsCnsIntOrI())
@@ -332,19 +323,7 @@ void CodeGen::genLclHeap(GenTree* tree)
}
stackAdjustment = 0;
-#if FEATURE_EH_FUNCLETS
- // If we have PSPsym, then need to re-locate it after localloc.
- if (hasPspSym)
- {
- stackAdjustment += STACK_ALIGN;
-
- // Save a copy of PSPSym
- pspSymReg = tree->ExtractTempReg();
- getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
- }
-#endif
-#if FEATURE_FIXED_OUT_ARGS
// If we have an outgoing arg area then we must adjust the SP by popping off the
// outgoing arg area. We will restore it right before we return from this method.
if (compiler->lvaOutgoingArgSpaceSize > 0)
@@ -354,7 +333,6 @@ void CodeGen::genLclHeap(GenTree* tree)
inst_RV_IV(INS_add, REG_SPBASE, compiler->lvaOutgoingArgSpaceSize, EA_PTRSIZE);
stackAdjustment += compiler->lvaOutgoingArgSpaceSize;
}
-#endif
// Put aligned allocation size to regCnt
if (size->IsCnsIntOrI())
@@ -382,7 +360,7 @@ void CodeGen::genLclHeap(GenTree* tree)
}
else if (!compiler->info.compInitMem && (amount < compiler->eeGetPageSize())) // must be < not <=
{
- // Since the size is a page or less, simply adjust the SP value
+ // Since the size is less than a page, simply adjust the SP value.
// The SP might already be in the guard page, must touch it BEFORE
// the alloc, not after.
getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regCnt, REG_SP, 0);
@@ -403,8 +381,8 @@ void CodeGen::genLclHeap(GenTree* tree)
// Allocation
if (compiler->info.compInitMem)
{
- // At this point 'regCnt' is set to the total number of bytes to locAlloc.
- // Since we have to zero out the allocated memory AND ensure that RSP is always valid
+ // At this point 'regCnt' is set to the total number of bytes to localloc.
+ // Since we have to zero out the allocated memory AND ensure that the stack pointer is always valid
// by tickling the pages, we will just push 0's on the stack.
regNumber regTmp = tree->ExtractTempReg();
@@ -498,21 +476,13 @@ void CodeGen::genLclHeap(GenTree* tree)
}
ALLOC_DONE:
- // Re-adjust SP to allocate PSPSym and out-going arg area
+ // Re-adjust SP to allocate out-going arg area
if (stackAdjustment != 0)
{
assert((stackAdjustment % STACK_ALIGN) == 0); // This must be true for the stack to remain aligned
assert(stackAdjustment > 0);
getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, (int)stackAdjustment);
-#if FEATURE_EH_FUNCLETS
- // Write PSPSym to its new location.
- if (hasPspSym)
- {
- assert(genIsValidIntReg(pspSymReg));
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
- }
-#endif
// Return the stackalloc'ed address in result register.
// regCnt = RSP + stackAdjustment.
getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, regCnt, REG_SPBASE, (int)stackAdjustment);
@@ -541,7 +511,7 @@ BAILOUT:
noway_assert(compiler->lvaReturnEspCheck != 0xCCCCCCCC &&
compiler->lvaTable[compiler->lvaReturnEspCheck].lvDoNotEnregister &&
compiler->lvaTable[compiler->lvaReturnEspCheck].lvOnFrame);
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, regCnt, compiler->lvaReturnEspCheck, 0);
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaReturnEspCheck, 0);
}
#endif
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index 6aad5d957a..b2a793b156 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -1831,6 +1831,7 @@ void CodeGen::genSimpleReturn(GenTree* treeNode)
void CodeGen::genLclHeap(GenTree* tree)
{
assert(tree->OperGet() == GT_LCLHEAP);
+ assert(compiler->compLocallocUsed);
GenTree* size = tree->gtOp.gtOp1;
noway_assert((genActualType(size->gtType) == TYP_INT) || (genActualType(size->gtType) == TYP_I_IMPL));
@@ -1864,14 +1865,6 @@ void CodeGen::genLclHeap(GenTree* tree)
noway_assert(isFramePointerUsed()); // localloc requires Frame Pointer to be established since SP changes
noway_assert(genStackLevel == 0); // Can't have anything on the stack
- // Whether method has PSPSym.
- bool hasPspSym;
-#if FEATURE_EH_FUNCLETS
- hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
-#else
- hasPspSym = false;
-#endif
-
// compute the amount of memory to allocate to properly STACK_ALIGN.
size_t amount = 0;
if (size->IsCnsIntOrI())
@@ -1900,9 +1893,9 @@ void CodeGen::genLclHeap(GenTree* tree)
inst_JMP(jmpEqual, endLabel);
// Compute the size of the block to allocate and perform alignment.
- // If the method has no PSPSym and compInitMem=true, we can reuse targetReg as regcnt,
+ // If compInitMem=true, we can reuse targetReg as regcnt,
// since we don't need any internal registers.
- if (!hasPspSym && compiler->info.compInitMem)
+ if (compiler->info.compInitMem)
{
assert(tree->AvailableTempRegCount() == 0);
regCnt = targetReg;
@@ -1923,34 +1916,18 @@ void CodeGen::genLclHeap(GenTree* tree)
}
stackAdjustment = 0;
-#if FEATURE_EH_FUNCLETS
- // If we have PSPsym, then need to re-locate it after localloc.
- if (hasPspSym)
- {
- stackAdjustment += STACK_ALIGN;
-
- // Save a copy of PSPSym
- pspSymReg = tree->ExtractTempReg();
- getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
- }
-#endif
-#if FEATURE_FIXED_OUT_ARGS
// If we have an outgoing arg area then we must adjust the SP by popping off the
// outgoing arg area. We will restore it right before we return from this method.
//
- // Localloc is supposed to return stack space that is STACK_ALIGN'ed. The following
- // are the cases that needs to be handled:
- // i) Method has PSPSym + out-going arg area.
- // It is guaranteed that size of out-going arg area is STACK_ALIGNED (see fgMorphArgs).
- // Therefore, we will pop-off RSP upto out-going arg area before locallocating.
- // We need to add padding to ensure RSP is STACK_ALIGN'ed while re-locating PSPSym + arg area.
- // ii) Method has no PSPSym but out-going arg area.
- // Almost same case as above without the requirement to pad for the final RSP to be STACK_ALIGN'ed.
- // iii) Method has PSPSym but no out-going arg area.
- // Nothing to pop-off from the stack but needs to relocate PSPSym with SP padded.
- // iv) Method has neither PSPSym nor out-going arg area.
- // Nothing needs to popped off from stack nor relocated.
+ // Localloc returns stack space that aligned to STACK_ALIGN bytes. The following
+ // are the cases that need to be handled:
+ // i) Method has out-going arg area.
+ // It is guaranteed that size of out-going arg area is STACK_ALIGN'ed (see fgMorphArgs).
+ // Therefore, we will pop off the out-going arg area from the stack pointer before allocating the localloc
+ // space.
+ // ii) Method has no out-going arg area.
+ // Nothing to pop off from the stack.
if (compiler->lvaOutgoingArgSpaceSize > 0)
{
assert((compiler->lvaOutgoingArgSpaceSize % STACK_ALIGN) == 0); // This must be true for the stack to remain
@@ -1958,7 +1935,6 @@ void CodeGen::genLclHeap(GenTree* tree)
inst_RV_IV(INS_add, REG_SPBASE, compiler->lvaOutgoingArgSpaceSize, EA_PTRSIZE);
stackAdjustment += compiler->lvaOutgoingArgSpaceSize;
}
-#endif
if (size->IsCnsIntOrI())
{
@@ -1983,9 +1959,10 @@ void CodeGen::genLclHeap(GenTree* tree)
}
else if (!compiler->info.compInitMem && (amount < compiler->eeGetPageSize())) // must be < not <=
{
- // Since the size is a page or less, simply adjust the SP value
- // The SP might already be in the guard page, must touch it BEFORE
+ // Since the size is less than a page, simply adjust the SP value.
+ // The SP might already be in the guard page, so we must touch it BEFORE
// the alloc, not after.
+
// ldr wz, [SP, #0]
getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, REG_ZR, REG_SP, 0);
@@ -1995,10 +1972,10 @@ void CodeGen::genLclHeap(GenTree* tree)
}
// else, "mov regCnt, amount"
- // If the method has no PSPSym and compInitMem=true, we can reuse targetReg as regcnt.
+ // If compInitMem=true, we can reuse targetReg as regcnt.
// Since size is a constant, regCnt is not yet initialized.
assert(regCnt == REG_NA);
- if (!hasPspSym && compiler->info.compInitMem)
+ if (compiler->info.compInitMem)
{
assert(tree->AvailableTempRegCount() == 0);
regCnt = targetReg;
@@ -2015,7 +1992,7 @@ void CodeGen::genLclHeap(GenTree* tree)
BasicBlock* loop = genCreateTempLabel();
// At this point 'regCnt' is set to the total number of bytes to locAlloc.
- // Since we have to zero out the allocated memory AND ensure that RSP is always valid
+ // Since we have to zero out the allocated memory AND ensure that the stack pointer is always valid
// by tickling the pages, we will just push 0's on the stack.
//
// Note: regCnt is guaranteed to be even on Amd64 since STACK_ALIGN/TARGET_POINTER_SIZE = 2
@@ -2038,7 +2015,7 @@ void CodeGen::genLclHeap(GenTree* tree)
}
else
{
- // At this point 'regCnt' is set to the total number of bytes to locAlloc.
+ // At this point 'regCnt' is set to the total number of bytes to localloc.
//
// We don't need to zero out the allocated memory. However, we do have
// to tickle the pages to ensure that SP is always valid and is
@@ -2109,23 +2086,15 @@ void CodeGen::genLclHeap(GenTree* tree)
}
ALLOC_DONE:
- // Re-adjust SP to allocate PSPSym and out-going arg area
+ // Re-adjust SP to allocate out-going arg area
if (stackAdjustment != 0)
{
assert((stackAdjustment % STACK_ALIGN) == 0); // This must be true for the stack to remain aligned
assert(stackAdjustment > 0);
getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, (int)stackAdjustment);
-#if FEATURE_EH_FUNCLETS
- // Write PSPSym to its new location.
- if (hasPspSym)
- {
- assert(genIsValidIntReg(pspSymReg));
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
- }
-#endif
// Return the stackalloc'ed address in result register.
- // TargetReg = RSP + stackAdjustment.
+ // TargetReg = SP + stackAdjustment.
//
getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, targetReg, REG_SPBASE, (int)stackAdjustment);
}
@@ -2248,7 +2217,7 @@ void CodeGen::genCodeForDivMod(GenTreeOp* tree)
{
GenTreeIntConCommon* intConstTree = divisorOp->AsIntConCommon();
ssize_t intConstValue = intConstTree->IconValue();
- assert(intConstValue != 0); // already checked above by IsIntegralConst(0))
+ assert(intConstValue != 0); // already checked above by IsIntegralConst(0)
if (intConstValue != -1)
{
checkDividend = false; // We statically know that the dividend is not -1
diff --git a/src/jit/lsraarm.cpp b/src/jit/lsraarm.cpp
index 980b2a3d64..f64b7fb3f0 100644
--- a/src/jit/lsraarm.cpp
+++ b/src/jit/lsraarm.cpp
@@ -36,18 +36,11 @@ int LinearScan::BuildLclHeap(GenTree* tree)
//
// Size? Init Memory? # temp regs
// 0 - 0
- // const and <=4 str instr - hasPspSym ? 1 : 0
- // const and <PageSize No hasPspSym ? 1 : 0
- // >4 ptr words Yes hasPspSym ? 2 : 1
- // Non-const Yes hasPspSym ? 2 : 1
- // Non-const No hasPspSym ? 2 : 1
-
- bool hasPspSym;
-#if FEATURE_EH_FUNCLETS
- hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
-#else
- hasPspSym = false;
-#endif
+ // const and <=4 str instr - 0
+ // const and <PageSize No 0
+ // >4 ptr words Yes 1
+ // Non-const Yes 1
+ // Non-const No 1
GenTree* size = tree->gtGetOp1();
int internalIntCount;
@@ -87,18 +80,13 @@ int LinearScan::BuildLclHeap(GenTree* tree)
{
internalIntCount = 1;
}
-
- if (hasPspSym)
- {
- internalIntCount++;
- }
}
}
else
{
- // target (regCnt) + tmp + [psp]
+ // target (regCnt) + tmp
srcCount = 1;
- internalIntCount = hasPspSym ? 2 : 1;
+ internalIntCount = 1;
BuildUse(size);
}
diff --git a/src/jit/lsraarm64.cpp b/src/jit/lsraarm64.cpp
index 76b56b3688..d5446362fe 100644
--- a/src/jit/lsraarm64.cpp
+++ b/src/jit/lsraarm64.cpp
@@ -522,18 +522,10 @@ int LinearScan::BuildNode(GenTree* tree)
// 0 - 0
// const and <=6 ptr words - 0
// const and <PageSize No 0
- // >6 ptr words Yes hasPspSym ? 1 : 0
- // Non-const Yes hasPspSym ? 1 : 0
+ // >6 ptr words Yes 0
+ // Non-const Yes 0
// Non-const No 2
//
- // PSPSym - If the method has PSPSym increment internalIntCount by 1.
- //
- bool hasPspSym;
-#if FEATURE_EH_FUNCLETS
- hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
-#else
- hasPspSym = false;
-#endif
GenTree* size = tree->gtGetOp1();
if (size->IsCnsIntOrI())
@@ -572,14 +564,6 @@ int LinearScan::BuildNode(GenTree* tree)
buildInternalIntRegisterDefForNode(tree);
}
}
- else if (hasPspSym)
- {
- // greater than 4 and need to zero initialize allocated stack space.
- // If the method has PSPSym, we need an internal register to hold regCnt
- // since targetReg allocated to GT_LCLHEAP node could be the same as one of
- // the the internal registers.
- buildInternalIntRegisterDefForNode(tree);
- }
}
}
else
@@ -590,24 +574,8 @@ int LinearScan::BuildNode(GenTree* tree)
buildInternalIntRegisterDefForNode(tree);
buildInternalIntRegisterDefForNode(tree);
}
- else if (hasPspSym)
- {
- // If the method has PSPSym, we need an internal register to hold regCnt
- // since targetReg allocated to GT_LCLHEAP node could be the same as one of
- // the the internal registers.
- buildInternalIntRegisterDefForNode(tree);
- }
}
- // If the method has PSPSym, we need an additional register to relocate it on stack.
- if (hasPspSym)
- {
- // Exclude const size 0
- if (!size->IsCnsIntOrI() || (size->gtIntCon.gtIconVal > 0))
- {
- buildInternalIntRegisterDefForNode(tree);
- }
- }
if (!size->isContained())
{
BuildUse(size);