[llvm] [VPlan] Introduce scalar loop header in plan, remove VPLiveOut. (PR #109975)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 4 05:46:57 PDT 2024
david-arm wrote:
Hi @fhahn, so I tried changing https://github.com/llvm/llvm-project/pull/88385 to use the new way of dealing with live-outs and not rely upon VPLiveOut in a similar way to how we deal with normal exits. However, I came across a fundamental ordering constraint that needs dealing with. The problem occurs when the exit block from the latch is the same as the exit from the early exiting block. In this case the vectorised CFG would look something like this:
```
vector.loop:
...
br i1, label %vector.early.exit, label %vector.loop.latch
vector.loop.latch:
br i1, label %middle.block, label %vector.loop
vector.early.exit:
...
br label %loop.exit
middle.block:
...
br i1 %finished, label %loop.exit, ...
... original scalar loop sits here ...
VPIRBasicBlock(loop.exit):
VPIRInstruction(%tea = phi i32 [ ..., %loop ], [ ..., %loop.latch ] (extra operands ...))
```
Using the example implementation you mentioned in https://github.com/llvm/llvm-project/commit/3cfe25bf43feaf94d319c7f804e5c73c45f96057 (thank you for this!) the order of the predecessors in VPIRBasicBlock(loop.exit) by definition has to match the same order in which the extra operands were added to VPIRInstruction(%tea) when collecting/adding users in the exit block during VPlan creation. However, `VPlan::execute` breaks this assumption immediately when rewiring the middle block from a VPBasicBlock to a VPIRBasicBlock. In this case I have two choices that I know of:
1. In replaceVPBBWithIRVPBB ensure that the middle block stays in the same position in the predecessor list of any successor. I imagine it's possible, but it does feel fragile.
2. Add a map to VPIRInstruction that maps the additional operand index with the incoming block so that when rewiring the middle block we can ensure the map stays correct. This removes any fragile ordering dependency. Then I'd adapt `VPIRInstruction::execute` in https://github.com/llvm/llvm-project/commit/3cfe25bf43feaf94d319c7f804e5c73c45f96057 to get the incoming block by looking the index up in the map.
I'll keep playing around with this a bit more and see what works best!
https://github.com/llvm/llvm-project/pull/109975
More information about the llvm-commits
mailing list