]> granicus.if.org Git - llvm/commitdiff
[Hexagon] Don't kill live registers when creating mux out of tfr
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Tue, 13 Jun 2017 16:07:36 +0000 (16:07 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Tue, 13 Jun 2017 16:07:36 +0000 (16:07 +0000)
When a mux instruction is created from a pair of complementary conditional
transfers, it can be placed at the location of either the earlier or the
later of the transfers. Since it will use the operands of the original
transfers, putting it in the earlier location may hoist a kill of a source
register that was originally further down. Make sure the kill flag is
removed if the register is still used afterwards.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305300 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Hexagon/HexagonGenMux.cpp
lib/Target/Hexagon/HexagonTargetMachine.cpp
test/CodeGen/Hexagon/mux-kill.mir [new file with mode: 0644]

index 3c37d9ebb0ebc5f3eab7115866b939f281114c89..a2502ce5ec34b31838bddd47c8fe2898d21dddbd 100644 (file)
@@ -59,9 +59,7 @@ namespace {
   public:
     static char ID;
 
-    HexagonGenMux() : MachineFunctionPass(ID), HII(nullptr), HRI(nullptr) {
-      initializeHexagonGenMuxPass(*PassRegistry::getPassRegistry());
-    }
+    HexagonGenMux() : MachineFunctionPass(ID) {}
 
     StringRef getPassName() const override {
       return "Hexagon generate mux instructions";
@@ -79,8 +77,8 @@ namespace {
     }
 
   private:
-    const HexagonInstrInfo *HII;
-    const HexagonRegisterInfo *HRI;
+    const HexagonInstrInfo *HII = nullptr;
+    const HexagonRegisterInfo *HRI = nullptr;
 
     struct CondsetInfo {
       unsigned PredR = 0;
@@ -134,7 +132,7 @@ namespace {
 
 } // end anonymous namespace
 
-INITIALIZE_PASS(HexagonGenMux, "hexagon-mux",
+INITIALIZE_PASS(HexagonGenMux, "hexagon-gen-mux",
   "Hexagon generate mux instructions", false, false)
 
 void HexagonGenMux::getSubRegs(unsigned Reg, BitVector &SRs) const {
@@ -297,12 +295,15 @@ bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) {
     unsigned SR1 = Src1->isReg() ? Src1->getReg() : 0;
     unsigned SR2 = Src2->isReg() ? Src2->getReg() : 0;
     bool Failure = false, CanUp = true, CanDown = true;
+    bool Used1 = false, Used2 = false;
     for (unsigned X = MinX+1; X < MaxX; X++) {
       const DefUseInfo &DU = DUM.lookup(X);
       if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) {
         Failure = true;
         break;
       }
+      Used1 |= DU.Uses[SR1];
+      Used2 |= DU.Uses[SR2];
       if (CanDown && DU.Defs[SR1])
         CanDown = false;
       if (CanUp && DU.Defs[SR2])
@@ -316,6 +317,15 @@ bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) {
     // Prefer "down", since this will move the MUX farther away from the
     // predicate definition.
     MachineBasicBlock::iterator At = CanDown ? Def2 : Def1;
+    if (!CanDown) {
+      // 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.
+      if (Used1 && Src1->isReg())
+        Src1->setIsKill(false);
+      if (Used2 && Src2->isReg())
+        Src2->setIsKill(false);
+    }
     ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2));
   }
 
index c757b6ecdd000d3ef71738786ecb13aa4d551cac..e507a797871fcdd0c62593914658a91bd2203b40 100644 (file)
@@ -111,6 +111,7 @@ namespace llvm {
   extern char &HexagonExpandCondsetsID;
   void initializeHexagonExpandCondsetsPass(PassRegistry&);
   void initializeHexagonLoopIdiomRecognizePass(PassRegistry&);
+  void initializeHexagonGenMuxPass(PassRegistry&);
   void initializeHexagonOptAddrModePass(PassRegistry&);
   Pass *createHexagonLoopIdiomPass();
 
@@ -152,8 +153,11 @@ static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
 extern "C" void LLVMInitializeHexagonTarget() {
   // Register the target.
   RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget());
-  initializeHexagonLoopIdiomRecognizePass(*PassRegistry::getPassRegistry());
-  initializeHexagonOptAddrModePass(*PassRegistry::getPassRegistry());
+
+  PassRegistry &PR = *PassRegistry::getPassRegistry();
+  initializeHexagonLoopIdiomRecognizePass(PR);
+  initializeHexagonGenMuxPass(PR);
+  initializeHexagonOptAddrModePass(PR);
 }
 
 HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT,
diff --git a/test/CodeGen/Hexagon/mux-kill.mir b/test/CodeGen/Hexagon/mux-kill.mir
new file mode 100644 (file)
index 0000000..6944050
--- /dev/null
@@ -0,0 +1,15 @@
+# RUN: llc -march=hexagon -run-pass hexagon-gen-mux -o - %s -verify-machineinstrs | FileCheck %s
+# CHECK: %r2 = C2_mux %p0, %r0, %r1
+---
+name: fred
+tracksRegLiveness: true
+
+body: |
+  bb.0:
+    liveins: %d0, %p0
+
+    %r2 = A2_tfrt %p0, %r0
+    %r0 = A2_tfr %r1
+    %r2 = A2_tfrf %p0, killed %r1
+...
+