From 9b1009a4abad8dfabf6ddf61f8bf821e29668282 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Tue, 29 Nov 2022 23:58:01 +0300 Subject: [PATCH 01/10] Don't create IND for InitializeArray --- src/coreclr/jit/importercalls.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 3504e04d5025a..35d10b6c8d7f7 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2156,9 +2156,13 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) dataOffset = eeGetArrayDataOffset(); } - GenTree* dstAddr = gtNewOperNode(GT_ADD, TYP_BYREF, arrayLocalNode, gtNewIconNode(dataOffset, TYP_I_IMPL)); - GenTree* dst = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, dstAddr, typGetBlkLayout(blkSize)); - GenTree* src = gtNewIndOfIconHandleNode(TYP_STRUCT, (size_t)initData, GTF_ICON_CONST_PTR, true); + ClassLayout* blkLayout = typGetBlkLayout(blkSize); + GenTree* dstAddr = gtNewOperNode(GT_ADD, TYP_BYREF, arrayLocalNode, gtNewIconNode(dataOffset, TYP_I_IMPL)); + GenTree* dst = gtNewStructVal(blkLayout, dstAddr); + dst->gtFlags |= GTF_GLOB_REF; + + GenTree* srcAddr = gtNewIconHandleNode((size_t)initData, GTF_ICON_CONST_PTR); + GenTree* src = gtNewStructVal(blkLayout, srcAddr); #ifdef DEBUG src->gtGetOp1()->AsIntCon()->gtTargetHandle = THT_InitializeArrayIntrinsics; From a19032e6b757b88492e643efbcc7731b739c5c65 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Wed, 30 Nov 2022 00:04:09 +0300 Subject: [PATCH 02/10] Don't create IND in STORE_DYN_BLK morph --- src/coreclr/jit/morphblock.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp index e4fff99c05a94..813c949863472 100644 --- a/src/coreclr/jit/morphblock.cpp +++ b/src/coreclr/jit/morphblock.cpp @@ -1507,18 +1507,29 @@ GenTree* Compiler::fgMorphStoreDynBlock(GenTreeStoreDynBlk* tree) if ((size != 0) && FitsIn(size)) { - GenTree* lhs = gtNewBlockVal(tree->Addr(), static_cast(size)); - GenTree* asg = gtNewAssignNode(lhs, tree->Data()); + ClassLayout* layout = typGetBlkLayout(static_cast(size)); + GenTree* dst = gtNewStructVal(layout, tree->Addr()); + dst->gtFlags |= GTF_GLOB_REF; + + GenTree* src = tree->Data(); + if (src->OperIs(GT_IND)) + { + assert(src->TypeIs(TYP_STRUCT)); + src->SetOper(GT_BLK); + src->AsBlk()->SetLayout(layout); + src->AsBlk()->gtBlkOpKind = GenTreeBlk::BlkOpKindInvalid; +#ifndef JIT32_GCENCODER + src->AsBlk()->gtBlkOpGcUnsafe = false; +#endif // !JIT32_GCENCODER + } + + GenTree* asg = gtNewAssignNode(dst, src); asg->gtFlags |= (tree->gtFlags & (GTF_ALL_EFFECT | GTF_BLK_VOLATILE | GTF_BLK_UNALIGNED)); INDEBUG(asg->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED); - JITDUMP("MorphStoreDynBlock: transformed STORE_DYN_BLK into ASG(BLK, Data())\n"); + fgAssignSetVarDef(asg); - GenTree* lclVarTree = fgIsIndirOfAddrOfLocal(lhs); - if (lclVarTree != nullptr) - { - lclVarTree->gtFlags |= GTF_VAR_DEF; - } + JITDUMP("MorphStoreDynBlock: transformed STORE_DYN_BLK into ASG(BLK, Data())\n"); return tree->OperIsCopyBlkOp() ? fgMorphCopyBlock(asg) : fgMorphInitBlock(asg); } From 18658fb4ab12995adcb4d2374264db4d79f34ccb Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Wed, 30 Nov 2022 22:57:15 +0300 Subject: [PATCH 03/10] Don't create IND for FIELDs --- src/coreclr/jit/gentree.h | 28 ++++++++++++---------------- src/coreclr/jit/lclmorph.cpp | 12 ++---------- src/coreclr/jit/lower.cpp | 7 ++----- src/coreclr/jit/lowerloongarch64.cpp | 4 +--- src/coreclr/jit/morph.cpp | 12 +++++++++++- src/coreclr/jit/morphblock.cpp | 6 +----- 6 files changed, 29 insertions(+), 40 deletions(-) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 9c2007df0ea83..9285e1be447cb 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -7157,29 +7157,25 @@ struct GenTreeBlk : public GenTreeIndir GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, ClassLayout* layout) : GenTreeIndir(oper, type, addr, nullptr) - , m_layout(layout) - , gtBlkOpKind(BlkOpKindInvalid) -#ifndef JIT32_GCENCODER - , gtBlkOpGcUnsafe(false) -#endif { - assert(OperIsBlk(oper)); - assert((layout != nullptr) || OperIs(GT_STORE_DYN_BLK)); - gtFlags |= (addr->gtFlags & GTF_ALL_EFFECT); + Initialize(layout); } GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, GenTree* data, ClassLayout* layout) : GenTreeIndir(oper, type, addr, data) - , m_layout(layout) - , gtBlkOpKind(BlkOpKindInvalid) + { + Initialize(layout); + } + + void Initialize(ClassLayout* layout) + { + assert(OperIsBlk(OperGet()) && ((layout != nullptr) || OperIs(GT_STORE_DYN_BLK))); + + m_layout = layout; + gtBlkOpKind = BlkOpKindInvalid; #ifndef JIT32_GCENCODER - , gtBlkOpGcUnsafe(false) + gtBlkOpGcUnsafe = false; #endif - { - assert(OperIsBlk(oper)); - assert((layout != nullptr) || OperIs(GT_STORE_DYN_BLK)); - gtFlags |= (addr->gtFlags & GTF_ALL_EFFECT); - gtFlags |= (data->gtFlags & GTF_ALL_EFFECT); } #if DEBUGGABLE_GENTREE diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp index 810f22d7fe7b6..f90388c6ceae1 100644 --- a/src/coreclr/jit/lclmorph.cpp +++ b/src/coreclr/jit/lclmorph.cpp @@ -899,11 +899,7 @@ class LocalAddressVisitor final : public GenTreeVisitor { ClassLayout* layout = node->GetLayout(m_compiler); node->SetOper(GT_OBJ); - node->AsBlk()->SetLayout(layout); - node->AsBlk()->gtBlkOpKind = GenTreeBlk::BlkOpKindInvalid; -#ifndef JIT32_GCENCODER - node->AsBlk()->gtBlkOpGcUnsafe = false; -#endif // !JIT32_GCENCODER + node->AsBlk()->Initialize(layout); } else { @@ -1236,11 +1232,7 @@ class LocalAddressVisitor final : public GenTreeVisitor if (node->TypeIs(TYP_STRUCT)) { node->SetOper(GT_OBJ); - node->AsBlk()->SetLayout(layout); - node->AsBlk()->gtBlkOpKind = GenTreeBlk::BlkOpKindInvalid; -#ifndef JIT32_GCENCODER - node->AsBlk()->gtBlkOpGcUnsafe = false; -#endif // !JIT32_GCENCODER + node->AsBlk()->Initialize(layout); } else { diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 572a46c8d3bc8..7ba7c6f96fb90 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -3677,13 +3677,10 @@ void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore) lclStore->ChangeOper(GT_STORE_OBJ); GenTreeBlk* objStore = lclStore->AsObj(); objStore->gtFlags = GTF_ASG | GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP; -#ifndef JIT32_GCENCODER - objStore->gtBlkOpGcUnsafe = false; -#endif - objStore->gtBlkOpKind = GenTreeObj::BlkOpKindInvalid; - objStore->SetLayout(layout); + objStore->Initialize(layout); objStore->SetAddr(addr); objStore->SetData(src); + BlockRange().InsertBefore(objStore, addr); LowerNode(objStore); return; diff --git a/src/coreclr/jit/lowerloongarch64.cpp b/src/coreclr/jit/lowerloongarch64.cpp index d892e72d24d8a..06e68fc324bc2 100644 --- a/src/coreclr/jit/lowerloongarch64.cpp +++ b/src/coreclr/jit/lowerloongarch64.cpp @@ -408,9 +408,7 @@ void Lowering::LowerPutArgStkOrSplit(GenTreePutArgStk* putArgNode) src->ChangeOper(GT_OBJ); src->AsObj()->SetAddr(lclAddr); - src->AsObj()->SetLayout(layout); - src->AsObj()->gtBlkOpKind = GenTreeBlk::BlkOpKindInvalid; - src->AsObj()->gtBlkOpGcUnsafe = false; + src->AsObj()->Initialize(layout); BlockRange().InsertBefore(src, lclAddr); } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 13e81bda6ac74..0e4012560bb1c 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -5152,7 +5152,17 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m if (tree->OperIs(GT_FIELD)) { - tree->SetOper(GT_IND); + if (tree->TypeIs(TYP_STRUCT)) + { + ClassLayout* layout = tree->GetLayout(this); + tree->SetOper(GT_OBJ); + tree->AsBlk()->Initialize(layout); + } + else + { + tree->SetOper(GT_IND); + } + tree->AsIndir()->SetAddr(addr); } else // Otherwise, we have a FIELD_ADDR. diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp index 813c949863472..4bcfbf058ecf0 100644 --- a/src/coreclr/jit/morphblock.cpp +++ b/src/coreclr/jit/morphblock.cpp @@ -1516,11 +1516,7 @@ GenTree* Compiler::fgMorphStoreDynBlock(GenTreeStoreDynBlk* tree) { assert(src->TypeIs(TYP_STRUCT)); src->SetOper(GT_BLK); - src->AsBlk()->SetLayout(layout); - src->AsBlk()->gtBlkOpKind = GenTreeBlk::BlkOpKindInvalid; -#ifndef JIT32_GCENCODER - src->AsBlk()->gtBlkOpGcUnsafe = false; -#endif // !JIT32_GCENCODER + src->AsBlk()->Initialize(layout); } GenTree* asg = gtNewAssignNode(dst, src); From 07d5d5f841e85d014612f5574767a9ee7dc039b5 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Wed, 30 Nov 2022 00:17:39 +0300 Subject: [PATCH 04/10] Simplify code --- src/coreclr/jit/gentree.cpp | 7 +++---- src/coreclr/jit/lower.cpp | 14 +++----------- src/coreclr/jit/morphblock.cpp | 13 +------------ 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 13c79a059ebe6..2c372d18cd26d 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -15718,12 +15718,11 @@ GenTree* Compiler::gtNewTempAssign( if (varTypeIsStruct(varDsc) && (valStructHnd == NO_CLASS_HANDLE) && !varTypeIsSIMD(valTyp)) { // There are some cases where we do not have a struct handle on the return value: - // 1. Handle-less IND/BLK/LCL_FLD nodes. + // 1. Handle-less BLK/LCL_FLD nodes. // 2. The zero constant created by local assertion propagation. - // In these cases, we can use the type of the merge return for the assignment. + // In these cases, we can use the type of the local for the assignment. assert(val->gtEffectiveVal(true)->OperIs(GT_IND, GT_BLK, GT_LCL_FLD, GT_CNS_INT)); - assert(tmp == genReturnLocal); - valStructHnd = lvaGetStruct(genReturnLocal); + valStructHnd = lvaGetDesc(tmp)->GetStructHnd(); assert(valStructHnd != NO_CLASS_HANDLE); } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 7ba7c6f96fb90..41bb882eb8e41 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -3774,20 +3774,12 @@ void Lowering::LowerRetStruct(GenTreeUnOp* ret) { // Spill to a local if sizes don't match so we can avoid the "load more than requested" // problem, e.g. struct size is 5 and we emit "ldr x0, [x1]" - unsigned realSize = retVal->AsIndir()->Size(); - CORINFO_CLASS_HANDLE structCls = comp->info.compMethodInfo->args.retTypeClass; - if (realSize == 0) - { - // TODO-ADDR: delete once "IND" nodes are no more - realSize = comp->info.compCompHnd->getClassSize(structCls); - } - - if (genTypeSize(nativeReturnType) > realSize) + if (genTypeSize(nativeReturnType) > retVal->AsIndir()->Size()) { LIR::Use retValUse(BlockRange(), &ret->gtOp1, ret); unsigned tmpNum = comp->lvaGrabTemp(true DEBUGARG("mis-sized struct return")); - comp->lvaSetStruct(tmpNum, structCls, false); - comp->genReturnLocal = tmpNum; + comp->lvaSetStruct(tmpNum, comp->info.compMethodInfo->args.retTypeClass, false); + ReplaceWithLclVar(retValUse, tmpNum); LowerRetSingleRegStructLclVar(ret); break; diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp index 4bcfbf058ecf0..6124f533a1f59 100644 --- a/src/coreclr/jit/morphblock.cpp +++ b/src/coreclr/jit/morphblock.cpp @@ -753,21 +753,10 @@ void MorphCopyBlockHelper::PrepareSrc() m_srcVarDsc = m_comp->lvaGetDesc(m_srcLclNum); } - // Verify that the types on the LHS and RHS match and morph away "IND" nodes. + // Verify that the types on the LHS and RHS match. assert(m_dst->TypeGet() == m_src->TypeGet()); if (m_dst->TypeIs(TYP_STRUCT)) { - // TODO-1stClassStructs: delete this once "IND" nodes are no more. - if (m_src->OperIs(GT_IND)) - { - m_src->SetOper(m_blockLayout->IsBlockLayout() ? GT_BLK : GT_OBJ); - m_src->AsBlk()->SetLayout(m_blockLayout); - m_src->AsBlk()->gtBlkOpKind = GenTreeBlk::BlkOpKindInvalid; -#ifndef JIT32_GCENCODER - m_src->AsBlk()->gtBlkOpGcUnsafe = false; -#endif // !JIT32_GCENCODER - } - assert(ClassLayout::AreCompatible(m_blockLayout, m_src->GetLayout(m_comp))); } // TODO-1stClassStructs: produce simple "IND" nodes in importer. From 3904c8d2235263ed5e4f01e499ded5bd0d3f6427 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Wed, 30 Nov 2022 14:19:00 +0300 Subject: [PATCH 05/10] Delete "ADDR(FIELD)" wrapping for struct args --- src/coreclr/jit/importer.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 4a3b20eb855ad..1c9be70be7c5f 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1354,15 +1354,6 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str makeTemp = true; break; - case GT_FIELD: - // Wrap it in a GT_OBJ, if needed. - structVal->gtType = structType; - if (structType == TYP_STRUCT) - { - structVal = gtNewObjNode(structHnd, gtNewOperNode(GT_ADDR, TYP_BYREF, structVal)); - } - break; - case GT_LCL_VAR: case GT_LCL_FLD: structLcl = structVal->AsLclVarCommon(); @@ -1370,19 +1361,15 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str structVal = gtNewObjNode(structHnd, gtNewOperNode(GT_ADDR, TYP_BYREF, structVal)); FALLTHROUGH; + case GT_IND: case GT_OBJ: case GT_BLK: + case GT_FIELD: // These should already have the appropriate type. assert(structVal->gtType == structType); alreadyNormalized = true; break; - case GT_IND: - assert(structVal->gtType == structType); - structVal = gtNewObjNode(structHnd, structVal->gtGetOp1()); - alreadyNormalized = true; - break; - case GT_CNS_VEC: assert(varTypeIsSIMD(structVal) && (structVal->gtType == structType)); break; From 3c8d497bd3ba2a47d524e7b97f6cb341c6ebb311 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Wed, 30 Nov 2022 16:28:52 +0300 Subject: [PATCH 06/10] Fix refanytype import --- src/coreclr/jit/importer.cpp | 52 ++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 1c9be70be7c5f..fd094c11eb29b 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1362,6 +1362,7 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str FALLTHROUGH; case GT_IND: + case GT_OBJ: case GT_BLK: case GT_FIELD: @@ -10092,26 +10093,11 @@ void Compiler::impImportBlockCode(BasicBlock* block) break; } case CEE_REFANYTYPE: - + { op1 = impPopStack().val; - // make certain it is normalized; - op1 = impNormStructVal(op1, impGetRefAnyClass(), CHECK_SPILL_ALL); - - if (op1->gtOper == GT_OBJ) - { - // Get the address of the refany - op1 = op1->AsOp()->gtOp1; - - // Fetch the type from the correct slot - op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, - gtNewIconNode(OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL)); - op1 = gtNewOperNode(GT_IND, TYP_BYREF, op1); - } - else + if (op1->OperIs(GT_MKREFANY)) { - assertImp(op1->gtOper == GT_MKREFANY); - // The pointer may have side-effects if (op1->AsOp()->gtOp1->gtFlags & GTF_SIDE_EFFECT) { @@ -10124,25 +10110,33 @@ void Compiler::impImportBlockCode(BasicBlock* block) // We already have the class handle op1 = op1->AsOp()->gtOp2; } - - // convert native TypeHandle to RuntimeTypeHandle + else { - op1 = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, TYP_STRUCT, op1); + // Get the address of the refany + op1 = impGetStructAddr(op1, impGetRefAnyClass(), CHECK_SPILL_ALL, /* willDeref */ true); + + // Fetch the type from the correct slot + op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1, + gtNewIconNode(OFFSETOF__CORINFO_TypedReference__type, TYP_I_IMPL)); + op1 = gtNewOperNode(GT_IND, TYP_BYREF, op1); + } + + // Convert native TypeHandle to RuntimeTypeHandle. + op1 = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, TYP_STRUCT, op1); - CORINFO_CLASS_HANDLE classHandle = impGetTypeHandleClass(); + CORINFO_CLASS_HANDLE classHandle = impGetTypeHandleClass(); - // The handle struct is returned in register - op1->AsCall()->gtReturnType = GetRuntimeHandleUnderlyingType(); - op1->AsCall()->gtRetClsHnd = classHandle; + // The handle struct is returned in register + op1->AsCall()->gtReturnType = GetRuntimeHandleUnderlyingType(); + op1->AsCall()->gtRetClsHnd = classHandle; #if FEATURE_MULTIREG_RET - op1->AsCall()->InitializeStructReturnType(this, classHandle, op1->AsCall()->GetUnmanagedCallConv()); + op1->AsCall()->InitializeStructReturnType(this, classHandle, op1->AsCall()->GetUnmanagedCallConv()); #endif - tiRetVal = typeInfo(TI_STRUCT, classHandle); - } - + tiRetVal = typeInfo(TI_STRUCT, classHandle); impPushOnStack(op1, tiRetVal); - break; + } + break; case CEE_LDTOKEN: { From 7bf4a76708bc61de29561bdec29aaa69d0f2d53c Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Wed, 30 Nov 2022 22:18:16 +0300 Subject: [PATCH 07/10] Fix fwd sub --- src/coreclr/jit/forwardsub.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/forwardsub.cpp b/src/coreclr/jit/forwardsub.cpp index d498c2291ca10..1cc2791f4696a 100644 --- a/src/coreclr/jit/forwardsub.cpp +++ b/src/coreclr/jit/forwardsub.cpp @@ -632,10 +632,10 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) // Quirks: // - // Don't substitute nodes "AddFinalArgsAndDetermineABIInfo" doesn't handle into struct args. + // Don't substitute nodes args morphing doesn't handle into struct args. // if (fsv.IsCallArg() && fsv.GetNode()->TypeIs(TYP_STRUCT) && - !fwdSubNode->OperIs(GT_OBJ, GT_LCL_VAR, GT_LCL_FLD, GT_MKREFANY)) + !fwdSubNode->OperIs(GT_OBJ, GT_FIELD, GT_LCL_VAR, GT_LCL_FLD, GT_MKREFANY)) { JITDUMP(" use is a struct arg; fwd sub node is not OBJ/LCL_VAR/LCL_FLD/MKREFANY\n"); return false; From 8a6f6bf712ed5b83c8d9c8fb98aee68d6e0ecd55 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Wed, 30 Nov 2022 22:34:46 +0300 Subject: [PATCH 08/10] Fix non-null prop --- src/coreclr/jit/assertionprop.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index db8e0f976ac05..1e45bed9a215c 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -4692,6 +4692,8 @@ bool Compiler::optAssertionIsNonNull(GenTree* op, return true; } + op = op->gtEffectiveVal(/* commaOnly */ true); + if (!op->OperIs(GT_LCL_VAR)) { return false; From a00a3f7883fb9d4b267a512c50b0f4c16edf7411 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Thu, 1 Dec 2022 20:49:22 +0300 Subject: [PATCH 09/10] Simplify impAssignStruct --- src/coreclr/jit/importer.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index fd094c11eb29b..e99d26d428a21 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -934,18 +934,11 @@ GenTree* Compiler::impAssignStruct(GenTree* dest, assert(varTypeIsStruct(dest) && (dest->OperIsLocal() || dest->OperIsIndir() || dest->OperIs(GT_FIELD))); assert(dest->TypeGet() == src->TypeGet()); - // TODO-1stClassStructs: delete the "!IND" condition once "IND" nodes are no more. - if (dest->TypeIs(TYP_STRUCT) && !src->gtEffectiveVal()->OperIs(GT_IND)) + if (dest->TypeIs(TYP_STRUCT)) { assert(ClassLayout::AreCompatible(dest->GetLayout(this), src->GetLayout(this))); } - if (dest->OperIs(GT_FIELD) && dest->TypeIs(TYP_STRUCT)) - { - // TODO-ADDR: delete this once FIELD nodes are transformed into OBJs (not INDs). - dest = gtNewObjNode(dest->GetLayout(this), gtNewOperNode(GT_ADDR, TYP_BYREF, dest)); - } - DebugInfo usedDI = di; if (!usedDI.IsValid()) { From 868b528bd939e4adbb82731f644f9beda7f388c0 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Sat, 10 Dec 2022 17:29:20 +0300 Subject: [PATCH 10/10] Simplify "impNormStructVal" more --- src/coreclr/jit/importer.cpp | 61 ++++++++++-------------------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e99d26d428a21..f9822f476c54c 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1331,17 +1331,10 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str { structType = impNormStructType(structHnd); } - bool alreadyNormalized = false; - GenTreeLclVarCommon* structLcl = nullptr; + GenTreeLclVarCommon* structLcl = nullptr; - genTreeOps oper = structVal->OperGet(); - switch (oper) + switch (structVal->OperGet()) { - // GT_MKREFANY is supported directly by args morphing. - case GT_MKREFANY: - alreadyNormalized = true; - break; - case GT_CALL: case GT_RET_EXPR: makeTemp = true; @@ -1355,31 +1348,20 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str FALLTHROUGH; case GT_IND: - case GT_OBJ: case GT_BLK: case GT_FIELD: - // These should already have the appropriate type. - assert(structVal->gtType == structType); - alreadyNormalized = true; - break; - case GT_CNS_VEC: - assert(varTypeIsSIMD(structVal) && (structVal->gtType == structType)); - break; - #ifdef FEATURE_SIMD case GT_SIMD: - assert(varTypeIsSIMD(structVal) && (structVal->gtType == structType)); - break; -#endif // FEATURE_SIMD +#endif #ifdef FEATURE_HW_INTRINSICS case GT_HWINTRINSIC: - assert(structVal->gtType == structType); - assert(varTypeIsSIMD(structVal) || - HWIntrinsicInfo::IsMultiReg(structVal->AsHWIntrinsic()->GetHWIntrinsicId())); - break; #endif + case GT_MKREFANY: + // These should already have the appropriate type. + assert(structVal->TypeGet() == structType); + break; case GT_COMMA: { @@ -1400,22 +1382,15 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str } while (blockNode->OperGet() == GT_COMMA); } - if (blockNode->OperGet() == GT_FIELD) - { - // If we have a GT_FIELD then wrap it in a GT_OBJ. - blockNode = gtNewObjNode(structHnd, gtNewOperNode(GT_ADDR, TYP_BYREF, blockNode)); - } - #ifdef FEATURE_SIMD if (blockNode->OperIsSimdOrHWintrinsic() || blockNode->IsCnsVec()) { parent->AsOp()->gtOp2 = impNormStructVal(blockNode, structHnd, curLevel); - alreadyNormalized = true; } else #endif { - noway_assert(blockNode->OperIsBlk()); + noway_assert(blockNode->OperIsBlk() || blockNode->OperIs(GT_FIELD)); // Sink the GT_COMMA below the blockNode addr. // That is GT_COMMA(op1, op2=blockNode) is transformed into @@ -1433,7 +1408,6 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str { structVal = blockNode; } - alreadyNormalized = true; } } break; @@ -1442,22 +1416,19 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, CORINFO_CLASS_HANDLE str noway_assert(!"Unexpected node in impNormStructVal()"); break; } - structVal->gtType = structType; - if (!alreadyNormalized) + if (makeTemp) { - if (makeTemp) - { - unsigned tmpNum = lvaGrabTemp(true DEBUGARG("struct address for call/obj")); + unsigned tmpNum = lvaGrabTemp(true DEBUGARG("struct address for call/obj")); - impAssignTempGen(tmpNum, structVal, structHnd, curLevel); + impAssignTempGen(tmpNum, structVal, structHnd, curLevel); - // The structVal is now the temp itself + // The structVal is now the temp itself - structLcl = gtNewLclvNode(tmpNum, structType)->AsLclVarCommon(); - structVal = structLcl; - } - if ((structType == TYP_STRUCT) && !structVal->OperIsBlk()) + structLcl = gtNewLclvNode(tmpNum, structType)->AsLclVarCommon(); + structVal = structLcl; + + if (structType == TYP_STRUCT) { // Wrap it in a GT_OBJ structVal = gtNewObjNode(structHnd, gtNewOperNode(GT_ADDR, TYP_BYREF, structVal));