* The versions that start with 'd' use the tlsCompiler, so don't require a Compiler*.
*
* Summary:
- * cBlock, dBlock : Display a basic block (call fgDispBasicBlock()).
+ * cBlock, dBlock : Display a basic block (call fgTableDispBasicBlock()).
* cBlocks, dBlocks : Display all the basic blocks of a function (call fgDispBasicBlocks()).
* cBlocksV, dBlocksV : Display all the basic blocks of a function (call fgDispBasicBlocks(true)).
* "V" means "verbose", and will dump all the trees.
* cTree, dTree : Display a tree (call gtDispTree()).
+ * cTreeLIR, dTreeLIR : Display a tree in LIR form (call gtDispLIRNode()).
* cTrees, dTrees : Display all the trees in a function (call fgDumpTrees()).
* cEH, dEH : Display the EH handler table (call fgDispHandlerTab()).
* cVar, dVar : Display a local variable given its number (call lvaDumpEntry()).
comp->gtDispTree(tree, nullptr, ">>>");
}
+void cTreeLIR(Compiler* comp, GenTree* tree)
+{
+ static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
+ printf("===================================================================== *TreeLIR %u\n", sequenceNumber++);
+ comp->gtDispLIRNode(tree);
+}
+
void cTrees(Compiler* comp)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
cTree(JitTls::GetCompiler(), tree);
}
+void dTreeLIR(GenTree* tree)
+{
+ cTreeLIR(JitTls::GetCompiler(), tree);
+}
+
void dTrees()
{
cTrees(JitTls::GetCompiler());
//
// Arguments:
// node - the LIR node to dump.
+// prefixMsg - an optional prefix for each line of output.
//
-void Compiler::gtDispLIRNode(GenTree* node)
+void Compiler::gtDispLIRNode(GenTree* node, const char* prefixMsg /* = nullptr */)
{
- auto displayOperand = [](GenTree* operand, const char* message, IndentInfo operandArc, IndentStack& indentStack) {
+ auto displayOperand = [](GenTree* operand, const char* message, IndentInfo operandArc, IndentStack& indentStack,
+ size_t prefixIndent = 0) {
assert(operand != nullptr);
assert(message != nullptr);
+ if (prefixIndent != 0)
+ {
+ printf("%*s", (int)prefixIndent, "");
+ }
+
// 49 spaces for alignment
printf("%-49s", "");
-#ifdef FEATURE_SET_FLAGS
+#if FEATURE_SET_FLAGS
// additional flag enlarges the flag field by one character
printf(" ");
#endif
operandArc = IIArc;
printf(" t%-5d %-6s %s\n", operand->gtTreeID, varTypeName(operand->TypeGet()), message);
-
};
IndentStack indentStack(this);
+ size_t prefixIndent = 0;
+ if (prefixMsg != nullptr)
+ {
+ prefixIndent = strlen(prefixMsg);
+ }
+
const int bufLength = 256;
char buf[bufLength];
if (operand == call->gtCallObjp)
{
sprintf_s(buf, sizeof(buf), "this in %s", compRegVarName(REG_ARG_0));
- displayOperand(operand, buf, operandArc, indentStack);
+ displayOperand(operand, buf, operandArc, indentStack, prefixIndent);
}
else if (operand == call->gtCallAddr)
{
- displayOperand(operand, "calli tgt", operandArc, indentStack);
+ displayOperand(operand, "calli tgt", operandArc, indentStack, prefixIndent);
}
else if (operand == call->gtControlExpr)
{
- displayOperand(operand, "control expr", operandArc, indentStack);
+ displayOperand(operand, "control expr", operandArc, indentStack, prefixIndent);
}
else if (operand == call->gtCallCookie)
{
- displayOperand(operand, "cookie", operandArc, indentStack);
+ displayOperand(operand, "cookie", operandArc, indentStack, prefixIndent);
}
else
{
gtGetLateArgMsg(call, operand, curArgTabEntry->lateArgInx, listIndex, buf, sizeof(buf));
}
- displayOperand(operand, buf, operandArc, indentStack);
+ displayOperand(operand, buf, operandArc, indentStack, prefixIndent);
operandArc = IIArc;
}
}
gtGetLateArgMsg(call, operand, curArgTabEntry->lateArgInx, -1, buf, sizeof(buf));
}
- displayOperand(operand, buf, operandArc, indentStack);
+ displayOperand(operand, buf, operandArc, indentStack, prefixIndent);
}
}
}
{
if (operand == node->AsBlk()->Addr())
{
- displayOperand(operand, "lhs", operandArc, indentStack);
+ displayOperand(operand, "lhs", operandArc, indentStack, prefixIndent);
}
else if (operand == node->AsBlk()->Data())
{
- displayOperand(operand, "rhs", operandArc, indentStack);
+ displayOperand(operand, "rhs", operandArc, indentStack, prefixIndent);
}
else
{
assert(operand == node->AsDynBlk()->gtDynamicSize);
- displayOperand(operand, "size", operandArc, indentStack);
+ displayOperand(operand, "size", operandArc, indentStack, prefixIndent);
}
}
else if (node->OperGet() == GT_DYN_BLK)
{
if (operand == node->AsBlk()->Addr())
{
- displayOperand(operand, "lhs", operandArc, indentStack);
+ displayOperand(operand, "lhs", operandArc, indentStack, prefixIndent);
}
else
{
assert(operand == node->AsDynBlk()->gtDynamicSize);
- displayOperand(operand, "size", operandArc, indentStack);
+ displayOperand(operand, "size", operandArc, indentStack, prefixIndent);
}
}
else if (node->OperIsAssignment())
{
if (operand == node->gtGetOp1())
{
- displayOperand(operand, "lhs", operandArc, indentStack);
+ displayOperand(operand, "lhs", operandArc, indentStack, prefixIndent);
}
else
{
- displayOperand(operand, "rhs", operandArc, indentStack);
+ displayOperand(operand, "rhs", operandArc, indentStack, prefixIndent);
}
}
else
{
- displayOperand(operand, "", operandArc, indentStack);
+ displayOperand(operand, "", operandArc, indentStack, prefixIndent);
}
operandArc = IIArc;
}
// Visit the operator
+
+ if (prefixMsg != nullptr)
+ {
+ printf("%s", prefixMsg);
+ }
+
const bool topOnly = true;
const bool isLIR = true;
gtDispTree(node, &indentStack, nullptr, topOnly, isLIR);
-
- printf("\n");
}
/*****************************************************************************/