[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