Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalize loop pre-header creation and loop hoisting #62560

Merged
4 changes: 2 additions & 2 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5997,6 +5997,7 @@ class Compiler
#endif // DUMP_FLOWGRAPHS

#ifdef DEBUG

void fgDispDoms();
void fgDispReach();
void fgDispBBLiveness(BasicBlock* block);
Expand Down Expand Up @@ -6029,8 +6030,7 @@ class Compiler
bool fgDebugCheckIncomingProfileData(BasicBlock* block);
bool fgDebugCheckOutgoingProfileData(BasicBlock* block);

unsigned* fgBuildBlockNumMap();
#endif
#endif // DEBUG

static bool fgProfileWeightsEqual(weight_t weight1, weight_t weight2);
static bool fgProfileWeightsConsistent(weight_t weight1, weight_t weight2);
Expand Down
76 changes: 23 additions & 53 deletions src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3790,9 +3790,29 @@ void Compiler::fgDebugCheckLoopTable()
assert(optLoopTable != nullptr);
}

// Construct a map of increasing block numbers to allow for block number comparisons when block numbers are not
// guaranteed to be in increasing order.
unsigned* blockNumMap = fgBuildBlockNumMap();
// Build a mapping from existing block list number (bbNum) to the block number it would be after the
// blocks are renumbered. This allows making asserts about the relative ordering of blocks using block number
// without actually renumbering the blocks, which would affect non-DEBUG code paths. Note that there may be
// `blockNumMap[bbNum] == 0` if the `bbNum` block was deleted and blocks haven't been renumbered since
// the deletion.

unsigned bbNumMax = compIsForInlining() ? impInlineInfo->InlinerCompiler->fgBBNumMax : fgBBNumMax;
BruceForstall marked this conversation as resolved.
Show resolved Hide resolved

// blockNumMap[old block number] => new block number
size_t blockNumBytes = (bbNumMax + 1) * sizeof(unsigned);
unsigned* blockNumMap = (unsigned*)_alloca(blockNumBytes);
BruceForstall marked this conversation as resolved.
Show resolved Hide resolved
memset(blockNumMap, 0, blockNumBytes);

unsigned newBBnum = 1;
for (BasicBlock* const block : Blocks())
{
if ((block->bbFlags & BBF_REMOVED) == 0)
{
assert(1 <= block->bbNum && block->bbNum <= bbNumMax);
assert(blockNumMap[block->bbNum] == 0); // If this fails, we have two blocks with the same block number.
blockNumMap[block->bbNum] = newBBnum++;
}
}

struct MappedChecks
{
Expand Down Expand Up @@ -4022,55 +4042,5 @@ void Compiler::fgDebugCheckLoopTable()
assert(preHeaderCount == 0);
}

//------------------------------------------------------------------------
// fgBuildBlockNumMap: Build a mapping from existing block list numbers (bbNum)
// to a set of block numbers that would exist after the blocks are renumbered.
// This allows making asserts about the relative ordering of blocks using block
// number without actually renumbering the blocks, which would affect non-DEBUG
// code paths.
//
// Arguments:
// jumpTarget -- [in] bit vector of jump targets found by fgFindJumpTargets
//
// Returns:
// A block number map array `blockNumMap` such that `blockNumMap[bbNum]` for a block is the number the block
// would have if the block list were renumbered. Note that there may be some blockNumMap[x] == 0, for a
// block number 'x' that has been deleted, if the blocks haven't been renumbered since the deletion.
//
unsigned* Compiler::fgBuildBlockNumMap()
{
unsigned bbNumMax = compIsForInlining() ? impInlineInfo->InlinerCompiler->fgBBNumMax : fgBBNumMax;

// blockNumMap[old block number] => new block number
size_t blockNumBytes = (bbNumMax + 1) * sizeof(unsigned);
unsigned* blockNumMap = (unsigned*)_alloca(blockNumBytes);
memset(blockNumMap, 0, blockNumBytes);

unsigned newBBnum = 1;
for (BasicBlock* const block : Blocks())
{
assert((block->bbFlags & BBF_REMOVED) == 0);
assert(1 <= block->bbNum && block->bbNum <= bbNumMax);
assert(blockNumMap[block->bbNum] == 0); // If this fails, we have two blocks with the same block number.
blockNumMap[block->bbNum] = newBBnum++;
}

#if 0 // Useful for debugging, but don't want to put this in the dump all the time
if (verbose)
{
printf("fgVerifyHandlerTab block number map: BB current => BB new\n");
for (unsigned i = 0; i <= bbNumMax; i++)
{
if (blockNumMap[i] != 0)
{
printf(FMT_BB " => " FMT_BB "\n", i, blockNumMap[i]);
}
}
}
#endif

return blockNumMap;
}

/*****************************************************************************/
#endif // DEBUG