diff options
author | Brian Sullivan <briansul@microsoft.com> | 2017-10-20 15:11:31 -0700 |
---|---|---|
committer | Brian Sullivan <briansul@microsoft.com> | 2017-10-25 14:13:35 -0700 |
commit | d8d54a7e705038eff3089bd1b7bb70d18bc371de (patch) | |
tree | f38ebb523f24dfe38976faef368ccd8501efa5a3 /src | |
parent | ea3f140da0e9e3bf6ee1f1c9d88a231cf3875a82 (diff) | |
download | coreclr-d8d54a7e705038eff3089bd1b7bb70d18bc371de.tar.gz coreclr-d8d54a7e705038eff3089bd1b7bb70d18bc371de.tar.bz2 coreclr-d8d54a7e705038eff3089bd1b7bb70d18bc371de.zip |
Added gtNewIndOfIconHandleNode
Renamed GTF_ICON_CIDMID_HDL to GTF_ICON_MID_HDL
Added a standard function header comment for gtNewIndOfIconHandleNode
Made compiletimeHandle a required argument instead of an option argument for gtNewIconEmbHndNode
Added new isInvariant arg to gtNewIndOfIconHandleNode, it will set GTF_IND_INVARIANT when true
Converted IBC Block Counts to use new gtNewIndOfIconHandleNode method
Simplified gtNewStringLiteralNode
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/compiler.cpp | 6 | ||||
-rw-r--r-- | src/jit/compiler.h | 5 | ||||
-rw-r--r-- | src/jit/ee_il_dll.cpp | 2 | ||||
-rw-r--r-- | src/jit/flowgraph.cpp | 73 | ||||
-rw-r--r-- | src/jit/gentree.cpp | 118 | ||||
-rw-r--r-- | src/jit/gentree.h | 2 | ||||
-rw-r--r-- | src/jit/importer.cpp | 22 | ||||
-rw-r--r-- | src/jit/morph.cpp | 21 |
8 files changed, 158 insertions, 91 deletions
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index 5c20a87e5f..159048cc0c 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -9686,9 +9686,9 @@ int cTreeFlagsIR(Compiler* comp, GenTree* tree) chars += printf("[ICON_FTN_ADDR]"); break; - case GTF_ICON_CIDMID_HDL: + case GTF_ICON_MID_HDL: - chars += printf("[ICON_CIDMID_HDL]"); + chars += printf("[ICON_MID_HDL]"); break; case GTF_ICON_BBC_PTR: @@ -10417,7 +10417,7 @@ int cLeafIR(Compiler* comp, GenTree* tree) chars += printf("FTN(?)"); break; - case GTF_ICON_CIDMID_HDL: + case GTF_ICON_MID_HDL: chars += printf("CIDMID(?)"); break; diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 6a64a7b648..29ee256877 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -2008,11 +2008,14 @@ public: GenTree* gtNewPhysRegNode(regNumber reg, var_types type); GenTreePtr gtNewJmpTableNode(); + + GenTreePtr gtNewIndOfIconHandleNode(var_types indType, size_t value, unsigned iconFlags, bool isInvariant); + GenTreePtr gtNewIconHandleNode(size_t value, unsigned flags, FieldSeqNode* fields = nullptr); unsigned gtTokenToIconFlags(unsigned token); - GenTreePtr gtNewIconEmbHndNode(void* value, void* pValue, unsigned flags, void* compileTimeHandle = nullptr); + GenTreePtr gtNewIconEmbHndNode(void* value, void* pValue, unsigned flags, void* compileTimeHandle); GenTreePtr gtNewIconEmbScpHndNode(CORINFO_MODULE_HANDLE scpHnd); GenTreePtr gtNewIconEmbClsHndNode(CORINFO_CLASS_HANDLE clsHnd); diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp index 73e6cd6459..4e65d24b30 100644 --- a/src/jit/ee_il_dll.cpp +++ b/src/jit/ee_il_dll.cpp @@ -506,7 +506,7 @@ GenTreePtr Compiler::eeGetPInvokeCookie(CORINFO_SIG_INFO* szMetaSig) cookie = info.compCompHnd->GetCookieForPInvokeCalliSig(szMetaSig, &pCookie); assert((cookie == nullptr) != (pCookie == nullptr)); - return gtNewIconEmbHndNode(cookie, pCookie, GTF_ICON_PINVKI_HDL); + return gtNewIconEmbHndNode(cookie, pCookie, GTF_ICON_PINVKI_HDL, szMetaSig); } //------------------------------------------------------------------------ diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index 18ef525fd3..a11f26ed61 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -309,21 +309,22 @@ void Compiler::fgInstrumentMethod() continue; } + // Assign the current block's IL offset into the profile data bbProfileBuffer->ILOffset = block->bbCodeOffs; - GenTreePtr addr; - GenTreePtr value; + size_t addrOfBlockCount = (size_t)&bbProfileBuffer->ExecutionCount; - value = gtNewOperNode(GT_IND, TYP_INT, gtNewIconEmbHndNode((void*)&bbProfileBuffer->ExecutionCount, nullptr, - GTF_ICON_BBC_PTR)); - value = gtNewOperNode(GT_ADD, TYP_INT, value, gtNewIconNode(1)); + // Read Basic-Block count value + GenTree* valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfBlockCount, GTF_ICON_BBC_PTR, false); - addr = gtNewOperNode(GT_IND, TYP_INT, gtNewIconEmbHndNode((void*)&bbProfileBuffer->ExecutionCount, nullptr, - GTF_ICON_BBC_PTR)); + // Increment value by 1 + GenTree* rhsNode = gtNewOperNode(GT_ADD, TYP_INT, valueNode, gtNewIconNode(1)); - addr = gtNewAssignNode(addr, value); + // Write new Basic-Block count value + GenTree* lhsNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfBlockCount, GTF_ICON_BBC_PTR, false); + GenTree* asgNode = gtNewAssignNode(lhsNode, rhsNode); - fgInsertStmtAtBeg(block, addr); + fgInsertStmtAtBeg(block, asgNode); countOfBlocks--; bbProfileBuffer++; @@ -358,10 +359,13 @@ void Compiler::fgInstrumentMethod() GenTreeArgList* args = gtNewArgList(arg); GenTreePtr call = gtNewHelperCallNode(CORINFO_HELP_BBT_FCN_ENTER, TYP_VOID, args); - GenTreePtr handle = - gtNewIconEmbHndNode((void*)&bbProfileBufferStart->ExecutionCount, nullptr, GTF_ICON_BBC_PTR); - GenTreePtr value = gtNewOperNode(GT_IND, TYP_INT, handle); - GenTreePtr relop = gtNewOperNode(GT_NE, TYP_INT, value, gtNewIconNode(0, TYP_INT)); + size_t addrOfBlockCount = (size_t)&bbProfileBuffer->ExecutionCount; + + // Read Basic-Block count value + GenTreePtr valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfBlockCount, GTF_ICON_BBC_PTR, false); + + // Compare Basic-Block count value against zero + GenTreePtr relop = gtNewOperNode(GT_NE, TYP_INT, valueNode, gtNewIconNode(0, TYP_INT)); relop->gtFlags |= GTF_RELOP_QMARK; // TODO-Cleanup: [Simple] Move this to gtNewQmarkNode GenTreePtr colon = new (this, GT_COLON) GenTreeColon(TYP_VOID, gtNewNothingNode(), call); GenTreePtr cond = gtNewQmarkNode(TYP_VOID, relop, colon); @@ -3984,23 +3988,30 @@ bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block) noway_assert(pAddrOfCaptureThreadGlobal == nullptr); #endif - GenTreePtr trap; + GenTreePtr value; // The value of g_TrapReturningThreads if (pAddrOfCaptureThreadGlobal != nullptr) { - trap = gtNewOperNode(GT_IND, TYP_I_IMPL, - gtNewIconHandleNode((size_t)pAddrOfCaptureThreadGlobal, GTF_ICON_PTR_HDL)); + // Use a double indirection + GenTreePtr addr = + gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pAddrOfCaptureThreadGlobal, GTF_ICON_PTR_HDL, true); + + value = gtNewOperNode(GT_IND, TYP_INT, addr); + // This indirection won't cause an exception. + value->gtFlags |= GTF_IND_NONFAULTING; } else { - trap = gtNewIconHandleNode((size_t)addrTrap, GTF_ICON_PTR_HDL); + // Use a single indirection + value = gtNewIndOfIconHandleNode(TYP_INT, (size_t)addrTrap, GTF_ICON_PTR_HDL, false); } - GenTreePtr trapRelop = gtNewOperNode(GT_EQ, TYP_INT, - // lhs [g_TrapReturningThreads] - gtNewOperNode(GT_IND, TYP_INT, trap), - // rhs 0 - gtNewIconNode(0, TYP_INT)); - trapRelop->gtFlags |= GTF_RELOP_JMP_USED | GTF_DONT_CSE; // Treat reading g_TrapReturningThreads as volatile. + // Treat the reading of g_TrapReturningThreads as volatile. + value->gtFlags |= GTF_IND_VOLATILE; + + // Compare for equal to zero + GenTreePtr trapRelop = gtNewOperNode(GT_EQ, TYP_INT, value, gtNewIconNode(0, TYP_INT)); + + trapRelop->gtFlags |= GTF_RELOP_JMP_USED | GTF_DONT_CSE; GenTreePtr trapCheck = gtNewOperNode(GT_JTRUE, TYP_VOID, trapRelop); fgInsertStmtAtEnd(top, trapCheck); top->bbJumpDest = bottom; @@ -7023,8 +7034,8 @@ GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfo if (pmoduleID) { - opModuleIDArg = gtNewIconHandleNode((size_t)pmoduleID, GTF_ICON_CIDMID_HDL); - opModuleIDArg = gtNewOperNode(GT_IND, TYP_I_IMPL, opModuleIDArg); + opModuleIDArg = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pmoduleID, GTF_ICON_MID_HDL, true); + // This indirection also is invariant. opModuleIDArg->gtFlags |= GTF_IND_INVARIANT; } else @@ -7036,9 +7047,7 @@ GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfo { if (pclsID) { - opClassIDArg = gtNewIconHandleNode((size_t)pclsID, GTF_ICON_CIDMID_HDL); - opClassIDArg = gtNewOperNode(GT_IND, TYP_INT, opClassIDArg); - opClassIDArg->gtFlags |= GTF_IND_INVARIANT; + opClassIDArg = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pclsID, GTF_ICON_CLASS_HDL, true); } else { @@ -7651,7 +7660,7 @@ GenTreePtr Compiler::fgGetCritSectOfStaticMethod() critSect = info.compCompHnd->getMethodSync(info.compMethodHnd, (void**)&pCrit); noway_assert((!critSect) != (!pCrit)); - tree = gtNewIconEmbHndNode(critSect, pCrit, GTF_ICON_METHOD_HDL); + tree = gtNewIconEmbHndNode(critSect, pCrit, GTF_ICON_METHOD_HDL, info.compMethodHnd); } else { @@ -8889,9 +8898,9 @@ void Compiler::fgAddInternal() if (dbgHandle || pDbgHandle) { - GenTreePtr guardCheckVal = - gtNewOperNode(GT_IND, TYP_INT, gtNewIconEmbHndNode(dbgHandle, pDbgHandle, GTF_ICON_TOKEN_HDL)); - GenTreePtr guardCheckCond = gtNewOperNode(GT_EQ, TYP_INT, guardCheckVal, gtNewZeroConNode(TYP_INT)); + GenTree* embNode = gtNewIconEmbHndNode(dbgHandle, pDbgHandle, GTF_ICON_TOKEN_HDL, info.compMethodHnd); + GenTree* guardCheckVal = gtNewOperNode(GT_IND, TYP_INT, embNode); + GenTree* guardCheckCond = gtNewOperNode(GT_EQ, TYP_INT, guardCheckVal, gtNewZeroConNode(TYP_INT)); guardCheckCond->gtFlags |= GTF_RELOP_QMARK; // Create the callback which will yield the final answer diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index 4cd4221bdd..455c7e1f8c 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -6126,6 +6126,50 @@ unsigned Compiler::gtTokenToIconFlags(unsigned token) return flags; } +//----------------------------------------------------------------------------------------- +// gtNewIndOfIconHandleNode: Creates an indirection GenTree node of a constant handle +// +// Arguments: +// indType - The type returned by the indirection node +// addr - The constant address to read from +// iconFlags - The GTF_ICON flag value that specifies the kind of handle that we have +// isInvariant - The indNode should also be marked as invariant +// +// Return Value: +// Returns a GT_IND node representing value at the address provided by 'value' +// +// Notes: +// The GT_IND node is marked as non-faulting +// If the indType is GT_REF we also mark the indNode as GTF_GLOB_REF +// + +GenTreePtr Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, unsigned iconFlags, bool isInvariant) +{ + GenTreePtr addrNode = gtNewIconHandleNode(addr, iconFlags); + GenTreePtr indNode = gtNewOperNode(GT_IND, indType, addrNode); + + // This indirection won't cause an exception. + // + indNode->gtFlags |= GTF_IND_NONFAULTING; + + // String Literal handles are indirections that return a TYP_REF. + // They are pointers into the GC heap and they are not invariant + // as the address is a reportable GC-root and as such it can be + // modified during a GC collection + // + if (indType == TYP_REF) + { + // This indirection points into the gloabal heap + indNode->gtFlags |= GTF_GLOB_REF; + } + if (isInvariant) + { + // This indirection also is invariant. + indNode->gtFlags |= GTF_IND_INVARIANT; + } + return indNode; +} + /***************************************************************************** * * Allocates a integer constant entry that represents a HANDLE to something. @@ -6134,29 +6178,44 @@ unsigned Compiler::gtTokenToIconFlags(unsigned token) * If the handle needs to be accessed via an indirection, pValue points to it. */ -GenTreePtr Compiler::gtNewIconEmbHndNode(void* value, void* pValue, unsigned flags, void* compileTimeHandle) +GenTreePtr Compiler::gtNewIconEmbHndNode(void* value, void* pValue, unsigned iconFlags, void* compileTimeHandle) { - GenTreePtr node; + GenTreePtr iconNode; + GenTreePtr handleNode; - assert((!value) != (!pValue)); - - if (value) + if (value != nullptr) { - node = gtNewIconHandleNode((size_t)value, flags, /*fieldSeq*/ FieldSeqStore::NotAField()); - node->gtIntCon.gtCompileTimeHandle = (size_t)compileTimeHandle; + // When 'value' is non-null, pValue is required to be null + assert(pValue == nullptr); + + // use 'value' to construct an integer constant node + iconNode = gtNewIconHandleNode((size_t)value, iconFlags); + + // 'value' is the handle + handleNode = iconNode; } else { - node = gtNewIconHandleNode((size_t)pValue, flags, /*fieldSeq*/ FieldSeqStore::NotAField()); - node->gtIntCon.gtCompileTimeHandle = (size_t)compileTimeHandle; - node = gtNewOperNode(GT_IND, TYP_I_IMPL, node); + // When 'value' is null, pValue is required to be non-null + assert(pValue != nullptr); + + // use 'pValue' to construct an integer constant node + iconNode = gtNewIconHandleNode((size_t)pValue, iconFlags); + + // 'pValue' is an address of a location that contains the handle + + // construct the indirection of 'pValue' + handleNode = gtNewOperNode(GT_IND, TYP_I_IMPL, iconNode); - // This indirection won't cause an exception. It should also - // be invariant, but marking it as such leads to bad diffs. - node->gtFlags |= GTF_IND_NONFAULTING; + // This indirection won't cause an exception. + handleNode->gtFlags |= GTF_IND_NONFAULTING; + // This indirection also is invariant. + handleNode->gtFlags |= GTF_IND_INVARIANT; } - return node; + iconNode->gtIntCon.gtCompileTimeHandle = (size_t)compileTimeHandle; + + return handleNode; } /*****************************************************************************/ @@ -6166,30 +6225,25 @@ GenTreePtr Compiler::gtNewStringLiteralNode(InfoAccessType iat, void* pValue) switch (iat) { - case IAT_VALUE: // The info value is directly available - tree = gtNewIconEmbHndNode(pValue, nullptr, GTF_ICON_STR_HDL); - tree->gtType = TYP_REF; - tree = gtNewOperNode(GT_NOP, TYP_REF, tree); // prevents constant folding - break; - - case IAT_PVALUE: // The value needs to be accessed via an indirection - tree = gtNewIconHandleNode((size_t)pValue, GTF_ICON_STR_HDL); - // An indirection of a string handle can't cause an exception so don't set GTF_EXCEPT - tree = gtNewOperNode(GT_IND, TYP_REF, tree); - tree->gtFlags |= GTF_GLOB_REF; + case IAT_PVALUE: // The value needs to be accessed via an indirection + // Create an indirection + tree = gtNewIndOfIconHandleNode(TYP_REF, (size_t)pValue, GTF_ICON_STR_HDL, true); break; case IAT_PPVALUE: // The value needs to be accessed via a double indirection - tree = gtNewIconHandleNode((size_t)pValue, GTF_ICON_PSTR_HDL); - tree = gtNewOperNode(GT_IND, TYP_I_IMPL, tree); - tree->gtFlags |= GTF_IND_INVARIANT; - // An indirection of a string handle can't cause an exception so don't set GTF_EXCEPT + // Create the first indirection + tree = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pValue, GTF_ICON_PSTR_HDL, true); + + // Create the second indirection tree = gtNewOperNode(GT_IND, TYP_REF, tree); + // This indirection won't cause an exception. + tree->gtFlags |= GTF_IND_NONFAULTING; + // This indirection points into the gloabal heap (it is String Object) tree->gtFlags |= GTF_GLOB_REF; break; default: - assert(!"Unexpected InfoAccessType"); + noway_assert(!"Unexpected InfoAccessType"); } return tree; @@ -10609,8 +10663,8 @@ void Compiler::gtDispConst(GenTree* tree) case GTF_ICON_FTN_ADDR: printf(" ftn"); break; - case GTF_ICON_CIDMID_HDL: - printf(" cid"); + case GTF_ICON_MID_HDL: + printf(" module"); break; case GTF_ICON_BBC_PTR: printf(" bbc"); diff --git a/src/jit/gentree.h b/src/jit/gentree.h index 4c194a45a9..ccd0146f79 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -1017,7 +1017,7 @@ public: #define GTF_ICON_TOKEN_HDL 0xB0000000 // GT_CNS_INT -- constant is a token handle #define GTF_ICON_TLS_HDL 0xC0000000 // GT_CNS_INT -- constant is a TLS ref with offset #define GTF_ICON_FTN_ADDR 0xD0000000 // GT_CNS_INT -- constant is a function address -#define GTF_ICON_CIDMID_HDL 0xE0000000 // GT_CNS_INT -- constant is a class or module ID handle +#define GTF_ICON_MID_HDL 0xE0000000 // GT_CNS_INT -- constant is a module ID handle #define GTF_ICON_BBC_PTR 0xF0000000 // GT_CNS_INT -- constant is a basic block count pointer #define GTF_ICON_FIELD_OFF 0x08000000 // GT_CNS_INT -- constant is a field offset diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 58273691de..730f79e221 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -1956,9 +1956,9 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok gtNewArgList(ctxTree), &pLookup->lookupKind); } #endif - - GenTreeArgList* helperArgs = gtNewArgList(ctxTree, gtNewIconEmbHndNode(pRuntimeLookup->signature, nullptr, - GTF_ICON_TOKEN_HDL, compileTimeHandle)); + GenTree* argNode = + gtNewIconEmbHndNode(pRuntimeLookup->signature, nullptr, GTF_ICON_TOKEN_HDL, compileTimeHandle); + GenTreeArgList* helperArgs = gtNewArgList(ctxTree, argNode); return gtNewHelperCallNode(pRuntimeLookup->helper, TYP_I_IMPL, helperArgs); } @@ -2059,9 +2059,10 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok nullptr DEBUGARG("impRuntimeLookup typehandle")); // Call to helper - GenTreeArgList* helperArgs = gtNewArgList(ctxTree, gtNewIconEmbHndNode(pRuntimeLookup->signature, nullptr, - GTF_ICON_TOKEN_HDL, compileTimeHandle)); - GenTreePtr helperCall = gtNewHelperCallNode(pRuntimeLookup->helper, TYP_I_IMPL, helperArgs); + GenTree* argNode = gtNewIconEmbHndNode(pRuntimeLookup->signature, nullptr, GTF_ICON_TOKEN_HDL, compileTimeHandle); + + GenTreeArgList* helperArgs = gtNewArgList(ctxTree, argNode); + GenTreePtr helperCall = gtNewHelperCallNode(pRuntimeLookup->helper, TYP_I_IMPL, helperArgs); // Check for null and possibly call helper GenTreePtr relop = gtNewOperNode(GT_NE, TYP_INT, handle, gtNewIconNode(0, TYP_I_IMPL)); @@ -3266,10 +3267,9 @@ GenTreePtr Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig) dataOffset = eeGetArrayDataOffset(elementType); } - GenTreePtr dst = gtNewOperNode(GT_ADD, TYP_BYREF, arrayLocalNode, gtNewIconNode(dataOffset, TYP_I_IMPL)); - GenTreePtr blk = gtNewBlockVal(dst, blkSize); - GenTreePtr srcAddr = gtNewIconHandleNode((size_t)initData, GTF_ICON_STATIC_HDL); - GenTreePtr src = gtNewOperNode(GT_IND, TYP_STRUCT, srcAddr); + GenTreePtr dst = gtNewOperNode(GT_ADD, TYP_BYREF, arrayLocalNode, gtNewIconNode(dataOffset, TYP_I_IMPL)); + GenTreePtr blk = gtNewBlockVal(dst, blkSize); + GenTreePtr src = gtNewIndOfIconHandleNode(TYP_STRUCT, (size_t)initData, GTF_ICON_STATIC_HDL, true); return gtNewBlkOpNode(blk, // dst src, // src @@ -7686,7 +7686,7 @@ var_types Compiler::impImportCall(OPCODE opcode, varCookie = info.compCompHnd->getVarArgsHandle(sig, &pVarCookie); assert((!varCookie) != (!pVarCookie)); - GenTreePtr cookie = gtNewIconEmbHndNode(varCookie, pVarCookie, GTF_ICON_VARG_HDL); + GenTreePtr cookie = gtNewIconEmbHndNode(varCookie, pVarCookie, GTF_ICON_VARG_HDL, sig); assert(extraArg == nullptr); extraArg = gtNewArgList(cookie); diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 73e07ff422..a65b7504ca 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -6669,15 +6669,19 @@ GenTreePtr Compiler::fgMorphField(GenTreePtr tree, MorphAddrContext* mac) #ifdef FEATURE_READYTORUN_COMPILER if (tree->gtField.gtFieldLookup.addr != nullptr) { - GenTreePtr baseOffset = gtNewIconEmbHndNode(tree->gtField.gtFieldLookup.addr, nullptr, GTF_ICON_FIELD_HDL); - + GenTree* offsetNode = nullptr; if (tree->gtField.gtFieldLookup.accessType == IAT_PVALUE) { - baseOffset = gtNewOperNode(GT_IND, TYP_I_IMPL, baseOffset); + offsetNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)tree->gtField.gtFieldLookup.addr, + GTF_ICON_FIELD_HDL, true); + } + else + { + noway_assert(!"unexpected accessType for R2R field access"); } - addr = - gtNewOperNode(GT_ADD, (var_types)(objRefType == TYP_I_IMPL ? TYP_I_IMPL : TYP_BYREF), addr, baseOffset); + var_types addType = (objRefType == TYP_I_IMPL) ? TYP_I_IMPL : TYP_BYREF; + addr = gtNewOperNode(GT_ADD, addType, addr, offsetNode); } #endif if (fldOffset != 0) @@ -6769,12 +6773,9 @@ GenTreePtr Compiler::fgMorphField(GenTreePtr tree, MorphAddrContext* mac) } else { - dllRef = gtNewIconHandleNode((size_t)pIdAddr, GTF_ICON_STATIC_HDL); - dllRef = gtNewOperNode(GT_IND, TYP_I_IMPL, dllRef); - dllRef->gtFlags |= GTF_IND_INVARIANT; - - /* Multiply by 4 */ + dllRef = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pIdAddr, GTF_ICON_STATIC_HDL, true); + // Next we multiply by 4 dllRef = gtNewOperNode(GT_MUL, TYP_I_IMPL, dllRef, gtNewIconNode(4, TYP_I_IMPL)); } |