Save the instruction list of a block before selecting banks.
This allows to cope with moved instructions, even if they are reordered
or splitted into multiple basic blocks.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
30 ms | x64 debian > flang-OldUnit.Evaluate::intrinsics.test |
Event Timeline
llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | ||
---|---|---|
46 | Don't need this since it's already done in the header. | |
734–735 | Can you initialise the worklist from RPOT and then just have a single worklist loop, instead of two nested loops? | |
llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp | ||
774–776 | Before this patch, how did these new BBs get regbankselected? |
Fix review comments, use just the worklist instead of a nested loop.
llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp | ||
---|---|---|
774–776 | RegBankSelect had logic to detect if applyMapping moved an instruction to a new basic block and then continued from there. The banks for instructions in RemainderBB and RestoreExecBB are set here, so they don’t need to be selected. |
OK, so if applyMapping creates new instructions it either has to
- set banks for the new instructions' operands as they are created, or
- do something to make sure RegBankSelect visits the new instructions.
The low level implementation details look OK to me.
I guess we need to get some agreement about the high level design: is this a good way of handling newly created instructions and BBs? In particular I wonder if there is some way of handling newly created instructions automatically, without having to call setNextInstruction, but I can't quite see how it would work.
llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | ||
---|---|---|
698–702 | Could just Worklist.insert(Worklist.end(), ...)? |
Thanks, the Worklist.insert does read better than std::copy.
I guess we need to get some agreement about the high level design: is this a good way of handling newly created instructions and BBs? In particular I wonder if there is some way of handling newly created instructions automatically, without having to call setNextInstruction, but I can't quite see how it would work.
Yes, it gets quite complicated when introducing loops for call instructions because it moves multiple instructions and now also unbundles them (so the I++ used in RegBankSelect points to the wrong instruction – after the bundle).
I implemented it using an observer and it worked. Then I realized that I never registered the observer anywhere…
So, here’s a simpler implementation that seems to be enough to find all instructions.
The new patch for creating loops around call instructions does not use bundles anymore because they create more problems than they solve (e.g. the legalizer tries and fails to legalize instructions in a bundle). This simplifies the cases that need to be handled.
llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | ||
---|---|---|
710 | I just tried and couldn’t get it working. I guess the iterator returns a MachineInstr& and no pointer, but SmallVector<MachineInstr&> doesn’t work. |
llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | ||
---|---|---|
710 | Ugh. This might work: SmallVector<MachineInstr *> WorkList(make_pointer_range(reverse(MBB->instrs()))); |
It’s complete. It worked in all cases I tested, so I hope it really can be that simple :)
Don't need this since it's already done in the header.