From b67a9166647833420fe8da071350c4b000921431 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Mon, 20 Jul 2020 01:16:41 -0700 Subject: [PATCH 1/3] Move `GetLclOffs` to `Common`. --- src/coreclr/src/jit/gentree.cpp | 12 ++++++++++++ src/coreclr/src/jit/gentree.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 8ca9a49a2ce7db..b2cd0ff63c62a2 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -19350,6 +19350,18 @@ regNumber GenTree::ExtractTempReg(regMaskTP mask /* = (regMaskTP)-1 */) return genRegNumFromMask(tempRegMask); } +uint16_t GenTreeLclVarCommon::GetLclOffs() const +{ + if (OperIsLocalField()) + { + return AsLclFld()->GetLclOffs(); + } + else + { + return 0; + } +} + #ifdef TARGET_ARM //------------------------------------------------------------------------ // IsOffsetMisaligned: check if the field needs a special handling on arm. diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index 5e51988d76686c..b6a95a1d3c7a74 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -3180,6 +3180,8 @@ struct GenTreeLclVarCommon : public GenTreeUnOp _gtSsaNum = SsaConfig::RESERVED_SSA_NUM; } + uint16_t GetLclOffs() const; + unsigned GetSsaNum() const { return _gtSsaNum; From 503a79276fe7670b9f9bb7d67ddf27ed2b057ad6 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Mon, 20 Jul 2020 01:16:53 -0700 Subject: [PATCH 2/3] Start using it. --- src/coreclr/src/jit/codegenarm64.cpp | 15 ++++----- src/coreclr/src/jit/codegenarmarch.cpp | 24 +++----------- src/coreclr/src/jit/codegenlinear.cpp | 8 ++--- src/coreclr/src/jit/codegenxarch.cpp | 42 +++++++----------------- src/coreclr/src/jit/emitarm64.cpp | 6 +--- src/coreclr/src/jit/emitxarch.cpp | 6 +--- src/coreclr/src/jit/gentree.cpp | 6 +--- src/coreclr/src/jit/morph.cpp | 2 +- src/coreclr/src/jit/simdcodegenxarch.cpp | 31 +++++++---------- 9 files changed, 39 insertions(+), 101 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 8ce7617de5d0ed..9b8c932f805011 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -4766,16 +4766,13 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) { assert((treeNode->OperGet() == GT_STORE_LCL_FLD) || (treeNode->OperGet() == GT_STORE_LCL_VAR)); - unsigned offs = 0; - unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum(); - assert(varNum < compiler->lvaCount); + GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon(); - if (treeNode->OperGet() == GT_STORE_LCL_FLD) - { - offs = treeNode->AsLclFld()->GetLclOffs(); - } + unsigned offs = lclVar->GetLclOffs(); + unsigned varNum = lclVar->GetLclNum(); + assert(varNum < compiler->lvaCount); - GenTree* op1 = treeNode->AsOp()->gtOp1; + GenTree* op1 = lclVar->gtGetOp1(); if (op1->isContained()) { @@ -4793,7 +4790,7 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) regNumber operandReg = genConsumeReg(op1); // Need an addtional integer register to extract upper 4 bytes from data. - regNumber tmpReg = treeNode->GetSingleTempReg(); + regNumber tmpReg = lclVar->GetSingleTempReg(); // store lower 8 bytes GetEmitter()->emitIns_S_R(INS_str, EA_8BYTE, operandReg, varNum, offs); diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 7dd95d2fdab6b8..a2d881588ab539 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -1959,11 +1959,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) { assert(dstAddr->OperIsLocalAddr()); dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs(); } regNumber srcReg; @@ -2095,11 +2091,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) assert(dstAddr->OperIsLocalAddr()); dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs(); } unsigned srcLclNum = BAD_VAR_NUM; @@ -2112,11 +2104,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) if (src->OperIs(GT_LCL_VAR, GT_LCL_FLD)) { srcLclNum = src->AsLclVarCommon()->GetLclNum(); - - if (src->OperIs(GT_LCL_FLD)) - { - srcOffset = src->AsLclFld()->GetLclOffs(); - } + srcOffset = src->AsLclVarCommon()->GetLclOffs(); } else { @@ -2136,11 +2124,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) { assert(srcAddr->OperIsLocalAddr()); srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); - - if (srcAddr->OperIs(GT_LCL_FLD_ADDR)) - { - srcOffset = srcAddr->AsLclFld()->GetLclOffs(); - } + srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs(); } } diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp index 94306e936549fe..5ce369b5242461 100644 --- a/src/coreclr/src/jit/codegenlinear.cpp +++ b/src/coreclr/src/jit/codegenlinear.cpp @@ -1741,15 +1741,11 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode, { // The OperLocalAddr is always contained. assert(srcAddr->isContained()); - GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon(); + const GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon(); // Generate LEA instruction to load the LclVar address in RSI. // Source is known to be on the stack. Use EA_PTRSIZE. - unsigned int offset = 0; - if (srcAddr->OperGet() == GT_LCL_FLD_ADDR) - { - offset = srcAddr->AsLclFld()->GetLclOffs(); - } + unsigned int offset = lclNode->GetLclOffs(); GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, lclNode->GetLclNum(), offset); } else diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 207cef87d94e38..e65dda6b46c7bc 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -2694,11 +2694,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) { assert(dstAddr->OperIsLocalAddr()); dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs(); } regNumber srcIntReg = REG_NA; @@ -2819,11 +2815,9 @@ void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst if (baseNode->OperIsLocalAddr()) { - if (baseNode->gtOper == GT_LCL_FLD_ADDR) - { - offset += baseNode->AsLclFld()->GetLclOffs(); - } - emit->emitIns_R_S(ins, size, dst, baseNode->AsLclVarCommon()->GetLclNum(), offset); + const GenTreeLclVarCommon* lclVar = baseNode->AsLclVarCommon(); + offset += lclVar->GetLclOffs(); + emit->emitIns_R_S(ins, size, dst, lclVar->GetLclNum(), offset); } else { @@ -2873,12 +2867,9 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) else { assert(dstAddr->OperIsLocalAddr()); - dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + const GenTreeLclVarCommon* lclVar = dstAddr->AsLclVarCommon(); + dstLclNum = lclVar->GetLclNum(); + dstOffset = lclVar->GetLclOffs(); } unsigned srcLclNum = BAD_VAR_NUM; @@ -2893,11 +2884,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) if (src->OperIs(GT_LCL_VAR, GT_LCL_FLD)) { srcLclNum = src->AsLclVarCommon()->GetLclNum(); - - if (src->OperIs(GT_LCL_FLD)) - { - srcOffset = src->AsLclFld()->GetLclOffs(); - } + srcOffset = src->AsLclVarCommon()->GetLclOffs(); } else { @@ -2929,11 +2916,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) { assert(srcAddr->OperIsLocalAddr()); srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); - - if (srcAddr->OperIs(GT_LCL_FLD_ADDR)) - { - srcOffset = srcAddr->AsLclFld()->GetLclOffs(); - } + srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs(); } } @@ -7941,11 +7924,8 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk) { assert(srcAddr->OperIsLocalAddr()); - srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); - if (srcAddr->OperGet() == GT_LCL_FLD_ADDR) - { - srcLclOffset = srcAddr->AsLclFld()->GetLclOffs(); - } + srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); + srcLclOffset = srcAddr->AsLclVarCommon()->GetLclOffs(); } for (int i = numSlots - 1; i >= 0; --i) diff --git a/src/coreclr/src/jit/emitarm64.cpp b/src/coreclr/src/jit/emitarm64.cpp index 9a82b01063b710..a23aef5812a618 100644 --- a/src/coreclr/src/jit/emitarm64.cpp +++ b/src/coreclr/src/jit/emitarm64.cpp @@ -13396,11 +13396,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR { GenTreeLclVarCommon* varNode = addr->AsLclVarCommon(); unsigned lclNum = varNode->GetLclNum(); - unsigned offset = 0; - if (addr->OperIs(GT_LCL_FLD_ADDR)) - { - offset = varNode->AsLclFld()->GetLclOffs(); - } + unsigned offset = varNode->GetLclOffs(); if (emitInsIsStore(ins)) { emitIns_S_R(ins, attr, dataReg, lclNum, offset); diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp index 81f9ce8ef68108..1938efb9ed44ab 100644 --- a/src/coreclr/src/jit/emitxarch.cpp +++ b/src/coreclr/src/jit/emitxarch.cpp @@ -3100,11 +3100,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m if (addr->OperIs(GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR)) { GenTreeLclVarCommon* varNode = addr->AsLclVarCommon(); - unsigned offset = 0; - if (addr->OperIs(GT_LCL_FLD_ADDR)) - { - offset = varNode->AsLclFld()->GetLclOffs(); - } + unsigned offset = varNode->GetLclOffs(); if (data->isContainedIntOrIImmed()) { emitIns_S_I(ins, attr, varNode->GetLclNum(), offset, (int)data->AsIntConCommon()->IconValue()); diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index b2cd0ff63c62a2..d9bf22b8ec338d 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -16365,11 +16365,7 @@ bool GenTree::DefinesLocalAddr(Compiler* comp, unsigned width, GenTreeLclVarComm *pLclVarTree = addrArgLcl; if (pIsEntire != nullptr) { - unsigned lclOffset = 0; - if (addrArg->OperIsLocalField()) - { - lclOffset = addrArg->AsLclFld()->GetLclOffs(); - } + unsigned lclOffset = addrArgLcl->GetLclOffs(); if (lclOffset != 0) { diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 4d420dabaa8091..c333a2799fe45b 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -4602,7 +4602,7 @@ GenTree* Compiler::fgMorphMultiregStructArg(GenTree* arg, fgArgTabEntry* fgEntry assert(varNum < lvaCount); LclVarDsc* varDsc = &lvaTable[varNum]; - unsigned baseOffset = argValue->OperIs(GT_LCL_FLD) ? argValue->AsLclFld()->GetLclOffs() : 0; + unsigned baseOffset = varNode->GetLclOffs(); unsigned lastOffset = baseOffset + structSize; // The allocated size of our LocalVar must be at least as big as lastOffset diff --git a/src/coreclr/src/jit/simdcodegenxarch.cpp b/src/coreclr/src/jit/simdcodegenxarch.cpp index a1acdfd2f1a729..4045c9b97f6280 100644 --- a/src/coreclr/src/jit/simdcodegenxarch.cpp +++ b/src/coreclr/src/jit/simdcodegenxarch.cpp @@ -585,9 +585,9 @@ void CodeGen::genSIMDIntrinsicInit(GenTreeSIMD* simdNode) } else if (op1->OperIsLocalAddr()) { - unsigned offset = op1->OperIs(GT_LCL_FLD_ADDR) ? op1->AsLclFld()->GetLclOffs() : 0; - GetEmitter()->emitIns_R_S(ins, emitTypeSize(targetType), targetReg, op1->AsLclVarCommon()->GetLclNum(), - offset); + const GenTreeLclVarCommon* lclVar = op1->AsLclVarCommon(); + unsigned offset = lclVar->GetLclOffs(); + GetEmitter()->emitIns_R_S(ins, emitTypeSize(targetType), targetReg, lclVar->GetLclNum(), offset); } else { @@ -2143,17 +2143,14 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) { assert((treeNode->OperGet() == GT_STORE_LCL_FLD) || (treeNode->OperGet() == GT_STORE_LCL_VAR)); - unsigned offs = 0; - unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum(); - assert(varNum < compiler->lvaCount); + const GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon(); - if (treeNode->OperGet() == GT_STORE_LCL_FLD) - { - offs = treeNode->AsLclFld()->GetLclOffs(); - } + unsigned offs = lclVar->GetLclOffs(); + unsigned varNum = lclVar->GetLclNum(); + assert(varNum < compiler->lvaCount); regNumber tmpReg = treeNode->GetSingleTempReg(); - GenTree* op1 = treeNode->AsOp()->gtOp1; + GenTree* op1 = lclVar->gtOp1; if (op1->isContained()) { // This is only possible for a zero-init. @@ -2197,16 +2194,12 @@ void CodeGen::genLoadLclTypeSIMD12(GenTree* treeNode) { assert((treeNode->OperGet() == GT_LCL_FLD) || (treeNode->OperGet() == GT_LCL_VAR)); - regNumber targetReg = treeNode->GetRegNum(); - unsigned offs = 0; - unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum(); + const GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon(); + regNumber targetReg = lclVar->GetRegNum(); + unsigned offs = lclVar->GetLclOffs(); + unsigned varNum = lclVar->GetLclNum(); assert(varNum < compiler->lvaCount); - if (treeNode->OperGet() == GT_LCL_FLD) - { - offs = treeNode->AsLclFld()->GetLclOffs(); - } - // Need an additional Xmm register that is different from targetReg to read upper 4 bytes. regNumber tmpReg = treeNode->GetSingleTempReg(); assert(tmpReg != targetReg); From bb173eb5de845c23ba007490bed00375f5577fe8 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Wed, 22 Jul 2020 00:54:46 -0700 Subject: [PATCH 3/3] Review response. --- src/coreclr/src/jit/codegenarm64.cpp | 4 ++-- src/coreclr/src/jit/gentree.cpp | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 9b8c932f805011..2edf42d8580ef4 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -4699,7 +4699,7 @@ void CodeGen::genStoreIndTypeSIMD12(GenTree* treeNode) genConsumeOperands(treeNode->AsOp()); - // Need an addtional integer register to extract upper 4 bytes from data. + // Need an additional integer register to extract upper 4 bytes from data. regNumber tmpReg = treeNode->GetSingleTempReg(); assert(tmpReg != addr->GetRegNum()); @@ -4789,7 +4789,7 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) } regNumber operandReg = genConsumeReg(op1); - // Need an addtional integer register to extract upper 4 bytes from data. + // Need an additional integer register to extract upper 4 bytes from data. regNumber tmpReg = lclVar->GetSingleTempReg(); // store lower 8 bytes diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index d9bf22b8ec338d..03b1d7ef87f1a3 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -19346,6 +19346,13 @@ regNumber GenTree::ExtractTempReg(regMaskTP mask /* = (regMaskTP)-1 */) return genRegNumFromMask(tempRegMask); } +//------------------------------------------------------------------------ +// GetLclOffs: if `this` is a field or a field address it returns offset +// of the field inside the struct, for not a field it returns 0. +// +// Return Value: +// The offset value. +// uint16_t GenTreeLclVarCommon::GetLclOffs() const { if (OperIsLocalField())