#endif
#include "allocacheck.h" // for alloca
+#include "jitstd/algorithm.h"
// Flowgraph Check and Dump Support
void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock, bool dumpTrees)
{
- BasicBlock* block;
+ // Build vector of blocks in order.
+ //
+ if (fgBBOrder == nullptr)
+ {
+ CompAllocator allocator = getAllocator(CMK_DebugOnly);
+ fgBBOrder = new (allocator) jitstd::vector<BasicBlock*>(allocator);
+ }
+
+ fgBBOrder->reserve(fgBBcount);
+ fgBBOrder->clear();
- // If any block has IBC data, we add an "IBC weight" column just before the 'IL range' column. This column is as
- // wide as necessary to accommodate all the various IBC weights. It's at least 4 characters wide, to accommodate
- // the "IBC" title and leading space.
int ibcColWidth = 0;
- for (block = firstBlock; block != nullptr; block = block->bbNext)
+
+ for (BasicBlock* block = firstBlock; block != nullptr; block = block->bbNext)
{
if (block->hasProfileWeight())
{
ibcColWidth = max(ibcColWidth, thisIbcWidth);
}
+ fgBBOrder->push_back(block);
+
if (block == lastBlock)
{
break;
}
}
+
+ bool inDefaultOrder = true;
+
+ struct fgBBNumCmp
+ {
+ bool operator()(const BasicBlock* bb1, const BasicBlock* bb2)
+ {
+ return bb1->bbNum < bb2->bbNum;
+ }
+ };
+
+ struct fgBBIDCmp
+ {
+ bool operator()(const BasicBlock* bb1, const BasicBlock* bb2)
+ {
+ return bb1->bbID < bb2->bbID;
+ }
+ };
+
+ // Optionally sort
+ //
+ if (JitConfig.JitDumpFgBlockOrder() == 1)
+ {
+ jitstd::sort(fgBBOrder->begin(), fgBBOrder->end(), fgBBNumCmp());
+ inDefaultOrder = false;
+ }
+ else if (JitConfig.JitDumpFgBlockOrder() == 2)
+ {
+
+ jitstd::sort(fgBBOrder->begin(), fgBBOrder->end(), fgBBIDCmp());
+ inDefaultOrder = false;
+ }
+
if (ibcColWidth > 0)
{
ibcColWidth = max(ibcColWidth, 3) + 1; // + 1 for the leading space
// clang-format on
- for (block = firstBlock; block; block = block->bbNext)
+ for (BasicBlock* block : *fgBBOrder)
{
// First, do some checking on the bbPrev links
if (block->bbPrev)
printf("bad prev link!\n");
}
- if (block == fgFirstColdBlock)
+ if (inDefaultOrder && (block == fgFirstColdBlock))
{
printf(
"~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~"
}
#if defined(FEATURE_EH_FUNCLETS)
- if (block == fgFirstFuncletBB)
+ if (inDefaultOrder && (block == fgFirstFuncletBB))
{
printf(
"++++++%*s+++++++++++++++++++++++++++++++++++++%*s++++++++++++++++++++++++++%*s++++++++++++++++++++++++"
if (dumpTrees)
{
- fgDumpTrees(firstBlock, lastBlock);
+ for (BasicBlock* block : *fgBBOrder)
+ {
+ fgDumpBlock(block);
+ }
+ printf("\n-----------------------------------------------------------------------------------------------------"
+ "----"
+ "----------\n");
}
}
// bbNum and bbID
CONFIG_INTEGER(JitDumpFgBlockFlags, W("JitDumpFgBlockFlags"), 0) // 0 == don't display block flags; 1 == display flags
CONFIG_INTEGER(JitDumpFgLoopFlags, W("JitDumpFgLoopFlags"), 0) // 0 == don't display loop flags; 1 == display flags
+CONFIG_INTEGER(JitDumpFgBlockOrder, W("JitDumpFgBlockOrder"), 0) // 0 == bbNext order; 1 == bbNum order; 2 == bbID
+ // order
CONFIG_STRING(JitDumpPreciseDebugInfoFile, W("JitDumpPreciseDebugInfoFile"))
CONFIG_INTEGER(JitDisasmWithDebugInfo, W("JitDisasmWithDebugInfo"), 0)