Skip to content

Revisit LSRA block sequence strategy #66994

@kunalspathak

Description

@kunalspathak

LSRA comes up with a block order in which it would allocate register for the code inside it. It would sequence all the predecessors of a block before scheduling a block. It also compares the bbWeight of a block and gives preference to the block with higher weights.
It is not uncommon to have multiple blocks of same weight (either because of lack of enough profile data or other reasons) and in such cases, we rely on the block number of the block as seen below.

int LinearScan::compareBlocksForSequencing(BasicBlock* block1, BasicBlock* block2, bool useBlockWeights)
{
if (useBlockWeights)
{
weight_t weight1 = block1->getBBWeight(compiler);
weight_t weight2 = block2->getBBWeight(compiler);
if (weight1 > weight2)
{
return -1;
}
else if (weight1 < weight2)
{
return 1;
}
}
// If weights are the same prefer LOWER bbnum
if (block1->bbNum < block2->bbNum)
{
return -1;
}
else if (block1->bbNum == block2->bbNum)
{
return 0;
}
else
{
return 1;
}
}

This is arguably not a good heuristic to arrange LSRA block sequencing. The bbNum are purely dependent on the how the blocks are laid out our data structure and might not represent the flow graph. The original thinking could be that the blocks with lower bbNum are executed first than the ones with higher numbers, but still, it is not the optimal strategy to have. If the blocks are renumbered, it can drastically change the allocation strategy because of different block sequencing coming out of it. This was seen in #66967 where I had to skip renumbering the blocks so the impact of "unreachable block elimination" doesn't regress register allocation.

Just to give a sense, I tried following strategies and the impact it has on code size is huge.

Strategy Methods improved Methods regressed Code size impact (in bytes)
Prefer block1 over block2 if block1 has more predecessors than those of block2. 2292 3313 23028
Prefer block1 over block2 if block1 has less predecessors than those of block2. 2669 3141 3079
Prefer block1 over block2 if block1 has more bbReach nodes than those of block2. 3495 3923 14156
Prefer block1 over block2 if block1 has less bbReach nodes than those of block2. 2642 3425 4155

Some other strategies could be:

  1. Prefer blocks depending on if they have critical in/out edges.
  2. Prefer blocks depending on if they have EH boundary in/out edges.
  3. Prefer blocks if they are in loop (this could be mostly taken care by bbWeight but should double check).

A clever way is to have a mix of above listed strategies in choosing the block sequencing.

category:design
theme:register-allocator
skill-level:expert
cost:medium
impact:large

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions