[llvm] r305553 - [Hexagon] Don't kill live registers when creating mux out of tfr

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 16 05:24:04 PDT 2017


Author: kparzysz
Date: Fri Jun 16 07:24:03 2017
New Revision: 305553

URL: http://llvm.org/viewvc/llvm-project?rev=305553&view=rev
Log:
[Hexagon] Don't kill live registers when creating mux out of tfr

The second part of r305300: when placing the mux at the later location,
make sure that it won't use any register that was killed between the
two original instructions. Remove any such kills and transfer them to
the mux.

Added:
    llvm/trunk/test/CodeGen/Hexagon/mux-kill2.mir
Modified:
    llvm/trunk/lib/Target/Hexagon/HexagonGenMux.cpp

Modified: llvm/trunk/lib/Target/Hexagon/HexagonGenMux.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonGenMux.cpp?rev=305553&r1=305552&r2=305553&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonGenMux.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonGenMux.cpp Fri Jun 16 07:24:03 2017
@@ -317,7 +317,37 @@ bool HexagonGenMux::genMuxInBlock(Machin
     // Prefer "down", since this will move the MUX farther away from the
     // predicate definition.
     MachineBasicBlock::iterator At = CanDown ? Def2 : Def1;
-    if (!CanDown) {
+    if (CanDown) {
+      // If the MUX is placed "down", we need to make sure that there aren't
+      // any kills of the source registers between the two defs.
+      if (Used1 || Used2) {
+        auto ResetKill = [this] (unsigned Reg, MachineInstr &MI) -> bool {
+          if (MachineOperand *Op = MI.findRegisterUseOperand(Reg, true, HRI)) {
+            Op->setIsKill(false);
+            return true;
+          }
+          return false;
+        };
+        bool KilledSR1 = false, KilledSR2 = false;
+        for (MachineInstr &MJ : make_range(std::next(It1), It2)) {
+          if (SR1)
+            KilledSR1 |= ResetKill(SR1, MJ);
+          if (SR2)
+            KilledSR2 |= ResetKill(SR1, MJ);
+        }
+        // If any of the source registers were killed in this range, transfer
+        // the kills to the source operands: they will me "moved" to the
+        // resulting MUX and their parent instructions will be deleted.
+        if (KilledSR1) {
+          assert(Src1->isReg());
+          Src1->setIsKill(true);
+        }
+        if (KilledSR2) {
+          assert(Src2->isReg());
+          Src2->setIsKill(true);
+        }
+      }
+    } else {
       // If the MUX is placed "up", it shouldn't kill any source registers
       // that are still used afterwards. We can reset the kill flags directly
       // on the operands, because the source instructions will be erased.

Added: llvm/trunk/test/CodeGen/Hexagon/mux-kill2.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/mux-kill2.mir?rev=305553&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/mux-kill2.mir (added)
+++ llvm/trunk/test/CodeGen/Hexagon/mux-kill2.mir Fri Jun 16 07:24:03 2017
@@ -0,0 +1,17 @@
+# RUN: llc -march=hexagon -run-pass hexagon-gen-mux -o - -verify-machineinstrs %s | FileCheck %s
+# CHECK: %r1 = C2_muxri %p0, 123, %r0
+# CHECK: %r2 = C2_muxir %p0, killed %r0, 321
+---
+name: fred
+tracksRegLiveness: true
+
+body: |
+  bb.0:
+    liveins: %r0, %p0
+
+    %r2 = A2_tfrt %p0, %r0
+    %r1 = C2_cmoveit %p0, 123
+    %r1 = A2_tfrf %p0, killed %r0, implicit killed %r1
+    %r2 = C2_cmoveif killed %p0, 321, implicit killed %r2
+...
+




More information about the llvm-commits mailing list