[PATCH] D92385: [ARM] Add a pass that re-arranges blocks when there is a backwards WLS branch

Sjoerd Meijer via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 11 02:35:55 PST 2021


SjoerdMeijer added a comment.

Here's my "pen-and-paper exercise" of the problem that we are solving here, and lets start with some examples.
In these examples, empty blocks means there are no instructions in it that are relevant to this problem.

  bb1:
  bb2:
    WLS bb1
  bb3:

In this first example above, we want to reorder blocks so that we get bb1 -> bb3 -> bb2. This is the easiest case, because there's nothing in `bb0` that interacts.
Interacting here means moving a block that also contains a WLS:

  bb1:
    WLS xyz
  bb2:
    WLS bb1
  bb3:

If we want to move `bb1, we now find a WLS in the block that we are moving:

- the WLS can be forward branch:
  - if it branches to `bb2`, then we would create a backward branch. So, we would fix one, and regress one, and don't really win anything, unless the one that we fix has is "more important to fix".
  - if it branches to some block after `bb3`, then moving `bb1` to after `bb2`, we create 2 forward branches, and all is okay.
- the WLS can be a backward branch:
  - if we move `bb1`, its backward branch remains backward, so that doesn't regress and we fix another and is thus a win.

If we increase the first example:

  bb1:
  bb2
  bb3:
    WLS bb1
  bb4:

then nothing is changes and we can safely move `bb1`.

  bb1:
  bb2:
    WLS xyz
  bb3:
    WLS bb1
  bb4:

If we move `bb1`, but there is a forward/backward branch in next block, `bb2` in this case:

- if it branches back to `bb1`, we create a forward one, so we improve,
- if branches forward, it will remain a forward branch.

So, I don't think we need consider WLS in blocks between the block that we are moving and its new place.

I think/hope this captures the decision making we need to do regarding the WLS instructions.

But I think this is not yet the complete picture; WLS is not the only instruction that need to check, as we have also the LE.
As a first example:

  bb1:
  bb2:
    LE bb1
  bb3:
    WLS bb1
  bb4: 

If we would like move `bb1` to create a forward branch for the `WLS, but `bb1` is a target for a LE in a successor block, then is that what we want? What are the restrictions for the LE instructions?

Summarising:

- I think we need to analyse all blocks between the block that we would like to move to its new place.
- We need to identify and analyse instructions in them that interacts with this, which are the WLS, and the LE?
- Looks like there are cases where we can improve one WLS, and regress one, so that we need some decision making to choose (could be done in a follow up).
- Terminology:
  - is "nesting" important? Or can we just forget it?
  - I had to remind myself again about the WLS semantics, i.e. WLS bb1 means something like:  CMP, BCC, B, and the `bb1` is the loop exit block. So, instead of calling this target, let's call this something with "exit".


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92385/new/

https://reviews.llvm.org/D92385



More information about the llvm-commits mailing list