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:
Diffstat (limited to 'src/coreclr/jit/assertionprop.cpp')
-rw-r--r--src/coreclr/jit/assertionprop.cpp184
1 files changed, 139 insertions, 45 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)