From 171962f54145236ab354f64961b2174f404d605f Mon Sep 17 00:00:00 2001 From: Peter Kukol Date: Tue, 20 Sep 2016 18:59:34 -0700 Subject: [PATCH] Clean up GenTree node size dumping code. (#7278) Clean up GenTreeXxxx struct size dump; fix 32-bit build when MEASURE_NODE_SIZE is enabled. --- src/jit/compiler.cpp | 107 +------------------------------------------------- src/jit/flowgraph.cpp | 38 +++++++++--------- src/jit/gentree.cpp | 93 +++++++++++++++++++++++++++++++++++++++++-- src/jit/gentree.h | 12 +++++- src/jit/gtlist.h | 2 + 5 files changed, 123 insertions(+), 129 deletions(-) diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index 4030913..3117d9e 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -1511,111 +1511,8 @@ void Compiler::compDisplayStaticSizes(FILE* fout) { #if MEASURE_NODE_SIZE - /* - IMPORTANT: Use the following code to check the alignment of - GenTree members (in a retail build, of course). - */ - - GenTree* gtDummy = nullptr; - - fprintf(fout, "\n"); - fprintf(fout, "Offset / size of gtOper = %2u / %2u\n", offsetof(GenTree, gtOper), sizeof(gtDummy->gtOper)); - fprintf(fout, "Offset / size of gtType = %2u / %2u\n", offsetof(GenTree, gtType), sizeof(gtDummy->gtType)); -#if FEATURE_ANYCSE - fprintf(fout, "Offset / size of gtCSEnum = %2u / %2u\n", offsetof(GenTree, gtCSEnum), - sizeof(gtDummy->gtCSEnum)); -#endif // FEATURE_ANYCSE -#if ASSERTION_PROP - fprintf(fout, "Offset / size of gtAssertionNum = %2u / %2u\n", offsetof(GenTree, gtAssertionNum), - sizeof(gtDummy->gtAssertionNum)); -#endif // ASSERTION_PROP -#if FEATURE_STACK_FP_X87 - fprintf(fout, "Offset / size of gtFPlvl = %2u / %2u\n", offsetof(GenTree, gtFPlvl), - sizeof(gtDummy->gtFPlvl)); -#endif // FEATURE_STACK_FP_X87 - // TODO: The section that report GenTree sizes should be made into a public static member function of the GenTree - // class (see https://github.com/dotnet/coreclr/pull/493) - // fprintf(fout, "Offset / size of gtCostEx = %2u / %2u\n", offsetof(GenTree, _gtCostEx ), - // sizeof(gtDummy->_gtCostEx )); - // fprintf(fout, "Offset / size of gtCostSz = %2u / %2u\n", offsetof(GenTree, _gtCostSz ), - // sizeof(gtDummy->_gtCostSz )); - fprintf(fout, "Offset / size of gtFlags = %2u / %2u\n", offsetof(GenTree, gtFlags), - sizeof(gtDummy->gtFlags)); - fprintf(fout, "Offset / size of gtVNPair = %2u / %2u\n", offsetof(GenTree, gtVNPair), - sizeof(gtDummy->gtVNPair)); - fprintf(fout, "Offset / size of gtRsvdRegs = %2u / %2u\n", offsetof(GenTree, gtRsvdRegs), - sizeof(gtDummy->gtRsvdRegs)); -#ifdef LEGACY_BACKEND - fprintf(fout, "Offset / size of gtUsedRegs = %2u / %2u\n", offsetof(GenTree, gtUsedRegs), - sizeof(gtDummy->gtUsedRegs)); -#endif // LEGACY_BACKEND -#ifndef LEGACY_BACKEND - fprintf(fout, "Offset / size of gtLsraInfo = %2u / %2u\n", offsetof(GenTree, gtLsraInfo), - sizeof(gtDummy->gtLsraInfo)); -#endif // !LEGACY_BACKEND - fprintf(fout, "Offset / size of gtNext = %2u / %2u\n", offsetof(GenTree, gtNext), sizeof(gtDummy->gtNext)); - fprintf(fout, "Offset / size of gtPrev = %2u / %2u\n", offsetof(GenTree, gtPrev), sizeof(gtDummy->gtPrev)); - fprintf(fout, "\n"); - -#if SMALL_TREE_NODES - fprintf(fout, "Small tree node size = %3u\n", TREE_NODE_SZ_SMALL); -#endif // SMALL_TREE_NODES - fprintf(fout, "Large tree node size = %3u\n", TREE_NODE_SZ_LARGE); - fprintf(fout, "\n"); - fprintf(fout, "Size of GenTree = %3u\n", sizeof(GenTree)); - fprintf(fout, "Size of GenTreeUnOp = %3u\n", sizeof(GenTreeUnOp)); - fprintf(fout, "Size of GenTreeOp = %3u\n", sizeof(GenTreeOp)); - fprintf(fout, "Size of GenTreeVal = %3u\n", sizeof(GenTreeVal)); - fprintf(fout, "Size of GenTreeIntConCommon = %3u\n", sizeof(GenTreeIntConCommon)); - fprintf(fout, "Size of GenTreePhysReg = %3u\n", sizeof(GenTreePhysReg)); -#ifndef LEGACY_BACKEND - fprintf(fout, "Size of GenTreeJumpTable = %3u\n", sizeof(GenTreeJumpTable)); -#endif // !LEGACY_BACKEND - fprintf(fout, "Size of GenTreeIntCon = %3u\n", sizeof(GenTreeIntCon)); - fprintf(fout, "Size of GenTreeLngCon = %3u\n", sizeof(GenTreeLngCon)); - fprintf(fout, "Size of GenTreeDblCon = %3u\n", sizeof(GenTreeDblCon)); - fprintf(fout, "Size of GenTreeStrCon = %3u\n", sizeof(GenTreeStrCon)); - fprintf(fout, "Size of GenTreeLclVarCommon = %3u\n", sizeof(GenTreeLclVarCommon)); - fprintf(fout, "Size of GenTreeLclVar = %3u\n", sizeof(GenTreeLclVar)); - fprintf(fout, "Size of GenTreeLclFld = %3u\n", sizeof(GenTreeLclFld)); - fprintf(fout, "Size of GenTreeRegVar = %3u\n", sizeof(GenTreeRegVar)); - fprintf(fout, "Size of GenTreeCast = %3u\n", sizeof(GenTreeCast)); - fprintf(fout, "Size of GenTreeJumpCC = %3u\n", sizeof(GenTreeJumpCC)); - fprintf(fout, "Size of GenTreeBox = %3u\n", sizeof(GenTreeBox)); - fprintf(fout, "Size of GenTreeField = %3u\n", sizeof(GenTreeField)); - fprintf(fout, "Size of GenTreeArgList = %3u\n", sizeof(GenTreeArgList)); - fprintf(fout, "Size of GenTreeColon = %3u\n", sizeof(GenTreeColon)); - fprintf(fout, "Size of GenTreeCall = %3u\n", sizeof(GenTreeCall)); - fprintf(fout, "Size of GenTreeCmpXchg = %3u\n", sizeof(GenTreeCmpXchg)); - fprintf(fout, "Size of GenTreeFptrVal = %3u\n", sizeof(GenTreeFptrVal)); - fprintf(fout, "Size of GenTreeQmark = %3u\n", sizeof(GenTreeQmark)); - fprintf(fout, "Size of GenTreeIntrinsic = %3u\n", sizeof(GenTreeIntrinsic)); - fprintf(fout, "Size of GenTreeIndex = %3u\n", sizeof(GenTreeIndex)); - fprintf(fout, "Size of GenTreeArrLen = %3u\n", sizeof(GenTreeArrLen)); - fprintf(fout, "Size of GenTreeBoundsChk = %3u\n", sizeof(GenTreeBoundsChk)); - fprintf(fout, "Size of GenTreeArrElem = %3u\n", sizeof(GenTreeArrElem)); - fprintf(fout, "Size of GenTreeAddrMode = %3u\n", sizeof(GenTreeAddrMode)); - fprintf(fout, "Size of GenTreeIndir = %3u\n", sizeof(GenTreeIndir)); - fprintf(fout, "Size of GenTreeStoreInd = %3u\n", sizeof(GenTreeStoreInd)); - fprintf(fout, "Size of GenTreeRetExpr = %3u\n", sizeof(GenTreeRetExpr)); - fprintf(fout, "Size of GenTreeStmt = %3u\n", sizeof(GenTreeStmt)); - fprintf(fout, "Size of GenTreeObj = %3u\n", sizeof(GenTreeObj)); - fprintf(fout, "Size of GenTreeClsVar = %3u\n", sizeof(GenTreeClsVar)); - fprintf(fout, "Size of GenTreeArgPlace = %3u\n", sizeof(GenTreeArgPlace)); - fprintf(fout, "Size of GenTreeLabel = %3u\n", sizeof(GenTreeLabel)); - fprintf(fout, "Size of GenTreePhiArg = %3u\n", sizeof(GenTreePhiArg)); - fprintf(fout, "Size of GenTreePutArgStk = %3u\n", sizeof(GenTreePutArgStk)); - fprintf(fout, "Size of GenTreeCopyOrReload = %3u\n", sizeof(GenTreeCopyOrReload)); - fprintf(fout, "Size of GenTreeAllocObj = %3u\n", sizeof(GenTreeAllocObj)); - fprintf(fout, "Size of GenTreeBlk = %3u\n", sizeof(GenTreeBlk)); - fprintf(fout, "Size of GenTreeDynBlk = %3u\n", sizeof(GenTreeDynBlk)); - fprintf(fout, "Size of GenTreeArrIndex = %3u\n", sizeof(GenTreeArrIndex)); - fprintf(fout, "Size of GenTreeArrOffs = %3u\n", sizeof(GenTreeArrOffs)); -#ifdef FEATURE_SIMD - fprintf(fout, "Size of GenTreeSIMD = %3u\n", sizeof(GenTreeSIMD)); + GenTree::DumpNodeSizes(fout); #endif - fprintf(fout, "\n"); -#endif // MEASURE_NODE_SIZE #if MEASURE_BLOCK_SIZE @@ -1642,8 +1539,6 @@ void Compiler::compDisplayStaticSizes(FILE* fout) sizeof(bbDummy->bbJumpDest)); fprintf(fout, "Offset / size of bbJumpSwt = %3u / %3u\n", offsetof(BasicBlock, bbJumpSwt), sizeof(bbDummy->bbJumpSwt)); - fprintf(fout, "Offset / size of bbTreeList = %3u / %3u\n", offsetof(BasicBlock, bbTreeList), - sizeof(bbDummy->bbTreeList)); fprintf(fout, "Offset / size of bbEntryState = %3u / %3u\n", offsetof(BasicBlock, bbEntryState), sizeof(bbDummy->bbEntryState)); fprintf(fout, "Offset / size of bbStkTempsIn = %3u / %3u\n", offsetof(BasicBlock, bbStkTempsIn), diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index bf51bc1..babf9c2 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -13490,6 +13490,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) GenTree* switchVal = switchTree->gtOp.gtOp1; noway_assert(genActualTypeIsIntOrI(switchVal->TypeGet())); +#ifndef LEGACY_BACKEND // If we are in LIR, remove the jump table from the block. if (block->IsLIR()) { @@ -13497,6 +13498,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) assert(jumpTable->OperGet() == GT_JMPTABLE); blockRange->Remove(jumpTable); } +#endif // Change the GT_SWITCH(switchVal) into GT_JTRUE(GT_EQ(switchVal==0)). // Also mark the node as GTF_DONT_CSE as further down JIT is not capable of handling it. @@ -18371,7 +18373,7 @@ void Compiler::fgSetBlockOrder(BasicBlock* block) // // For the (usual) case of GT_BLK or GT_OBJ, the size is always "evaluated" (i.e. // instantiated into a register) last. In those cases, the GTF_REVERSE_OPS flag -// on the assignment works as usual. +// on the assignment works as usual. // In order to preserve previous possible orderings, the order for evaluating // the size of a GT_DYN_BLK node is controlled by its gtEvalSizeFirst flag. If // that is set, the size is evaluated first, and then the src and dst are evaluated @@ -18980,7 +18982,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase) { createDotFile = true; } - + FILE* fgxFile = fgOpenFlowGraphFile(&dontClose, phase, createDotFile ? W("dot") : W("fgx")); if (fgxFile == nullptr) @@ -19061,7 +19063,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase) fprintf(fgxFile, ">"); } - static const char* kindImage[] = { "EHFINALLYRET", "EHFILTERRET", "EHCATCHRET", + static const char* kindImage[] = { "EHFINALLYRET", "EHFILTERRET", "EHCATCHRET", "THROW", "RETURN", "NONE", "ALWAYS", "LEAVE", "CALLFINALLY", "COND", "SWITCH" }; @@ -19693,7 +19695,7 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, { printf("bad prev link!\n"); } - + if (block == fgFirstColdBlock) { printf("~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", @@ -19794,7 +19796,7 @@ void Compiler::fgDumpTrees(BasicBlock* firstBlock, /* Walk the basic blocks */ - // Note that typically we have already called fgDispBasicBlocks() + // Note that typically we have already called fgDispBasicBlocks() // so we don't need to print the preds and succs again here // for (BasicBlock* block = firstBlock; block; block = block->bbNext) @@ -19819,7 +19821,7 @@ Compiler::fgWalkResult Compiler::fgStress64RsltMulCB(GenTreePtr* pTree, fgW { GenTreePtr tree = *pTree; Compiler* pComp = data->compiler; - + if (tree->gtOper != GT_MUL || tree->gtType != TYP_INT || (tree->gtOverflow())) { return WALK_CONTINUE; } @@ -19827,14 +19829,14 @@ Compiler::fgWalkResult Compiler::fgStress64RsltMulCB(GenTreePtr* pTree, fgW #ifdef DEBUG if (pComp->verbose) { - printf("STRESS_64RSLT_MUL before:\n"); + printf("STRESS_64RSLT_MUL before:\n"); pComp->gtDispTree(tree); } #endif // DEBUG // To ensure optNarrowTree() doesn't fold back to the original tree. tree->gtOp.gtOp1 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp1, TYP_LONG); - tree->gtOp.gtOp1 = pComp->gtNewOperNode(GT_NOP, TYP_LONG, tree->gtOp.gtOp1); + tree->gtOp.gtOp1 = pComp->gtNewOperNode(GT_NOP, TYP_LONG, tree->gtOp.gtOp1); tree->gtOp.gtOp1 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp1, TYP_LONG); tree->gtOp.gtOp2 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp2, TYP_LONG); tree->gtType = TYP_LONG; @@ -19843,7 +19845,7 @@ Compiler::fgWalkResult Compiler::fgStress64RsltMulCB(GenTreePtr* pTree, fgW #ifdef DEBUG if (pComp->verbose) { - printf("STRESS_64RSLT_MUL after:\n"); + printf("STRESS_64RSLT_MUL after:\n"); pComp->gtDispTree(*pTree); } #endif // DEBUG @@ -19887,7 +19889,7 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, #endif // DEBUG fgDebugCheckBlockLinks(); - + if (fgBBcount > 10000 && expensiveDebugCheckLevel < 1) { // The basic block checks are too expensive if there are too many blocks, @@ -20373,7 +20375,7 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree) fgDebugCheckFlags(op2); } - if (op1) + if (op1) { chkFlags |= (op1->gtFlags & GTF_ALL_EFFECT); } @@ -20442,8 +20444,8 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree) /* See what kind of a special operator we have here */ - else - { + else + { switch (tree->OperGet()) { case GT_CALL: @@ -20451,7 +20453,7 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree) GenTreePtr args; GenTreePtr argx; GenTreeCall* call; - + call = tree->AsCall(); chkFlags |= GTF_CALL; @@ -21020,7 +21022,7 @@ void Compiler::fgInline() (void *) this); // See if stmt is of the form GT_COMMA(call, nop) - // If yes, we can get rid of GT_COMMA. + // If yes, we can get rid of GT_COMMA. if (expr->OperGet() == GT_COMMA && expr->gtOp.gtOp1->OperGet() == GT_CALL && expr->gtOp.gtOp2->OperGet() == GT_NOP) @@ -21309,7 +21311,7 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder( if (tree->gtOper == GT_RET_EXPR) { - // We are going to copy the tree from the inlinee, + // We are going to copy the tree from the inlinee, // so record the handle now. // if (varTypeIsStruct(tree)) @@ -21325,7 +21327,7 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder( #ifdef DEBUG if (comp->verbose) { - printf("\nReplacing the return expression placeholder "); + printf("\nReplacing the return expression placeholder "); printTreeID(tree); printf(" with "); printTreeID(inlineCandidate); @@ -21335,7 +21337,7 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder( } #endif // DEBUG - tree->CopyFrom(inlineCandidate, comp); + tree->CopyFrom(inlineCandidate, comp); #ifdef DEBUG if (comp->verbose) diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index 89fee00..fa84ae2 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -222,7 +222,7 @@ const char* GenTree::NodeName(genTreeOps op) #endif -#if defined(DEBUG) || NODEBASH_STATS || COUNT_AST_OPERS +#if defined(DEBUG) || NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS static const char* opNames[] = { #define GTNODE(en, sn, st, cm, ok) #en, @@ -238,6 +238,22 @@ const char* GenTree::OpName(genTreeOps op) #endif +#if MEASURE_NODE_SIZE && SMALL_TREE_NODES + +static const char* opStructNames[] = { + #define GTNODE(en, sn, st, cm, ok) #st, + #include "gtlist.h" +}; + +const char* GenTree::OpStructName(genTreeOps op) +{ + assert((unsigned)op < sizeof(opStructNames) / sizeof(opStructNames[0])); + + return opStructNames[op]; +} + +#endif + /***************************************************************************** * * When 'SMALL_TREE_NODES' is enabled, we allocate tree nodes in 2 different @@ -251,7 +267,7 @@ const char* GenTree::OpName(genTreeOps op) /* static */ unsigned char GenTree::s_gtNodeSizes[GT_COUNT + 1]; -#if NODEBASH_STATS || COUNT_AST_OPERS +#if NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS unsigned char GenTree::s_gtTrueSizes[GT_COUNT+1] { @@ -259,7 +275,7 @@ unsigned char GenTree::s_gtTrueSizes[GT_COUNT+1] #include "gtlist.h" }; -#endif // NODEBASH_STATS || COUNT_AST_OPERS +#endif // NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS #if COUNT_AST_OPERS LONG GenTree::s_gtNodeCounts[GT_COUNT+1] = {0}; @@ -514,6 +530,75 @@ bool GenTree::IsNodeProperlySized() const /*****************************************************************************/ +#if MEASURE_NODE_SIZE + +void GenTree::DumpNodeSizes(FILE* fp) +{ + // Dump the sizes of the various GenTree flavors + +#if SMALL_TREE_NODES + fprintf(fp, "Small tree node size = %3u bytes\n", TREE_NODE_SZ_SMALL); +#endif + fprintf(fp, "Large tree node size = %3u bytes\n", TREE_NODE_SZ_LARGE); + fprintf(fp, "\n"); + +#if SMALL_TREE_NODES + + // Verify that node sizes are set kosherly and dump sizes + for (unsigned op = GT_NONE+1; op < GT_COUNT; op++) + { + unsigned needSize = s_gtTrueSizes[op]; + unsigned nodeSize = s_gtNodeSizes[op]; + + const char* structNm = OpStructName((genTreeOps)op); + const char* operName = OpName((genTreeOps)op); + + bool repeated = false; + + // Have we seen this struct flavor before? + for (unsigned mop = GT_NONE+1; mop < op; mop++) + { + if (strcmp(structNm, OpStructName((genTreeOps)mop)) == 0) + { + repeated = true; + break; + } + } + + // Don't repeat the same GenTree flavor unless we have an error + if (!repeated || needSize > nodeSize) + { + unsigned sizeChar = '?'; + + if (nodeSize == TREE_NODE_SZ_SMALL) + sizeChar = 'S'; + else if (nodeSize == TREE_NODE_SZ_LARGE) + sizeChar = 'L'; + + fprintf(fp, "GT_%-16s ... %-19s = %3u bytes (%c)", operName, + structNm, + needSize, + sizeChar); + if (needSize > nodeSize) + { + fprintf(fp, " -- ERROR -- allocation is only %u bytes!", nodeSize); + } + else if (needSize <= TREE_NODE_SZ_SMALL && nodeSize == TREE_NODE_SZ_LARGE) + { + fprintf(fp, " ... could be small"); + } + + fprintf(fp, "\n"); + } + } + +#endif + +} + +#endif // MEASURE_NODE_SIZE +/*****************************************************************************/ + // make sure these get instantiated, because it's not in a header file // (emulating the c++ 'export' keyword here) // VC appears to be somewhat unpredictable about whether they end up in the .obj file without this @@ -15559,7 +15644,9 @@ bool GenTree::isContained() const case GT_STORE_OBJ: case GT_STORE_DYN_BLK: case GT_SWITCH: +#ifndef LEGACY_BACKEND case GT_JMPTABLE: +#endif case GT_SWITCH_TABLE: case GT_SWAP: case GT_LCLHEAP: diff --git a/src/jit/gentree.h b/src/jit/gentree.h index 2e9f4b0..6d50cf4 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -1570,7 +1570,7 @@ public: public: #if SMALL_TREE_NODES static unsigned char s_gtNodeSizes[]; -#if NODEBASH_STATS || COUNT_AST_OPERS +#if NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS static unsigned char s_gtTrueSizes[]; #endif #if COUNT_AST_OPERS @@ -1600,10 +1600,14 @@ public: static const char* NodeName(genTreeOps op); #endif -#if defined(DEBUG) || NODEBASH_STATS || COUNT_AST_OPERS +#if defined(DEBUG) || NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS static const char* OpName(genTreeOps op); #endif +#if MEASURE_NODE_SIZE && SMALL_TREE_NODES + static const char* OpStructName(genTreeOps op); +#endif + //--------------------------------------------------------------------- bool IsNothingNode() const; @@ -1917,6 +1921,10 @@ public: gtFlags &= ~GTF_REUSE_REG_VAL; } +#if MEASURE_NODE_SIZE + static void DumpNodeSizes(FILE* fp); +#endif + #ifdef DEBUG private: diff --git a/src/jit/gtlist.h b/src/jit/gtlist.h index edd246d..a330a6b 100644 --- a/src/jit/gtlist.h +++ b/src/jit/gtlist.h @@ -247,7 +247,9 @@ GTNODE(PHI_ARG , "phiArg" ,GenTreePhiArg ,0,GTK_LEAF|GTK_LOC // Nodes used by Lower to generate a closer CPU representation of other nodes //----------------------------------------------------------------------------- +#ifndef LEGACY_BACKEND GTNODE(JMPTABLE , "jumpTable" ,GenTreeJumpTable ,0, GTK_LEAF) // Generates the jump table for switches +#endif GTNODE(SWITCH_TABLE , "tableSwitch" ,GenTreeOp ,0, GTK_BINOP|GTK_NOVALUE) // Jump Table based switch construct //----------------------------------------------------------------------------- -- 2.7.4