Skip to content

Commit

Permalink
Merge pull request dotnet#14640 from briansull/ind-icon
Browse files Browse the repository at this point in the history
Added gtNewIndOfIconHandleNode
  • Loading branch information
briansull authored Oct 27, 2017
2 parents 5bd7c82 + 9fbce81 commit fb4af6c
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 88 deletions.
5 changes: 4 additions & 1 deletion src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2008,11 +2008,14 @@ class Compiler
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);
Expand Down
2 changes: 1 addition & 1 deletion src/jit/ee_il_dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

//------------------------------------------------------------------------
Expand Down
73 changes: 40 additions & 33 deletions src/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -7023,9 +7034,7 @@ 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->gtFlags |= GTF_IND_INVARIANT;
opModuleIDArg = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)pmoduleID, GTF_ICON_CIDMID_HDL, true);
}
else
{
Expand All @@ -7036,9 +7045,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_INT, (size_t)pclsID, GTF_ICON_CIDMID_HDL, true);
}
else
{
Expand Down Expand Up @@ -7651,7 +7658,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
{
Expand Down Expand Up @@ -8889,9 +8896,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
Expand Down
120 changes: 89 additions & 31 deletions src/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -6134,29 +6178,48 @@ 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;

assert((!value) != (!pValue));
GenTreePtr iconNode;
GenTreePtr handleNode;

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.
handleNode->gtFlags |= GTF_IND_NONFAULTING;
#if 0
// It should also be invariant, but marking it as such leads to bad diffs.

// 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 also is invariant.
handleNode->gtFlags |= GTF_IND_INVARIANT;
#endif
}

return node;
iconNode->gtIntCon.gtCompileTimeHandle = (size_t)compileTimeHandle;

return handleNode;
}

/*****************************************************************************/
Expand All @@ -6166,30 +6229,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, false);
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;
Expand Down Expand Up @@ -10610,7 +10668,7 @@ void Compiler::gtDispConst(GenTree* tree)
printf(" ftn");
break;
case GTF_ICON_CIDMID_HDL:
printf(" cid");
printf(" cid/mid");
break;
case GTF_ICON_BBC_PTR:
printf(" bbc");
Expand Down
2 changes: 1 addition & 1 deletion src/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,7 @@ struct GenTree
#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_CIDMID_HDL 0xE0000000 // GT_CNS_INT -- constant is a class ID or a module ID
#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
Expand Down
22 changes: 11 additions & 11 deletions src/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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, false);

return gtNewBlkOpNode(blk, // dst
src, // src
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit fb4af6c

Please sign in to comment.