Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSingleAccretion <62474226+SingleAccretion@users.noreply.github.com>2021-07-09 00:14:21 +0300
committerGitHub <noreply@github.com>2021-07-09 00:14:21 +0300
commitf3b777546cceaeea7693b22a16bc08c797ec38bc (patch)
tree50918c3b0548152730a1003bf522ca8d4d349ea1 /src/coreclr/jit
parent24329262b88fd29951a7b561169c12e82c668b19 (diff)
Print indices of assertions instead of raw bitsets (#54928)
* Add JITDUMPEXEC macro For use in contexts where some printing method should only be executed when "verbose" is true. * Add helpers for printing assertion indexes * Print assertion indices instead of raw bitsets To aid in understanding what assertions are being propagated and merged when reading the dumps. * Don't print VNs for the same assertion twice * Also correctly print VNs in CopyProp * Align "in"s with "out"s for final assertions * Don't print the assertion dataflow in usual dumps It can still be enabled if needed.
Diffstat (limited to 'src/coreclr/jit')
-rw-r--r--src/coreclr/jit/assertionprop.cpp184
-rw-r--r--src/coreclr/jit/compiler.h5
-rw-r--r--src/coreclr/jit/copyprop.cpp4
-rw-r--r--src/coreclr/jit/jit.h6
-rw-r--r--src/coreclr/jit/rangecheck.cpp15
5 files changed, 160 insertions, 54 deletions
diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp
index 981879142bf..fb869c89fee 100644
--- a/src/coreclr/jit/assertionprop.cpp
+++ b/src/coreclr/jit/assertionprop.cpp
@@ -558,7 +558,7 @@ void Compiler::optAssertionInit(bool isLocalProp)
}
#ifdef DEBUG
-void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex assertionIndex /* =0 */)
+void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex assertionIndex /* = 0 */)
{
if (curAssertion->op1.kind == O1K_EXACT_TYPE)
{
@@ -590,10 +590,6 @@ void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex asse
printf("?assertion classification? ");
}
printf("Assertion: ");
- if (!optLocalAssertionProp)
- {
- printf("(%d, %d) ", curAssertion->op1.vn, curAssertion->op2.vn);
- }
if (!optLocalAssertionProp)
{
@@ -778,12 +774,67 @@ void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex asse
if (assertionIndex > 0)
{
- printf(" index=#%02u, mask=", assertionIndex);
- printf("%s", BitVecOps::ToString(apTraits, BitVecOps::MakeSingleton(apTraits, assertionIndex - 1)));
+ printf(", index = ");
+ optPrintAssertionIndex(assertionIndex);
}
printf("\n");
}
+
+void Compiler::optPrintAssertionIndex(AssertionIndex index)
+{
+ if (index == NO_ASSERTION_INDEX)
+ {
+ printf("#NA");
+ return;
+ }
+
+ printf("#%02u", index);
+}
+
+void Compiler::optPrintAssertionIndices(ASSERT_TP assertions)
+{
+ if (BitVecOps::IsEmpty(apTraits, assertions))
+ {
+ optPrintAssertionIndex(NO_ASSERTION_INDEX);
+ return;
+ }
+
+ BitVecOps::Iter iter(apTraits, assertions);
+ unsigned bitIndex = 0;
+ if (iter.NextElem(&bitIndex))
+ {
+ optPrintAssertionIndex(static_cast<AssertionIndex>(bitIndex + 1));
+ while (iter.NextElem(&bitIndex))
+ {
+ printf(" ");
+ optPrintAssertionIndex(static_cast<AssertionIndex>(bitIndex + 1));
+ }
+ }
+}
+#endif // DEBUG
+
+/* static */
+void Compiler::optDumpAssertionIndices(const char* header, ASSERT_TP assertions, const char* footer /* = nullptr */)
+{
+#ifdef DEBUG
+ Compiler* compiler = JitTls::GetCompiler();
+ if (compiler->verbose)
+ {
+ printf(header);
+ compiler->optPrintAssertionIndices(assertions);
+ if (footer != nullptr)
+ {
+ printf(footer);
+ }
+ }
#endif // DEBUG
+}
+
+/* static */
+void Compiler::optDumpAssertionIndices(ASSERT_TP assertions, const char* footer /* = nullptr */)
+{
+ optDumpAssertionIndices("", assertions, footer);
+}
/******************************************************************************
*
@@ -4511,7 +4562,7 @@ void Compiler::optImpliedByConstAssertion(AssertionDsc* constAssertion, ASSERT_T
if (verbose)
{
AssertionDsc* firstAssertion = optGetAssertion(1);
- printf("\nCompiler::optImpliedByConstAssertion: constAssertion #%02d , implies assertion #%02d",
+ printf("Compiler::optImpliedByConstAssertion: const assertion #%02d implies assertion #%02d\n",
(constAssertion - firstAssertion) + 1, (impAssertion - firstAssertion) + 1);
}
#endif
@@ -4721,8 +4772,12 @@ public:
// At the start of the merge function of the dataflow equations, initialize premerge state (to detect change.)
void StartMerge(BasicBlock* block)
{
- JITDUMP("AssertionPropCallback::StartMerge: " FMT_BB " in -> %s\n", block->bbNum,
- BitVecOps::ToString(apTraits, block->bbAssertionIn));
+ if (VerboseDataflow())
+ {
+ JITDUMP("StartMerge: " FMT_BB " ", block->bbNum);
+ Compiler::optDumpAssertionIndices("in -> ", block->bbAssertionIn, "\n");
+ }
+
BitVecOps::Assign(apTraits, preMergeOut, block->bbAssertionOut);
BitVecOps::Assign(apTraits, preMergeJumpDestOut, mJumpDestOut[block->bbNum]);
}
@@ -4743,11 +4798,14 @@ public:
assert(predBlock->bbNext == block);
BitVecOps::IntersectionD(apTraits, pAssertionOut, predBlock->bbAssertionOut);
- JITDUMP("AssertionPropCallback::Merge : Duplicate flow, " FMT_BB " in -> %s, predBlock " FMT_BB
- " out1 -> %s, out2 -> %s\n",
- block->bbNum, BitVecOps::ToString(apTraits, block->bbAssertionIn), predBlock->bbNum,
- BitVecOps::ToString(apTraits, mJumpDestOut[predBlock->bbNum]),
- BitVecOps::ToString(apTraits, predBlock->bbAssertionOut));
+ if (VerboseDataflow())
+ {
+ JITDUMP("Merge : Duplicate flow, " FMT_BB " ", block->bbNum);
+ Compiler::optDumpAssertionIndices("in -> ", block->bbAssertionIn, "; ");
+ JITDUMP("pred " FMT_BB " ", predBlock->bbNum);
+ Compiler::optDumpAssertionIndices("out1 -> ", mJumpDestOut[predBlock->bbNum], "; ");
+ Compiler::optDumpAssertionIndices("out2 -> ", predBlock->bbAssertionOut, "\n");
+ }
}
}
else
@@ -4755,9 +4813,14 @@ public:
pAssertionOut = predBlock->bbAssertionOut;
}
- JITDUMP("AssertionPropCallback::Merge : " FMT_BB " in -> %s, predBlock " FMT_BB " out -> %s\n",
- block->bbNum, BitVecOps::ToString(apTraits, block->bbAssertionIn), predBlock->bbNum,
- BitVecOps::ToString(apTraits, pAssertionOut));
+ if (VerboseDataflow())
+ {
+ JITDUMP("Merge : " FMT_BB " ", block->bbNum);
+ Compiler::optDumpAssertionIndices("in -> ", block->bbAssertionIn, "; ");
+ JITDUMP("pred " FMT_BB " ", predBlock->bbNum);
+ Compiler::optDumpAssertionIndices("out -> ", pAssertionOut, "\n");
+ }
+
BitVecOps::IntersectionD(apTraits, block->bbAssertionIn, pAssertionOut);
}
@@ -4781,8 +4844,11 @@ public:
// At the end of the merge store results of the dataflow equations, in a postmerge state.
bool EndMerge(BasicBlock* block)
{
- JITDUMP("AssertionPropCallback::EndMerge : " FMT_BB " in -> %s\n\n", block->bbNum,
- BitVecOps::ToString(apTraits, block->bbAssertionIn));
+ if (VerboseDataflow())
+ {
+ JITDUMP("EndMerge : " FMT_BB " ", block->bbNum);
+ Compiler::optDumpAssertionIndices("in -> ", block->bbAssertionIn, "\n\n");
+ }
BitVecOps::DataFlowD(apTraits, block->bbAssertionOut, block->bbAssertionGen, block->bbAssertionIn);
BitVecOps::DataFlowD(apTraits, mJumpDestOut[block->bbNum], mJumpDestGen[block->bbNum], block->bbAssertionIn);
@@ -4790,24 +4856,35 @@ public:
bool changed = (!BitVecOps::Equal(apTraits, preMergeOut, block->bbAssertionOut) ||
!BitVecOps::Equal(apTraits, preMergeJumpDestOut, mJumpDestOut[block->bbNum]));
- if (changed)
- {
- JITDUMP("AssertionPropCallback::Changed : " FMT_BB " before out -> %s; after out -> %s;\n"
- "\t\tjumpDest before out -> %s; jumpDest after out -> %s;\n\n",
- block->bbNum, BitVecOps::ToString(apTraits, preMergeOut),
- BitVecOps::ToString(apTraits, block->bbAssertionOut),
- BitVecOps::ToString(apTraits, preMergeJumpDestOut),
- BitVecOps::ToString(apTraits, mJumpDestOut[block->bbNum]));
- }
- else
+ if (VerboseDataflow())
{
- JITDUMP("AssertionPropCallback::Unchanged : " FMT_BB " out -> %s; \t\tjumpDest out -> %s\n\n",
- block->bbNum, BitVecOps::ToString(apTraits, block->bbAssertionOut),
- BitVecOps::ToString(apTraits, mJumpDestOut[block->bbNum]));
+ if (changed)
+ {
+ JITDUMP("Changed : " FMT_BB " ", block->bbNum);
+ Compiler::optDumpAssertionIndices("before out -> ", preMergeOut, "; ");
+ Compiler::optDumpAssertionIndices("after out -> ", block->bbAssertionOut, ";\n ");
+ Compiler::optDumpAssertionIndices("jumpDest before out -> ", preMergeJumpDestOut, "; ");
+ Compiler::optDumpAssertionIndices("jumpDest after out -> ", mJumpDestOut[block->bbNum], ";\n\n");
+ }
+ else
+ {
+ JITDUMP("Unchanged : " FMT_BB " ", block->bbNum);
+ Compiler::optDumpAssertionIndices("out -> ", block->bbAssertionOut, "; ");
+ Compiler::optDumpAssertionIndices("jumpDest out -> ", mJumpDestOut[block->bbNum], "\n\n");
+ }
}
return changed;
}
+
+ // Can be enabled to get detailed debug output about dataflow for assertions.
+ bool VerboseDataflow()
+ {
+#if 0
+ return VERBOSE;
+#endif
+ return false;
+ }
};
/*****************************************************************************
@@ -4894,16 +4971,28 @@ ASSERT_TP* Compiler::optComputeAssertionGen()
#ifdef DEBUG
if (verbose)
{
- printf(FMT_BB " valueGen = %s", block->bbNum, BitVecOps::ToString(apTraits, block->bbAssertionGen));
+ if (block == fgFirstBB)
+ {
+ printf("\n");
+ }
+
+ printf(FMT_BB " valueGen = ", block->bbNum);
+ optPrintAssertionIndices(block->bbAssertionGen);
if (block->bbJumpKind == BBJ_COND)
{
- printf(" => " FMT_BB " valueGen = %s,", block->bbJumpDest->bbNum,
- BitVecOps::ToString(apTraits, jumpDestGen[block->bbNum]));
+ printf(" => " FMT_BB " valueGen = ", block->bbJumpDest->bbNum);
+ optPrintAssertionIndices(jumpDestGen[block->bbNum]);
}
printf("\n");
+
+ if (block == fgLastBB)
+ {
+ printf("\n");
+ }
}
#endif
}
+
return jumpDestGen;
}
@@ -5408,6 +5497,10 @@ void Compiler::optAssertionPropMain()
// Modified dataflow algorithm for available expressions.
DataFlow flow(this);
AssertionPropFlowCallback ap(this, bbJtrueAssertionOut, jumpDestGen);
+ if (ap.VerboseDataflow())
+ {
+ JITDUMP("AssertionPropFlowCallback:\n\n")
+ }
flow.ForwardAnalysis(ap);
for (BasicBlock* const block : Blocks())
@@ -5419,16 +5512,15 @@ void Compiler::optAssertionPropMain()
#ifdef DEBUG
if (verbose)
{
- printf("\n");
for (BasicBlock* const block : Blocks())
{
- printf("\n" FMT_BB, block->bbNum);
- printf(" valueIn = %s", BitVecOps::ToString(apTraits, block->bbAssertionIn));
- printf(" valueOut = %s", BitVecOps::ToString(apTraits, block->bbAssertionOut));
+ printf(FMT_BB ":\n", block->bbNum);
+ optDumpAssertionIndices(" in = ", block->bbAssertionIn, "\n");
+ optDumpAssertionIndices(" out = ", block->bbAssertionOut, "\n");
if (block->bbJumpKind == BBJ_COND)
{
- printf(" => " FMT_BB, block->bbJumpDest->bbNum);
- printf(" valueOut= %s", BitVecOps::ToString(apTraits, bbJtrueAssertionOut[block->bbNum]));
+ printf(" " FMT_BB " = ", block->bbJumpDest->bbNum);
+ optDumpAssertionIndices(bbJtrueAssertionOut[block->bbNum], "\n");
}
}
printf("\n");
@@ -5473,9 +5565,11 @@ void Compiler::optAssertionPropMain()
// and thus we must morph, set order, re-link
for (GenTree* tree = stmt->GetTreeList(); tree != nullptr; tree = tree->gtNext)
{
- JITDUMP("Propagating %s assertions for " FMT_BB ", stmt " FMT_STMT ", tree [%06d], tree -> %d\n",
- BitVecOps::ToString(apTraits, assertions), block->bbNum, stmt->GetID(), dspTreeID(tree),
- tree->GetAssertionInfo().GetAssertionIndex());
+ optDumpAssertionIndices("Propagating ", assertions, " ");
+ JITDUMP("for " FMT_BB ", stmt " FMT_STMT ", tree [%06d]", block->bbNum, stmt->GetID(), dspTreeID(tree));
+ JITDUMP(", tree -> ");
+ JITDUMPEXEC(optPrintAssertionIndex(tree->GetAssertionInfo().GetAssertionIndex()));
+ JITDUMP("\n");
GenTree* newTree = optAssertionProp(assertions, tree, stmt, block);
if (newTree)
diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h
index 356fe6498d1..639b67bb15c 100644
--- a/src/coreclr/jit/compiler.h
+++ b/src/coreclr/jit/compiler.h
@@ -7491,9 +7491,14 @@ public:
#ifdef DEBUG
void optPrintAssertion(AssertionDsc* newAssertion, AssertionIndex assertionIndex = 0);
+ void optPrintAssertionIndex(AssertionIndex index);
+ void optPrintAssertionIndices(ASSERT_TP assertions);
void optDebugCheckAssertion(AssertionDsc* assertion);
void optDebugCheckAssertions(AssertionIndex AssertionIndex);
#endif
+ static void optDumpAssertionIndices(const char* header, ASSERT_TP assertions, const char* footer = nullptr);
+ static void optDumpAssertionIndices(ASSERT_TP assertions, const char* footer = nullptr);
+
void optAddCopies();
#endif // ASSERTION_PROP
diff --git a/src/coreclr/jit/copyprop.cpp b/src/coreclr/jit/copyprop.cpp
index c0d72123e1a..625e2eee5e8 100644
--- a/src/coreclr/jit/copyprop.cpp
+++ b/src/coreclr/jit/copyprop.cpp
@@ -270,9 +270,9 @@ void Compiler::optCopyProp(BasicBlock* block, Statement* stmt, GenTree* tree, Lc
{
JITDUMP("VN based copy assertion for ");
printTreeID(tree);
- printf(" V%02d @%08X by ", lclNum, tree->GetVN(VNK_Conservative));
+ printf(" V%02d " FMT_VN " by ", lclNum, tree->GetVN(VNK_Conservative));
printTreeID(op);
- printf(" V%02d @%08X.\n", newLclNum, op->GetVN(VNK_Conservative));
+ printf(" V%02d " FMT_VN ".\n", newLclNum, op->GetVN(VNK_Conservative));
gtDispTree(tree, nullptr, nullptr, true);
}
#endif
diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h
index 2dd39559c28..fb39fda019c 100644
--- a/src/coreclr/jit/jit.h
+++ b/src/coreclr/jit/jit.h
@@ -487,6 +487,11 @@ const bool dspGCtbls = true;
if (JitTls::GetCompiler()->verbose) \
logf(__VA_ARGS__); \
}
+#define JITDUMPEXEC(x) \
+ { \
+ if (JitTls::GetCompiler()->verbose) \
+ x; \
+ }
#define JITLOG(x) \
{ \
JitLogEE x; \
@@ -521,6 +526,7 @@ const bool dspGCtbls = true;
#define VERBOSE JitTls::GetCompiler()->verbose
#else // !DEBUG
#define JITDUMP(...)
+#define JITDUMPEXEC(x)
#define JITLOG(x)
#define JITLOG_THIS(t, x)
#define DBEXEC(flg, expr)
diff --git a/src/coreclr/jit/rangecheck.cpp b/src/coreclr/jit/rangecheck.cpp
index 5c95b91883c..a37f11cedae 100644
--- a/src/coreclr/jit/rangecheck.cpp
+++ b/src/coreclr/jit/rangecheck.cpp
@@ -865,16 +865,16 @@ void RangeCheck::MergeAssertion(BasicBlock* block, GenTree* op, Range* pRange DE
if (pred->bbFallsThrough() && pred->bbNext == block)
{
assertions = pred->bbAssertionOut;
- JITDUMP("Merge assertions from pred " FMT_BB " edge: %s\n", pred->bbNum,
- BitVecOps::ToString(m_pCompiler->apTraits, assertions));
+ JITDUMP("Merge assertions from pred " FMT_BB " edge: ", pred->bbNum);
+ Compiler::optDumpAssertionIndices(assertions, "\n");
}
else if ((pred->bbJumpKind == BBJ_COND || pred->bbJumpKind == BBJ_ALWAYS) && pred->bbJumpDest == block)
{
if (m_pCompiler->bbJtrueAssertionOut != nullptr)
{
assertions = m_pCompiler->bbJtrueAssertionOut[pred->bbNum];
- JITDUMP("Merge assertions from pred " FMT_BB " JTrue edge: %s\n", pred->bbNum,
- BitVecOps::ToString(m_pCompiler->apTraits, assertions));
+ JITDUMP("Merge assertions from pred " FMT_BB " JTrue edge: ", pred->bbNum);
+ Compiler::optDumpAssertionIndices(assertions, "\n");
}
}
}
@@ -1012,9 +1012,10 @@ Range RangeCheck::ComputeRangeForLocalDef(BasicBlock* block,
Range range = GetRange(ssaDef->GetBlock(), ssaDef->GetAssignment()->gtGetOp2(), monIncreasing DEBUGARG(indent));
if (!BitVecOps::MayBeUninit(block->bbAssertionIn) && (m_pCompiler->GetAssertionCount() > 0))
{
- JITDUMP("Merge assertions from " FMT_BB ":%s for assignment about [%06d]\n", block->bbNum,
- BitVecOps::ToString(m_pCompiler->apTraits, block->bbAssertionIn),
- Compiler::dspTreeID(ssaDef->GetAssignment()->gtGetOp1()));
+ JITDUMP("Merge assertions from " FMT_BB ": ", block->bbNum);
+ Compiler::optDumpAssertionIndices(block->bbAssertionIn, " ");
+ JITDUMP("for assignment about [%06d]\n", Compiler::dspTreeID(ssaDef->GetAssignment()->gtGetOp1()))
+
MergeEdgeAssertions(ssaDef->GetAssignment()->gtGetOp1()->AsLclVarCommon(), block->bbAssertionIn, &range);
JITDUMP("done merging\n");
}