[llvm] [GlobalISel] Support physical register inputs in nested patterns (PR #121239)
Evgenii Kudriashov via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 28 05:52:43 PST 2024
================
@@ -1412,15 +1412,18 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
action_iterator InsertPt = InsertPtOrError.get();
BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
- for (auto PhysInput : InsnMatcher.getPhysRegInputs()) {
- InsertPt = M.insertAction<BuildMIAction>(
- InsertPt, M.allocateOutputInsnID(),
- &Target.getInstruction(RK.getDef("COPY")));
- BuildMIAction &CopyToPhysRegMIBuilder =
- *static_cast<BuildMIAction *>(InsertPt->get());
- CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(
- Target, PhysInput.first, true);
- CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first);
+ for (auto PhysOp : M.physoperands()) {
+ auto &OpInsnMatcher = PhysOp.second->getInstructionMatcher();
+ for (auto PhysInput : OpInsnMatcher.getPhysRegInputs()) {
----------------
e-kud wrote:
Interesting, if we have a pattern like
```
def ADD_PHYS : I<(outs GPR32:$dst), (ins),
[(set GPR32:$dst, (add SPECIAL, SPECIAL))]> {
let Uses = [SPECIAL];
}
```
We see two copies without this change as well
```
// (add:{ *:[i32] } SPECIAL:{ *:[i32] }, SPECIAL:{ *:[i32] }) => (ADD_PHYS:{ *:[i32] })
GIR_BuildMI, /*InsnID*/2, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
GIR_AddRegister, /*InsnID*/2, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),
GIR_Copy, /*NewInsnID*/2, /*OldInsnID*/0, /*OpIdx*/1, // SPECIAL
GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
GIR_AddRegister, /*InsnID*/1, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),
GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/1, // SPECIAL
GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::ADD_PHYS),
```
At the same time for the pattern like
```
def ADD_PHYS : I<(outs GPR32:$dst), (ins ),
[(set GPR32:$dst, (add SPECIAL, SPECIAL_2))]> {
let Uses = [SPECIAL, SPECIAL_2];
}
```
We need this loop because two copies are required
```
// (add:{ *:[i32] } SPECIAL:{ *:[i32] }, SPECIAL_2:{ *:[i32] }) => (ADD_PHYS:{ *:[i32] })
GIR_BuildMI, /*InsnID*/2, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
GIR_AddRegister, /*InsnID*/2, GIMT_Encode2(MyTarget::SPECIAL_2), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),
GIR_Copy, /*NewInsnID*/2, /*OldInsnID*/0, /*OpIdx*/2, // SPECIAL_2
GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
GIR_AddRegister, /*InsnID*/1, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),
GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/1, // SPECIAL
GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::ADD_PHYS),
```
So should we have initially tracked the uniqueness of physical registers?
https://github.com/llvm/llvm-project/pull/121239
More information about the llvm-commits
mailing list