diff options
Diffstat (limited to 'src/coreclr/jit/assertionprop.cpp')
-rw-r--r-- | src/coreclr/jit/assertionprop.cpp | 184 |
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) |