}
}
- bool verboseDump = false;
- bool dumpIR = false;
- bool dumpIRTypes = false;
- bool dumpIRLocals = false;
- bool dumpIRRegs = false;
- bool dumpIRSsa = false;
- bool dumpIRValnums = false;
- bool dumpIRCosts = false;
- bool dumpIRFlags = false;
- bool dumpIRKinds = false;
- bool dumpIRNodes = false;
- bool dumpIRNoLists = false;
- bool dumpIRNoLeafs = false;
- bool dumpIRNoStmts = false;
- bool dumpIRTrees = false;
- bool dumpIRLinear = false;
- bool dumpIRDataflow = false;
- bool dumpIRBlockHeaders = false;
- bool dumpIRExit = false;
- LPCWSTR dumpIRPhase = nullptr;
+ bool verboseDump = false;
if (!altJitConfig || opts.altJit)
{
{
verboseDump = true;
}
- if (JitConfig.NgenDumpIR().contains(info.compMethodName, info.compClassName,
- &info.compMethodInfo->args))
- {
- dumpIR = true;
- }
- unsigned ngenHashDumpIRVal = (unsigned)JitConfig.NgenHashDumpIR();
- if ((ngenHashDumpIRVal != (DWORD)-1) && (ngenHashDumpIRVal == info.compMethodHash()))
- {
- dumpIR = true;
- }
- dumpIRFormat = JitConfig.NgenDumpIRFormat();
- dumpIRPhase = JitConfig.NgenDumpIRPhase();
}
else
{
{
verboseDump = true;
}
- if (JitConfig.JitDumpIR().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args))
- {
- dumpIR = true;
- }
- unsigned jitHashDumpIRVal = (unsigned)JitConfig.JitHashDumpIR();
- if ((jitHashDumpIRVal != (DWORD)-1) && (jitHashDumpIRVal == info.compMethodHash()))
- {
- dumpIR = true;
- }
- dumpIRFormat = JitConfig.JitDumpIRFormat();
- dumpIRPhase = JitConfig.JitDumpIRPhase();
- }
- }
-
- if (dumpIRPhase == nullptr)
- {
- dumpIRPhase = W("*");
- }
-
- this->dumpIRPhase = dumpIRPhase;
-
- if (dumpIRFormat != nullptr)
- {
- this->dumpIRFormat = dumpIRFormat;
- }
-
- dumpIRTrees = false;
- dumpIRLinear = true;
- if (dumpIRFormat != nullptr)
- {
- for (LPCWSTR p = dumpIRFormat; (*p != 0);)
- {
- for (; (*p != 0); p++)
- {
- if (*p != L' ')
- {
- break;
- }
- }
-
- if (*p == 0)
- {
- break;
- }
-
- static bool dumpedHelp = false;
-
- if ((*p == L'?') && (!dumpedHelp))
- {
- printf("*******************************************************************************\n");
- printf("\n");
- dFormatIR();
- printf("\n");
- printf("\n");
- printf("Available specifiers (comma separated):\n");
- printf("\n");
- printf("? dump out value of COMPlus_JitDumpIRFormat and this list of values\n");
- printf("\n");
- printf("linear linear IR dump (default)\n");
- printf("tree tree IR dump (traditional)\n");
- printf("mixed intermingle tree dump with linear IR dump\n");
- printf("\n");
- printf("dataflow use data flow form of linear IR dump\n");
- printf("structural use structural form of linear IR dump\n");
- printf("all implies structural, include everything\n");
- printf("\n");
- printf("kinds include tree node kinds in dump, example: \"kinds=[LEAF][LOCAL]\"\n");
- printf("flags include tree node flags in dump, example: \"flags=[CALL][GLOB_REF]\" \n");
- printf("types includes tree node types in dump, example: \".int\"\n");
- printf("locals include local numbers and tracking numbers in dump, example: \"(V3,T1)\"\n");
- printf("regs include register assignments in dump, example: \"(rdx)\"\n");
- printf("ssa include SSA numbers in dump, example: \"<d:3>\" or \"<u:3>\"\n");
- printf("valnums include Value numbers in dump, example: \"<v:$c4>\" or \"<v:$c4,$c5>\"\n");
- printf("\n");
- printf("nolist exclude GT_LIST nodes from dump\n");
- printf("noleafs exclude LEAF nodes from dump (fold into operations)\n");
- printf("nostmts exclude GT_STMTS from dump (unless required by dependencies)\n");
- printf("\n");
- printf("blkhdrs include block headers\n");
- printf("exit exit program after last phase dump (used with single method)\n");
- printf("\n");
- printf("*******************************************************************************\n");
- dumpedHelp = true;
- }
-
- if (wcsncmp(p, W("types"), 5) == 0)
- {
- dumpIRTypes = true;
- }
-
- if (wcsncmp(p, W("locals"), 6) == 0)
- {
- dumpIRLocals = true;
- }
-
- if (wcsncmp(p, W("regs"), 4) == 0)
- {
- dumpIRRegs = true;
- }
-
- if (wcsncmp(p, W("ssa"), 3) == 0)
- {
- dumpIRSsa = true;
- }
-
- if (wcsncmp(p, W("valnums"), 7) == 0)
- {
- dumpIRValnums = true;
- }
-
- if (wcsncmp(p, W("costs"), 5) == 0)
- {
- dumpIRCosts = true;
- }
-
- if (wcsncmp(p, W("flags"), 5) == 0)
- {
- dumpIRFlags = true;
- }
-
- if (wcsncmp(p, W("kinds"), 5) == 0)
- {
- dumpIRKinds = true;
- }
-
- if (wcsncmp(p, W("nodes"), 5) == 0)
- {
- dumpIRNodes = true;
- }
-
- if (wcsncmp(p, W("exit"), 4) == 0)
- {
- dumpIRExit = true;
- }
-
- if (wcsncmp(p, W("nolists"), 7) == 0)
- {
- dumpIRNoLists = true;
- }
-
- if (wcsncmp(p, W("noleafs"), 7) == 0)
- {
- dumpIRNoLeafs = true;
- }
-
- if (wcsncmp(p, W("nostmts"), 7) == 0)
- {
- dumpIRNoStmts = true;
- }
-
- if (wcsncmp(p, W("trees"), 5) == 0)
- {
- dumpIRTrees = true;
- dumpIRLinear = false;
- }
-
- if (wcsncmp(p, W("structural"), 10) == 0)
- {
- dumpIRLinear = true;
- dumpIRNoStmts = false;
- dumpIRNoLeafs = false;
- dumpIRNoLists = false;
- }
-
- if (wcsncmp(p, W("all"), 3) == 0)
- {
- dumpIRLinear = true;
- dumpIRKinds = true;
- dumpIRFlags = true;
- dumpIRTypes = true;
- dumpIRLocals = true;
- dumpIRRegs = true;
- dumpIRSsa = true;
- dumpIRValnums = true;
- dumpIRCosts = true;
- dumpIRNoStmts = false;
- dumpIRNoLeafs = false;
- dumpIRNoLists = false;
- }
-
- if (wcsncmp(p, W("linear"), 6) == 0)
- {
- dumpIRTrees = false;
- dumpIRLinear = true;
- }
-
- if (wcsncmp(p, W("mixed"), 5) == 0)
- {
- dumpIRTrees = true;
- dumpIRLinear = true;
- }
-
- if (wcsncmp(p, W("dataflow"), 8) == 0)
- {
- dumpIRDataflow = true;
- dumpIRNoLeafs = true;
- dumpIRNoLists = true;
- dumpIRNoStmts = true;
- }
-
- if (wcsncmp(p, W("blkhdrs"), 7) == 0)
- {
- dumpIRBlockHeaders = true;
- }
-
- for (; (*p != 0); p++)
- {
- if (*p == L',')
- {
- p++;
- break;
- }
- }
}
}
}
{
verbose = true;
}
-
- if (dumpIR)
- {
- this->dumpIR = true;
- }
-
- if (dumpIRTypes)
- {
- this->dumpIRTypes = true;
- }
-
- if (dumpIRLocals)
- {
- this->dumpIRLocals = true;
- }
-
- if (dumpIRRegs)
- {
- this->dumpIRRegs = true;
- }
-
- if (dumpIRSsa)
- {
- this->dumpIRSsa = true;
- }
-
- if (dumpIRValnums)
- {
- this->dumpIRValnums = true;
- }
-
- if (dumpIRCosts)
- {
- this->dumpIRCosts = true;
- }
-
- if (dumpIRFlags)
- {
- this->dumpIRFlags = true;
- }
-
- if (dumpIRKinds)
- {
- this->dumpIRKinds = true;
- }
-
- if (dumpIRNodes)
- {
- this->dumpIRNodes = true;
- }
-
- if (dumpIRNoLists)
- {
- this->dumpIRNoLists = true;
- }
-
- if (dumpIRNoLeafs)
- {
- this->dumpIRNoLeafs = true;
- }
-
- if (dumpIRNoLeafs && dumpIRDataflow)
- {
- this->dumpIRDataflow = true;
- }
-
- if (dumpIRNoStmts)
- {
- this->dumpIRNoStmts = true;
- }
-
- if (dumpIRTrees)
- {
- this->dumpIRTrees = true;
- }
-
- if (dumpIRLinear)
- {
- this->dumpIRLinear = true;
- }
-
- if (dumpIRBlockHeaders)
- {
- this->dumpIRBlockHeaders = true;
- }
-
- if (dumpIRExit)
- {
- this->dumpIRExit = true;
- }
-
#endif // DEBUG
#ifdef FEATURE_SIMD
forceFrameJIT = (void*)&me; // let us see the this pointer in fastchecked build
// set this early so we can use it without relying on random memory values
verbose = compIsForInlining() ? impInlineInfo->InlinerCompiler->verbose : false;
-
- this->dumpIR = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIR : false;
- this->dumpIRPhase = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRPhase : nullptr;
- this->dumpIRFormat = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRFormat : nullptr;
- this->dumpIRTypes = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRTypes : false;
- this->dumpIRLocals = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRLocals : false;
- this->dumpIRRegs = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRRegs : false;
- this->dumpIRSsa = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRSsa : false;
- this->dumpIRValnums = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRValnums : false;
- this->dumpIRCosts = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRCosts : false;
- this->dumpIRFlags = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRFlags : false;
- this->dumpIRKinds = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRKinds : false;
- this->dumpIRNodes = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRNodes : false;
- this->dumpIRNoLists = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRNoLists : false;
- this->dumpIRNoLeafs = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRNoLeafs : false;
- this->dumpIRNoStmts = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRNoStmts : false;
- this->dumpIRTrees = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRTrees : false;
- this->dumpIRLinear = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRLinear : false;
- this->dumpIRDataflow = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRDataflow : false;
- this->dumpIRBlockHeaders = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRBlockHeaders : NULL;
- this->dumpIRExit = compIsForInlining() ? impInlineInfo->InlinerCompiler->dumpIRExit : NULL;
-
#endif
#if defined(DEBUG) || defined(INLINE_DATA)
* cCVarSet, dCVarSet : Display a "converted" VARSET_TP: the varset is assumed to be tracked variable
* indices. These are converted to variable numbers and sorted. (Calls
* dumpConvertedVarSet()).
- *
- * cFuncIR, dFuncIR : Display all the basic blocks of a function in linear IR form.
- * cLoopIR, dLoopIR : Display a loop in linear IR form.
- * dLoopNumIR : Display a loop (given number) in linear IR form.
- * cBlockIR, dBlockIR : Display a basic block in linear IR form.
- * cTreeIR, dTreeIR : Display a tree in linear IR form.
- * dTabStopIR : Display spaces to the next tab stop column
- * cTreeTypeIR dTreeTypeIR : Display tree type
- * cTreeKindsIR dTreeKindsIR : Display tree kinds
- * cTreeFlagsIR dTreeFlagsIR : Display tree flags
- * cOperandIR dOperandIR : Display tree operand
- * cLeafIR dLeafIR : Display tree leaf
- * cIndirIR dIndirIR : Display indir tree as [t#] or [leaf]
- * cListIR dListIR : Display tree list
- * cSsaNumIR dSsaNumIR : Display SSA number as <u|d:#>
- * cValNumIR dValNumIR : Display Value number as <v{l|c}:#{,R}>
- * cDependsIR : Display dependencies of a tree DEP(t# ...) node
- * based on child comma tree nodes
- * dFormatIR : Display dump format specified on command line
- *
+ * cLoop, dLoop : Display the blocks of a loop, including the trees.
+ * cTreeFlags, dTreeFlags : Display tree flags
*
* The following don't require a Compiler* to work:
* dRegMask : Display a regMaskTP (call dspRegMask(mask)).
printf("\n"); // dumpConvertedVarSet() doesn't emit a trailing newline
}
+void cLoop(Compiler* comp, Compiler::LoopDsc* loop)
+{
+ static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
+ printf("===================================================================== Loop %u\n", sequenceNumber++);
+ printf("HEAD " FMT_BB "\n", loop->lpHead->bbNum);
+ printf("FIRST " FMT_BB "\n", loop->lpFirst->bbNum);
+ printf("TOP " FMT_BB "\n", loop->lpTop->bbNum);
+ printf("ENTRY " FMT_BB "\n", loop->lpEntry->bbNum);
+ if (loop->lpExitCnt == 1)
+ {
+ printf("EXIT " FMT_BB "\n", loop->lpExit->bbNum);
+ }
+ else
+ {
+ printf("EXITS %u\n", loop->lpExitCnt);
+ }
+ printf("BOTTOM " FMT_BB "\n", loop->lpBottom->bbNum);
+
+ comp->fgDispBasicBlocks(loop->lpHead, loop->lpBottom, true);
+}
+
void dBlock(BasicBlock* block)
{
cBlock(JitTls::GetCompiler(), block);
cCVarSet(JitTls::GetCompiler(), vars);
}
+void dLoop(Compiler::LoopDsc* loop)
+{
+ cLoop(JitTls::GetCompiler(), loop);
+}
+
void dRegMask(regMaskTP mask)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
return block;
}
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out function in linear IR form
- */
-
-void cFuncIR(Compiler* comp)
-{
- BasicBlock* block;
-
- printf("Method %s::%s, hash=%08x\n", comp->info.compClassName, comp->info.compMethodName,
- comp->info.compMethodHash());
-
- printf("\n");
-
- for (block = comp->fgFirstBB; block != nullptr; block = block->bbNext)
- {
- cBlockIR(comp, block);
- }
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out the format specifiers from COMPlus_JitDumpIRFormat
- */
-
-void dFormatIR()
+Compiler::LoopDsc* dFindLoop(unsigned loopNum)
{
Compiler* comp = JitTls::GetCompiler();
- if (comp->dumpIRFormat != nullptr)
+ if (loopNum >= comp->optLoopCount)
{
- printf("COMPlus_JitDumpIRFormat=%ls", comp->dumpIRFormat);
+ printf("loopNum %u out of range\n");
+ return nullptr;
}
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out function in linear IR form
- */
-void dFuncIR()
-{
- cFuncIR(JitTls::GetCompiler());
+ return &comp->optLoopTable[loopNum];
}
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out loop in linear IR form
- */
-
-void cLoopIR(Compiler* comp, Compiler::LoopDsc* loop)
+void cTreeFlags(Compiler* comp, GenTree* tree)
{
- BasicBlock* blockHead = loop->lpHead;
- BasicBlock* blockFirst = loop->lpFirst;
- BasicBlock* blockTop = loop->lpTop;
- BasicBlock* blockEntry = loop->lpEntry;
- BasicBlock* blockBottom = loop->lpBottom;
- BasicBlock* blockExit = loop->lpExit;
- BasicBlock* blockLast = blockBottom->bbNext;
- BasicBlock* block;
-
- printf("LOOP\n");
- printf("\n");
- printf("HEAD " FMT_BB "\n", blockHead->bbNum);
- printf("FIRST " FMT_BB "\n", blockFirst->bbNum);
- printf("TOP " FMT_BB "\n", blockTop->bbNum);
- printf("ENTRY " FMT_BB "\n", blockEntry->bbNum);
- if (loop->lpExitCnt == 1)
- {
- printf("EXIT " FMT_BB "\n", blockExit->bbNum);
- }
- else
- {
- printf("EXITS %u", loop->lpExitCnt);
- }
- printf("BOTTOM " FMT_BB "\n", blockBottom->bbNum);
- printf("\n");
+ int chars = 0;
- cBlockIR(comp, blockHead);
- for (block = blockFirst; ((block != nullptr) && (block != blockLast)); block = block->bbNext)
+ if (tree->gtFlags != 0)
{
- cBlockIR(comp, block);
- }
-}
+ chars += printf("flags=");
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out loop in linear IR form
- */
+ // Node flags
+ CLANG_FORMAT_COMMENT_ANCHOR;
-void dLoopIR(Compiler::LoopDsc* loop)
-{
- cLoopIR(JitTls::GetCompiler(), loop);
-}
+#if defined(DEBUG)
+ if (tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE)
+ {
+ chars += printf("[NODE_LARGE]");
+ }
+ if (tree->gtDebugFlags & GTF_DEBUG_NODE_SMALL)
+ {
+ chars += printf("[NODE_SMALL]");
+ }
+ if (tree->gtDebugFlags & GTF_DEBUG_NODE_MORPHED)
+ {
+ chars += printf("[MORPHED]");
+ }
+#endif // defined(DEBUG)
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out loop (given loop number) in linear IR form
- */
+ if (tree->gtFlags & GTF_COLON_COND)
+ {
+ chars += printf("[COLON_COND]");
+ }
-void dLoopNumIR(unsigned loopNum)
-{
- Compiler* comp = JitTls::GetCompiler();
+ // Operator flags
- if (loopNum >= comp->optLoopCount)
- {
- printf("loopNum %u out of range\n");
- return;
- }
-
- Compiler::LoopDsc* loop = &comp->optLoopTable[loopNum];
- cLoopIR(JitTls::GetCompiler(), loop);
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump spaces to specified tab stop
- */
-
-int dTabStopIR(int curr, int tabstop)
-{
- int chars = 0;
-
- if (tabstop <= curr)
- {
- chars += printf(" ");
- }
-
- for (int i = curr; i < tabstop; i++)
- {
- chars += printf(" ");
- }
-
- return chars;
-}
-
-void cNodeIR(Compiler* comp, GenTree* tree);
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out block in linear IR form
- */
-
-void cBlockIR(Compiler* comp, BasicBlock* block)
-{
- bool noStmts = comp->dumpIRNoStmts;
- bool trees = comp->dumpIRTrees;
-
- if (comp->dumpIRBlockHeaders)
- {
- block->dspBlockHeader(comp);
- }
- else
- {
- printf(FMT_BB ":\n", block->bbNum);
- }
-
- printf("\n");
-
- if (!block->IsLIR())
- {
- for (Statement* stmt : block->Statements())
- {
- // Print current stmt.
-
- if (trees)
- {
- cStmt(comp, stmt);
- printf("\n");
- printf("=====================================================================\n");
- }
-
- if (comp->compRationalIRForm)
- {
- for (GenTree* tree = stmt->GetTreeList(); tree != nullptr; tree = tree->gtNext)
- {
- cNodeIR(comp, tree);
- }
- }
- else
- {
- cStmtIR(comp, stmt);
- }
-
- if (!noStmts && !trees)
- {
- printf("\n");
- }
- }
- }
- else
- {
- for (GenTree* node = block->GetFirstLIRNode(); node != nullptr; node = node->gtNext)
- {
- cNodeIR(comp, node);
- }
- }
-
- int chars = 0;
-
- chars += dTabStopIR(chars, COLUMN_OPCODE);
-
- chars += printf(" ");
- switch (block->bbJumpKind)
- {
- case BBJ_EHFINALLYRET:
- chars += printf("BRANCH(EHFINALLYRET)");
- break;
-
- case BBJ_EHFILTERRET:
- chars += printf("BRANCH(EHFILTERRET)");
- break;
-
- case BBJ_EHCATCHRET:
- chars += printf("BRANCH(EHCATCHRETURN)");
- chars += dTabStopIR(chars, COLUMN_OPERANDS);
- chars += printf(" " FMT_BB, block->bbJumpDest->bbNum);
- break;
-
- case BBJ_THROW:
- chars += printf("BRANCH(THROW)");
- break;
-
- case BBJ_RETURN:
- chars += printf("BRANCH(RETURN)");
- break;
-
- case BBJ_NONE:
- // For fall-through blocks
- chars += printf("BRANCH(NONE)");
- break;
-
- case BBJ_ALWAYS:
- chars += printf("BRANCH(ALWAYS)");
- chars += dTabStopIR(chars, COLUMN_OPERANDS);
- chars += printf(" " FMT_BB, block->bbJumpDest->bbNum);
- if (block->bbFlags & BBF_KEEP_BBJ_ALWAYS)
- {
- chars += dTabStopIR(chars, COLUMN_KINDS);
- chars += printf("; [KEEP_BBJ_ALWAYS]");
- }
- break;
-
- case BBJ_LEAVE:
- chars += printf("BRANCH(LEAVE)");
- chars += dTabStopIR(chars, COLUMN_OPERANDS);
- chars += printf(" " FMT_BB, block->bbJumpDest->bbNum);
- break;
-
- case BBJ_CALLFINALLY:
- chars += printf("BRANCH(CALLFINALLY)");
- chars += dTabStopIR(chars, COLUMN_OPERANDS);
- chars += printf(" " FMT_BB, block->bbJumpDest->bbNum);
- break;
-
- case BBJ_COND:
- chars += printf("BRANCH(COND)");
- chars += dTabStopIR(chars, COLUMN_OPERANDS);
- chars += printf(" " FMT_BB, block->bbJumpDest->bbNum);
- break;
-
- case BBJ_SWITCH:
- chars += printf("BRANCH(SWITCH)");
- chars += dTabStopIR(chars, COLUMN_OPERANDS);
-
- unsigned jumpCnt;
- jumpCnt = block->bbJumpSwt->bbsCount;
- BasicBlock** jumpTab;
- jumpTab = block->bbJumpSwt->bbsDstTab;
- do
- {
- chars += printf("%c " FMT_BB, (jumpTab == block->bbJumpSwt->bbsDstTab) ? ' ' : ',', (*jumpTab)->bbNum);
- } while (++jumpTab, --jumpCnt);
- break;
-
- default:
- unreached();
- break;
- }
-
- printf("\n");
- if (block->bbNext != nullptr)
- {
- printf("\n");
- }
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out block in linear IR form
- */
-
-void dBlockIR(BasicBlock* block)
-{
- cBlockIR(JitTls::GetCompiler(), block);
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree node type for linear IR form
- */
-
-int cTreeTypeIR(Compiler* comp, GenTree* tree)
-{
- int chars = 0;
-
- var_types type = tree->TypeGet();
-
- const char* typeName = varTypeName(type);
- chars += printf(".%s", typeName);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree node type for linear IR form
- */
-
-int dTreeTypeIR(GenTree* tree)
-{
- int chars = cTreeTypeIR(JitTls::GetCompiler(), tree);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree node kind for linear IR form
- */
-
-int cTreeKindsIR(Compiler* comp, GenTree* tree)
-{
- int chars = 0;
-
- unsigned kind = tree->OperKind();
-
- chars += printf("kinds=");
- if (kind == GTK_SPECIAL)
- {
- chars += printf("[SPECIAL]");
- }
- if (kind & GTK_CONST)
- {
- chars += printf("[CONST]");
- }
- if (kind & GTK_LEAF)
- {
- chars += printf("[LEAF]");
- }
- if (kind & GTK_UNOP)
- {
- chars += printf("[UNOP]");
- }
- if (kind & GTK_BINOP)
- {
- chars += printf("[BINOP]");
- }
- if (kind & GTK_LOGOP)
- {
- chars += printf("[LOGOP]");
- }
- if (kind & GTK_COMMUTE)
- {
- chars += printf("[COMMUTE]");
- }
- if (kind & GTK_EXOP)
- {
- chars += printf("[EXOP]");
- }
- if (kind & GTK_LOCAL)
- {
- chars += printf("[LOCAL]");
- }
- if (kind & GTK_SMPOP)
- {
- chars += printf("[SMPOP]");
- }
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree node kind for linear IR form
- */
-
-int dTreeKindsIR(GenTree* tree)
-{
- int chars = cTreeKindsIR(JitTls::GetCompiler(), tree);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree node flags for linear IR form
- */
-
-int cTreeFlagsIR(Compiler* comp, GenTree* tree)
-{
- int chars = 0;
-
- if (tree->gtFlags != 0)
- {
- chars += printf("flags=");
-
- // Node flags
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#if defined(DEBUG)
- if (comp->dumpIRNodes)
- {
- if (tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE)
- {
- chars += printf("[NODE_LARGE]");
- }
- if (tree->gtDebugFlags & GTF_DEBUG_NODE_SMALL)
- {
- chars += printf("[NODE_SMALL]");
- }
- }
- if (tree->gtDebugFlags & GTF_DEBUG_NODE_MORPHED)
- {
- chars += printf("[MORPHED]");
- }
-#endif // defined(DEBUG)
-
- if (tree->gtFlags & GTF_COLON_COND)
- {
- chars += printf("[COLON_COND]");
- }
-
- // Operator flags
-
- genTreeOps op = tree->OperGet();
- switch (op)
- {
+ genTreeOps op = tree->OperGet();
+ switch (op)
+ {
case GT_LCL_VAR:
case GT_LCL_VAR_ADDR:
}
}
}
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree node flags for linear IR form
- */
-
-int dTreeFlagsIR(GenTree* tree)
-{
- int chars = cTreeFlagsIR(JitTls::GetCompiler(), tree);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out SSA number on tree node for linear IR form
- */
-
-int cSsaNumIR(Compiler* comp, GenTree* tree)
-{
- int chars = 0;
-
- if (tree->AsLclVarCommon()->HasSsaName())
- {
- if (tree->gtFlags & GTF_VAR_USEASG)
- {
- assert(tree->gtFlags & GTF_VAR_DEF);
- chars += printf("<u:%d><d:%d>", tree->AsLclVarCommon()->GetSsaNum(), comp->GetSsaNumForLocalVarDef(tree));
- }
- else
- {
- chars += printf("<%s:%d>", (tree->gtFlags & GTF_VAR_DEF) ? "d" : "u", tree->AsLclVarCommon()->GetSsaNum());
- }
- }
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out SSA number on tree node for linear IR form
- */
-
-int dSsaNumIR(GenTree* tree)
-{
- int chars = cSsaNumIR(JitTls::GetCompiler(), tree);
-
- return chars;
}
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out Value Number on tree node for linear IR form
- */
-
-int cValNumIR(Compiler* comp, GenTree* tree)
-{
- int chars = 0;
-
- if (tree->gtVNPair.GetLiberal() != ValueNumStore::NoVN)
- {
- assert(tree->gtVNPair.GetConservative() != ValueNumStore::NoVN);
- ValueNumPair vnp = tree->gtVNPair;
- ValueNum vn;
- if (vnp.BothEqual())
- {
- chars += printf("<v:");
- vn = vnp.GetLiberal();
- chars += printf(FMT_VN, vn);
- if (ValueNumStore::isReservedVN(vn))
- {
- chars += printf("R");
- }
- chars += printf(">");
- }
- else
- {
- vn = vnp.GetLiberal();
- chars += printf("<v:");
- chars += printf(FMT_VN, vn);
- if (ValueNumStore::isReservedVN(vn))
- {
- chars += printf("R");
- }
- chars += printf(",");
- vn = vnp.GetConservative();
- chars += printf(FMT_VN, vn);
- if (ValueNumStore::isReservedVN(vn))
- {
- chars += printf("R");
- }
- chars += printf(">");
- }
- }
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out Value Number on tree node for linear IR form
- */
-
-int dValNumIR(GenTree* tree)
-{
- int chars = cValNumIR(JitTls::GetCompiler(), tree);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree leaf node for linear IR form
- */
-
-int cLeafIR(Compiler* comp, GenTree* tree)
-{
- int chars = 0;
- genTreeOps op = tree->OperGet();
- const char* ilKind = nullptr;
- const char* ilName = nullptr;
- unsigned ilNum = 0;
- unsigned lclNum = 0;
- bool hasSsa = false;
-
- switch (op)
- {
-
- case GT_PHI_ARG:
- case GT_LCL_VAR:
- case GT_LCL_VAR_ADDR:
- case GT_STORE_LCL_VAR:
- lclNum = tree->AsLclVarCommon()->GetLclNum();
- comp->gtGetLclVarNameInfo(lclNum, &ilKind, &ilName, &ilNum);
- if (ilName != nullptr)
- {
- chars += printf("%s", ilName);
- }
- else
- {
- LclVarDsc* varDsc = comp->lvaTable + lclNum;
- chars += printf("%s%d", ilKind, ilNum);
- if (comp->dumpIRLocals)
- {
- chars += printf("(V%02u", lclNum);
- if (varDsc->lvTracked)
- {
- chars += printf(":T%02u", varDsc->lvVarIndex);
- }
- if (comp->dumpIRRegs)
- {
- if (varDsc->lvRegister)
- {
- chars += printf(":%s", getRegName(varDsc->GetRegNum()));
- }
- else
- {
- switch (tree->GetRegTag())
- {
- case GenTree::GT_REGTAG_REG:
- chars += printf(":%s", comp->compRegVarName(tree->GetRegNum()));
- break;
- default:
- break;
- }
- }
- }
- chars += printf(")");
- }
- else if (comp->dumpIRRegs)
- {
- if (varDsc->lvRegister)
- {
- chars += printf("(%s)", getRegName(varDsc->GetRegNum()));
- }
- else
- {
- switch (tree->GetRegTag())
- {
- case GenTree::GT_REGTAG_REG:
- chars += printf("(%s)", comp->compRegVarName(tree->GetRegNum()));
- break;
- default:
- break;
- }
- }
- }
- }
-
- hasSsa = true;
- break;
-
- case GT_LCL_FLD:
- case GT_LCL_FLD_ADDR:
- case GT_STORE_LCL_FLD:
-
- lclNum = tree->AsLclVarCommon()->GetLclNum();
- comp->gtGetLclVarNameInfo(lclNum, &ilKind, &ilName, &ilNum);
- if (ilName != nullptr)
- {
- chars += printf("%s+%u", ilName, tree->AsLclFld()->GetLclOffs());
- }
- else
- {
- chars += printf("%s%d+%u", ilKind, ilNum, tree->AsLclFld()->GetLclOffs());
- LclVarDsc* varDsc = comp->lvaTable + lclNum;
- if (comp->dumpIRLocals)
- {
- chars += printf("(V%02u", lclNum);
- if (varDsc->lvTracked)
- {
- chars += printf(":T%02u", varDsc->lvVarIndex);
- }
- if (comp->dumpIRRegs)
- {
- if (varDsc->lvRegister)
- {
- chars += printf(":%s", getRegName(varDsc->GetRegNum()));
- }
- else
- {
- switch (tree->GetRegTag())
- {
- case GenTree::GT_REGTAG_REG:
- chars += printf(":%s", comp->compRegVarName(tree->GetRegNum()));
- break;
- default:
- break;
- }
- }
- }
- chars += printf(")");
- }
- else if (comp->dumpIRRegs)
- {
- if (varDsc->lvRegister)
- {
- chars += printf("(%s)", getRegName(varDsc->GetRegNum()));
- }
- else
- {
- switch (tree->GetRegTag())
- {
- case GenTree::GT_REGTAG_REG:
- chars += printf("(%s)", comp->compRegVarName(tree->GetRegNum()));
- break;
- default:
- break;
- }
- }
- }
- }
-
- // TODO: We probably want to expand field sequence.
- // gtDispFieldSeq(tree->AsLclFld()->gtFieldSeq);
-
- hasSsa = true;
- break;
-
- case GT_CNS_INT:
-
- if (tree->IsIconHandle())
- {
-#if 0
- // TODO: Commented out because sometimes the CLR throws
- // and exception when asking the names of some handles.
- // Need to investigate.
-
- const char* className;
- const char* fieldName;
- const char* methodName;
- const WCHAR* str;
-
- switch (tree->GetIconHandleFlag())
- {
-
- case GTF_ICON_SCOPE_HDL:
-
- chars += printf("SCOPE(?)");
- break;
-
- case GTF_ICON_CLASS_HDL:
-
- className = comp->eeGetClassName((CORINFO_CLASS_HANDLE)tree->AsIntCon()->gtIconVal);
- chars += printf("CLASS(%s)", className);
- break;
-
- case GTF_ICON_METHOD_HDL:
-
- methodName = comp->eeGetMethodName((CORINFO_METHOD_HANDLE)tree->AsIntCon()->gtIconVal,
- &className);
- chars += printf("METHOD(%s.%s)", className, methodName);
- break;
-
- case GTF_ICON_FIELD_HDL:
-
- fieldName = comp->eeGetFieldName((CORINFO_FIELD_HANDLE)tree->AsIntCon()->gtIconVal,
- &className);
- chars += printf("FIELD(%s.%s) ", className, fieldName);
- break;
-
- case GTF_ICON_STATIC_HDL:
-
- fieldName = comp->eeGetFieldName((CORINFO_FIELD_HANDLE)tree->AsIntCon()->gtIconVal,
- &className);
- chars += printf("STATIC_FIELD(%s.%s)", className, fieldName);
- break;
-
- case GTF_ICON_STR_HDL:
-
- str = comp->eeGetCPString(tree->AsIntCon()->gtIconVal);
- chars += printf("\"%S\"", str);
- break;
-
- case GTF_ICON_PSTR_HDL:
-
- chars += printf("PSTR(?)");
- break;
-
- case GTF_ICON_PTR_HDL:
-
- chars += printf("PTR(?)");
- break;
-
- case GTF_ICON_VARG_HDL:
-
- chars += printf("VARARG(?)");
- break;
-
- case GTF_ICON_PINVKI_HDL:
-
- chars += printf("PINVOKE(?)");
- break;
-
- case GTF_ICON_TOKEN_HDL:
-
- chars += printf("TOKEN(%08X)", tree->AsIntCon()->gtIconVal);
- break;
-
- case GTF_ICON_TLS_HDL:
-
- chars += printf("TLS(?)");
- break;
-
- case GTF_ICON_FTN_ADDR:
-
- chars += printf("FTN(?)");
- break;
-
- case GTF_ICON_CIDMID_HDL:
-
- chars += printf("CIDMID(?)");
- break;
-
- case GTF_ICON_BBC_PTR:
-
- chars += printf("BBC(?)");
- break;
-
- default:
-
- chars += printf("HANDLE(?)");
- break;
- }
-#else
-#ifdef _TARGET_64BIT_
- if ((tree->AsIntCon()->gtIconVal & 0xFFFFFFFF00000000LL) != 0)
- {
- chars += printf("HANDLE(0x%llx)", dspPtr(tree->AsIntCon()->gtIconVal));
- }
- else
-#endif
- {
- chars += printf("HANDLE(0x%0x)", dspPtr(tree->AsIntCon()->gtIconVal));
- }
-#endif
- }
- else
- {
- if (tree->TypeGet() == TYP_REF)
- {
- assert(tree->AsIntCon()->gtIconVal == 0);
- chars += printf("null");
- }
-#ifdef _TARGET_64BIT_
- else if ((tree->AsIntCon()->gtIconVal & 0xFFFFFFFF00000000LL) != 0)
- {
- chars += printf("0x%llx", tree->AsIntCon()->gtIconVal);
- }
- else
-#endif
- {
- chars += printf("%ld(0x%x)", tree->AsIntCon()->gtIconVal, tree->AsIntCon()->gtIconVal);
- }
- }
- break;
-
- case GT_CNS_LNG:
-
- chars += printf("CONST(LONG)");
- break;
-
- case GT_CNS_DBL:
-
- chars += printf("CONST(DOUBLE)");
- break;
-
- case GT_CNS_STR:
-
- chars += printf("CONST(STR)");
- break;
-
- case GT_JMP:
-
- {
- const char* methodName;
- const char* className;
-
- methodName = comp->eeGetMethodName((CORINFO_METHOD_HANDLE)tree->AsVal()->gtVal1, &className);
- chars += printf(" %s.%s", className, methodName);
- }
- break;
-
- case GT_NO_OP:
- case GT_START_NONGC:
- case GT_START_PREEMPTGC:
- case GT_PROF_HOOK:
- case GT_CATCH_ARG:
- case GT_MEMORYBARRIER:
- case GT_ARGPLACE:
- case GT_PINVOKE_PROLOG:
- case GT_JMPTABLE:
- // Do nothing.
- break;
-
- case GT_RET_EXPR:
-
- chars += printf("t%d", tree->AsRetExpr()->gtInlineCandidate->gtTreeID);
- break;
-
- case GT_PHYSREG:
-
- chars += printf("%s", getRegName(tree->AsPhysReg()->gtSrcReg, varTypeIsFloating(tree)));
- break;
-
- case GT_LABEL:
- break;
-
- case GT_IL_OFFSET:
-
- if (tree->AsILOffset()->gtStmtILoffsx == BAD_IL_OFFSET)
- {
- chars += printf("?");
- }
- else
- {
- chars += printf("0x%x", jitGetILoffs(tree->AsILOffset()->gtStmtILoffsx));
- }
- break;
-
- case GT_CLS_VAR:
- case GT_CLS_VAR_ADDR:
- default:
-
- if (tree->OperIsLeaf())
- {
- chars += printf("<leaf nyi: %s>", tree->OpName(tree->OperGet()));
- }
-
- chars += printf("t%d", tree->gtTreeID);
- break;
- }
-
- if (comp->dumpIRTypes)
- {
- chars += cTreeTypeIR(comp, tree);
- }
- if (comp->dumpIRValnums)
- {
- chars += cValNumIR(comp, tree);
- }
- if (hasSsa && comp->dumpIRSsa)
- {
- chars += cSsaNumIR(comp, tree);
- }
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree leaf node for linear IR form
- */
-
-int dLeafIR(GenTree* tree)
-{
- int chars = cLeafIR(JitTls::GetCompiler(), tree);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree indir node for linear IR form
- */
-
-int cIndirIR(Compiler* comp, GenTree* tree)
-{
- assert(tree->gtOper == GT_IND);
-
- int chars = 0;
- GenTree* child;
-
- chars += printf("[");
- child = tree->GetChild(0);
- chars += cLeafIR(comp, child);
- chars += printf("]");
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree indir node for linear IR form
- */
-
-int dIndirIR(GenTree* tree)
-{
- int chars = cIndirIR(JitTls::GetCompiler(), tree);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree operand node for linear IR form
- */
-
-int cOperandIR(Compiler* comp, GenTree* operand)
-{
- int chars = 0;
-
- if (operand == nullptr)
- {
- chars += printf("t?");
- return chars;
- }
-
- bool dumpTypes = comp->dumpIRTypes;
- bool dumpValnums = comp->dumpIRValnums;
- bool foldIndirs = comp->dumpIRDataflow;
- bool foldLeafs = comp->dumpIRNoLeafs;
- bool foldCommas = comp->dumpIRDataflow;
- bool dumpDataflow = comp->dumpIRDataflow;
- bool foldLists = comp->dumpIRNoLists;
- bool dumpRegs = comp->dumpIRRegs;
-
- genTreeOps op = operand->OperGet();
-
- if (foldLeafs && operand->OperIsLeaf())
- {
- if ((op == GT_ARGPLACE) && foldLists)
- {
- return chars;
- }
- chars += cLeafIR(comp, operand);
- }
- else if (dumpDataflow && (operand->OperIs(GT_ASG) || (op == GT_STORE_LCL_VAR) || (op == GT_STORE_LCL_FLD)))
- {
- operand = operand->GetChild(0);
- chars += cOperandIR(comp, operand);
- }
- else if ((op == GT_INDEX) && foldIndirs)
- {
- chars += printf("[t%d]", operand->gtTreeID);
- if (dumpTypes)
- {
- chars += cTreeTypeIR(comp, operand);
- }
- if (dumpValnums)
- {
- chars += cValNumIR(comp, operand);
- }
- }
- else if ((op == GT_IND) && foldIndirs)
- {
- chars += cIndirIR(comp, operand);
- if (dumpTypes)
- {
- chars += cTreeTypeIR(comp, operand);
- }
- if (dumpValnums)
- {
- chars += cValNumIR(comp, operand);
- }
- }
- else if ((op == GT_COMMA) && foldCommas)
- {
- operand = operand->GetChild(1);
- chars += cOperandIR(comp, operand);
- }
- else if ((op == GT_LIST) && foldLists)
- {
- GenTree* list = operand;
- unsigned childCount = list->NumChildren();
-
- operand = list->GetChild(0);
- int operandChars = cOperandIR(comp, operand);
- chars += operandChars;
- if (childCount > 1)
- {
- if (operandChars > 0)
- {
- chars += printf(", ");
- }
- operand = list->GetChild(1);
- if (operand->gtOper == GT_LIST)
- {
- chars += cListIR(comp, operand);
- }
- else
- {
- chars += cOperandIR(comp, operand);
- }
- }
- }
- else
- {
- chars += printf("t%d", operand->gtTreeID);
- if (dumpRegs)
- {
- regNumber regNum = operand->GetReg();
- if (regNum != REG_NA)
- {
- chars += printf("(%s)", getRegName(regNum));
- }
- }
- if (dumpTypes)
- {
- chars += cTreeTypeIR(comp, operand);
- }
- if (dumpValnums)
- {
- chars += cValNumIR(comp, operand);
- }
- }
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree operand node for linear IR form
- */
-
-int dOperandIR(GenTree* operand)
-{
- int chars = cOperandIR(JitTls::GetCompiler(), operand);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree list of nodes for linear IR form
- */
-
-int cListIR(Compiler* comp, GenTree* list)
-{
- int chars = 0;
- int operandChars;
-
- assert(list->gtOper == GT_LIST);
-
- GenTree* child;
- unsigned childCount;
-
- childCount = list->NumChildren();
- assert(childCount == 1 || childCount == 2);
-
- operandChars = 0;
- for (unsigned childIndex = 0; childIndex < childCount; childIndex++)
- {
- if ((childIndex > 0) && (operandChars > 0))
- {
- chars += printf(", ");
- }
-
- child = list->GetChild(childIndex);
- operandChars = cOperandIR(comp, child);
- chars += operandChars;
- }
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree list of nodes for linear IR form
- */
-
-int dListIR(GenTree* list)
-{
- int chars = cListIR(JitTls::GetCompiler(), list);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree dependencies based on comma nodes for linear IR form
- */
-
-int cDependsIR(Compiler* comp, GenTree* comma, bool* first)
-{
- int chars = 0;
-
- assert(comma->gtOper == GT_COMMA);
-
- GenTree* child;
-
- child = comma->GetChild(0);
- if (child->gtOper == GT_COMMA)
- {
- chars += cDependsIR(comp, child, first);
- }
- else
- {
- if (!(*first))
- {
- chars += printf(", ");
- }
- chars += printf("t%d", child->gtTreeID);
- *first = false;
- }
-
- child = comma->GetChild(1);
- if (child->gtOper == GT_COMMA)
- {
- chars += cDependsIR(comp, child, first);
- }
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree dependencies based on comma nodes for linear IR form
- */
-
-int dDependsIR(GenTree* comma)
-{
- int chars = 0;
- bool first = TRUE;
-
- chars = cDependsIR(JitTls::GetCompiler(), comma, &first);
-
- return chars;
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree node in linear IR form
- */
-
-void cNodeIR(Compiler* comp, GenTree* tree)
-{
- bool foldLeafs = comp->dumpIRNoLeafs;
- bool foldIndirs = comp->dumpIRDataflow;
- bool foldLists = comp->dumpIRNoLists;
- bool dataflowView = comp->dumpIRDataflow;
- bool dumpTypes = comp->dumpIRTypes;
- bool dumpValnums = comp->dumpIRValnums;
- bool noStmts = comp->dumpIRNoStmts;
- genTreeOps op = tree->OperGet();
- unsigned childCount = tree->NumChildren();
- GenTree* child;
-
- // What are we skipping?
-
- if (tree->OperIsLeaf())
- {
- if (foldLeafs)
- {
- return;
- }
- }
- else if (op == GT_IND)
- {
- if (foldIndirs)
- {
- return;
- }
- }
- else if (op == GT_LIST)
- {
- if (foldLists)
- {
- return;
- }
- }
- else if (op == GT_COMMA)
- {
- if (dataflowView)
- {
- return;
- }
- }
-
- bool nodeIsValue = tree->IsValue();
-
- // Dump tree id or dataflow destination.
-
- int chars = 0;
-
- // if (comp->compRationalIRForm)
- // {
- // chars += printf("R");
- // }
-
- chars += printf(" ");
- if (dataflowView && tree->OperIs(GT_ASG))
- {
- child = tree->GetChild(0);
- chars += cOperandIR(comp, child);
- }
- else if (dataflowView && ((op == GT_STORE_LCL_VAR) || (op == GT_STORE_LCL_FLD)))
- {
- chars += cLeafIR(comp, tree);
- }
- else if (dataflowView && (op == GT_STOREIND))
- {
- child = tree->GetChild(0);
- chars += printf("[");
- chars += cOperandIR(comp, child);
- chars += printf("]");
- if (dumpTypes)
- {
- chars += cTreeTypeIR(comp, tree);
- }
- if (dumpValnums)
- {
- chars += cValNumIR(comp, tree);
- }
- }
- else if (nodeIsValue)
- {
- chars += printf("t%d", tree->gtTreeID);
- if (comp->dumpIRRegs)
- {
- regNumber regNum = tree->GetReg();
- if (regNum != REG_NA)
- {
- chars += printf("(%s)", getRegName(regNum));
- }
- }
- if (dumpTypes)
- {
- chars += cTreeTypeIR(comp, tree);
- }
- if (dumpValnums)
- {
- chars += cValNumIR(comp, tree);
- }
- }
-
- // Dump opcode and tree ID if need in dataflow view.
-
- chars += dTabStopIR(chars, COLUMN_OPCODE);
- const char* opName = tree->OpName(op);
- chars += printf(" %c %s", nodeIsValue ? '=' : ' ', opName);
-
- if (dataflowView)
- {
- if (tree->OperIs(GT_ASG) || (op == GT_STORE_LCL_VAR) || (op == GT_STORE_LCL_FLD) || (op == GT_STOREIND))
- {
- chars += printf("(t%d)", tree->gtTreeID);
- }
- }
-
- // Dump modifiers for opcodes to help with readability
-
- if (op == GT_CALL)
- {
- GenTreeCall* call = tree->AsCall();
-
- if (call->gtCallType == CT_USER_FUNC)
- {
- if (call->IsVirtualStub())
- {
- chars += printf(":VS");
- }
- else if (call->IsVirtualVtable())
- {
- chars += printf(":VT");
- }
- else if (call->IsVirtual())
- {
- chars += printf(":V");
- }
- }
- else if (call->gtCallType == CT_HELPER)
- {
- chars += printf(":H");
- }
- else if (call->gtCallType == CT_INDIRECT)
- {
- chars += printf(":I");
- }
- else if (call->IsUnmanaged())
- {
- chars += printf(":U");
- }
- else
- {
- if (call->IsVirtualStub())
- {
- chars += printf(":XVS");
- }
- else if (call->IsVirtualVtable())
- {
- chars += printf(":XVT");
- }
- else
- {
- chars += printf(":?");
- }
- }
-
- if (call->IsUnmanaged())
- {
- if (call->gtCallMoreFlags & GTF_CALL_M_UNMGD_THISCALL)
- {
- chars += printf(":T");
- }
- }
-
- if (tree->gtFlags & GTF_CALL_NULLCHECK)
- {
- chars += printf(":N");
- }
- }
- else if (op == GT_INTRINSIC)
- {
- CorInfoIntrinsics intrin = tree->AsIntrinsic()->gtIntrinsicId;
-
- chars += printf(":");
- switch (intrin)
- {
- case CORINFO_INTRINSIC_Sin:
- chars += printf("Sin");
- break;
- case CORINFO_INTRINSIC_Cos:
- chars += printf("Cos");
- break;
- case CORINFO_INTRINSIC_Cbrt:
- chars += printf("Cbrt");
- break;
- case CORINFO_INTRINSIC_Sqrt:
- chars += printf("Sqrt");
- break;
- case CORINFO_INTRINSIC_Cosh:
- chars += printf("Cosh");
- break;
- case CORINFO_INTRINSIC_Sinh:
- chars += printf("Sinh");
- break;
- case CORINFO_INTRINSIC_Tan:
- chars += printf("Tan");
- break;
- case CORINFO_INTRINSIC_Tanh:
- chars += printf("Tanh");
- break;
- case CORINFO_INTRINSIC_Asin:
- chars += printf("Asin");
- break;
- case CORINFO_INTRINSIC_Asinh:
- chars += printf("Asinh");
- break;
- case CORINFO_INTRINSIC_Acos:
- chars += printf("Acos");
- break;
- case CORINFO_INTRINSIC_Acosh:
- chars += printf("Acosh");
- break;
- case CORINFO_INTRINSIC_Atan:
- chars += printf("Atan");
- break;
- case CORINFO_INTRINSIC_Atan2:
- chars += printf("Atan2");
- break;
- case CORINFO_INTRINSIC_Atanh:
- chars += printf("Atanh");
- break;
- case CORINFO_INTRINSIC_Log10:
- chars += printf("Log10");
- break;
- case CORINFO_INTRINSIC_Pow:
- chars += printf("Pow");
- break;
- case CORINFO_INTRINSIC_Exp:
- chars += printf("Exp");
- break;
- case CORINFO_INTRINSIC_Ceiling:
- chars += printf("Ceiling");
- break;
- case CORINFO_INTRINSIC_Floor:
- chars += printf("Floor");
- break;
- default:
- chars += printf("unknown(%d)", intrin);
- break;
- }
- }
-
- // Dump operands.
-
- chars += dTabStopIR(chars, COLUMN_OPERANDS);
-
- // Dump operator specific fields as operands
-
- switch (op)
- {
- default:
- break;
- case GT_FIELD:
-
- {
- const char* className = nullptr;
- const char* fieldName = comp->eeGetFieldName(tree->AsField()->gtFldHnd, &className);
-
- chars += printf(" %s.%s", className, fieldName);
- }
- break;
-
- case GT_CALL:
-
- if (tree->AsCall()->gtCallType != CT_INDIRECT)
- {
- const char* methodName;
- const char* className;
-
- methodName = comp->eeGetMethodName(tree->AsCall()->gtCallMethHnd, &className);
-
- chars += printf(" %s.%s", className, methodName);
- }
- break;
-
- case GT_STORE_LCL_VAR:
- case GT_STORE_LCL_FLD:
-
- if (!dataflowView)
- {
- chars += printf(" ");
- chars += cLeafIR(comp, tree);
- }
- break;
-
- case GT_LEA:
-
- GenTreeAddrMode* lea = tree->AsAddrMode();
- GenTree* base = lea->Base();
- GenTree* index = lea->Index();
- unsigned scale = lea->gtScale;
- int offset = lea->Offset();
-
- chars += printf(" [");
- if (base != nullptr)
- {
- chars += cOperandIR(comp, base);
- }
- if (index != nullptr)
- {
- if (base != nullptr)
- {
- chars += printf("+");
- }
- chars += cOperandIR(comp, index);
- if (scale > 1)
- {
- chars += printf("*%u", scale);
- }
- }
- if ((offset != 0) || ((base == nullptr) && (index == nullptr)))
- {
- if ((base != nullptr) || (index != nullptr))
- {
- chars += printf("+");
- }
- chars += printf("%d", offset);
- }
- chars += printf("]");
- break;
- }
-
- // Dump operands.
-
- if (tree->OperIsLeaf())
- {
- chars += printf(" ");
- chars += cLeafIR(comp, tree);
- }
- else if (op == GT_LEA)
- {
- // Already dumped it above.
- }
- else if (op == GT_PHI)
- {
- bool first = true;
- for (GenTreePhi::Use& use : tree->AsPhi()->Uses())
- {
- child = use.GetNode();
- if (!first)
- {
- chars += printf(",");
- }
- first = false;
- chars += printf(" ");
- chars += cOperandIR(comp, child);
- }
- }
- else
- {
- bool hasComma = false;
- bool first = true;
- int operandChars = 0;
- for (unsigned childIndex = 0; childIndex < childCount; childIndex++)
- {
- child = tree->GetChild(childIndex);
- if (child == nullptr)
- {
- continue;
- }
-
- if (child->gtOper == GT_COMMA)
- {
- hasComma = true;
- }
-
- if (dataflowView && (childIndex == 0))
- {
- if ((op == GT_ASG) || (op == GT_STOREIND))
- {
- continue;
- }
- }
-
- if (!first)
- {
- chars += printf(",");
- }
-
- bool isList = (child->gtOper == GT_LIST);
- if (!isList || !foldLists)
- {
- if (foldLeafs && (child->gtOper == GT_ARGPLACE))
- {
- continue;
- }
- chars += printf(" ");
- operandChars = cOperandIR(comp, child);
- chars += operandChars;
- if (operandChars > 0)
- {
- first = false;
- }
- }
- else
- {
- assert(isList);
- chars += printf(" ");
- operandChars = cOperandIR(comp, child);
- chars += operandChars;
- if (operandChars > 0)
- {
- first = false;
- }
- }
- }
-
- if (dataflowView && hasComma)
- {
- chars += printf(", DEPS(");
- first = true;
- for (unsigned childIndex = 0; childIndex < childCount; childIndex++)
- {
- child = tree->GetChild(childIndex);
- if (child->gtOper == GT_COMMA)
- {
- chars += cDependsIR(comp, child, &first);
- }
- }
- chars += printf(")");
- }
- }
-
- // Dump kinds, flags, costs
-
- if (comp->dumpIRKinds || comp->dumpIRFlags || comp->dumpIRCosts)
- {
- chars += dTabStopIR(chars, COLUMN_KINDS);
- chars += printf(";");
- if (comp->dumpIRKinds)
- {
- chars += printf(" ");
- chars += cTreeKindsIR(comp, tree);
- }
- if (comp->dumpIRFlags && (tree->gtFlags != 0))
- {
- if (comp->dumpIRKinds)
- {
- chars += dTabStopIR(chars, COLUMN_FLAGS);
- }
- else
- {
- chars += printf(" ");
- }
- chars += cTreeFlagsIR(comp, tree);
- }
- if (comp->dumpIRCosts && (tree->gtCostsInitialized))
- {
- chars += printf(" CostEx=%d, CostSz=%d", tree->GetCostEx(), tree->GetCostSz());
- }
- }
-
- printf("\n");
-}
-
-void cStmtIR(Compiler* comp, Statement* stmt)
-{
- cTreeIR(comp, stmt->GetRootNode());
- if (!comp->dumpIRNoStmts)
- {
- dTabStopIR(0, COLUMN_OPCODE);
- Compiler::printStmtID(stmt);
- }
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree in linear IR form
- */
-
-void cTreeIR(Compiler* comp, GenTree* tree)
-{
- genTreeOps op = tree->OperGet();
- unsigned childCount = tree->NumChildren();
- GenTree* child;
-
- // Recurse and dump trees that this node depends on.
-
- if (tree->OperIsLeaf())
- {
- }
- else if (tree->OperIsBinary() && tree->IsReverseOp())
- {
- child = tree->GetChild(1);
- cTreeIR(comp, child);
- child = tree->GetChild(0);
- cTreeIR(comp, child);
- }
- else if (op == GT_PHI)
- {
- // Don't recurse.
- }
- else
- {
- assert(!tree->IsReverseOp());
- for (unsigned childIndex = 0; childIndex < childCount; childIndex++)
- {
- child = tree->GetChild(childIndex);
- if (child != nullptr)
- {
- cTreeIR(comp, child);
- }
- }
- }
-
- cNodeIR(comp, tree);
-}
-
-/*****************************************************************************
- *
- * COMPlus_JitDumpIR support - dump out tree in linear IR form
- */
-
-void dTreeIR(GenTree* tree)
+void dTreeFlags(GenTree* tree)
{
- cTreeIR(JitTls::GetCompiler(), tree);
+ cTreeFlags(JitTls::GetCompiler(), tree);
}
#endif // DEBUG