Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 139 additions & 45 deletions src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}

/******************************************************************************
*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -4721,8 +4772,12 @@ class AssertionPropFlowCallback
// 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]);
}
Expand All @@ -4743,21 +4798,29 @@ class AssertionPropFlowCallback
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
{
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);
}

Expand All @@ -4781,33 +4844,47 @@ class AssertionPropFlowCallback
// 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);

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;
}
};

/*****************************************************************************
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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())
Expand All @@ -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");
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7491,9 +7491,14 @@ class Compiler

#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

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/copyprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; \
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 8 additions & 7 deletions src/coreclr/jit/rangecheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
}
Expand Down Expand Up @@ -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");
}
Expand Down