Allow target to place 2-address pass inserted copies in better spots. Thumb2 will...
authorEvan Cheng <evan.cheng@apple.com>
Wed, 9 Jun 2010 19:26:01 +0000 (19:26 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 9 Jun 2010 19:26:01 +0000 (19:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105745 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetInstrInfo.h
lib/CodeGen/TwoAddressInstructionPass.cpp
lib/Target/ARM/Thumb2ITBlockPass.cpp
lib/Target/ARM/Thumb2InstrInfo.cpp
lib/Target/ARM/Thumb2InstrInfo.h

index 98a5f57137df8a17d1f950c19781f5277040d50d..855400318aabb9aef34671b57318bc614a377ae7 100644 (file)
@@ -203,6 +203,14 @@ public:
                              const MachineInstr *Orig,
                              const TargetRegisterInfo &TRI) const = 0;
 
+  /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
+  /// two-addrss instruction inserted by two-address pass.
+  virtual void scheduleTwoAddrSource(MachineInstr *SrcMI,
+                                     MachineInstr *UseMI,
+                                     const TargetRegisterInfo &TRI) const {
+    // Do nothing.
+  }
+
   /// duplicate - Create a duplicate of the Orig instruction in MF. This is like
   /// MachineFunction::CloneMachineInstr(), but the target may update operands
   /// that are required to be unique.
index 16588bf3a7a2de9af137de7b8fd12b1df879bd9c..5b7ae19e90140390ffd12c6b5ae1ead3982ff698 100644 (file)
@@ -1104,7 +1104,12 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
             }
           }
         }
-          
+
+        // Schedule the source copy / remat inserted to form two-address
+        // instruction. FIXME: Does it matter the distance map may not be
+        // accurate after it's scheduled?
+        TII->scheduleTwoAddrSource(prior(mi), mi, *TRI);
+
         MadeChange = true;
 
         DEBUG(dbgs() << "\t\trewrite to:\t" << *mi);
index fb33f887340680db30ade44f3fd5d3b1291eae57..691444cdc02ecbb1b1894bf5e55cdcaebd361706 100644 (file)
@@ -61,15 +61,7 @@ static ARMCC::CondCodes getPredicate(const MachineInstr *MI, unsigned &PredReg){
   unsigned Opc = MI->getOpcode();
   if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
     return ARMCC::AL;
-
-  int PIdx = MI->findFirstPredOperandIdx();
-  if (PIdx == -1) {
-    PredReg = 0;
-    return ARMCC::AL;
-  }
-
-  PredReg = MI->getOperand(PIdx+1).getReg();
-  return (ARMCC::CondCodes)MI->getOperand(PIdx).getImm();
+  return llvm::getInstrPredicate(MI, PredReg);
 }
 
 bool
@@ -242,15 +234,15 @@ bool Thumb2ITBlockPass::InsertITBlock(MachineInstr *First, MachineInstr *Last) {
   // Insert a new block for consecutive predicated instructions.
   MachineFunction *MF = MBB->getParent();
   MachineBasicBlock *NewMBB = MF->CreateMachineBasicBlock(MBB->getBasicBlock());
-  MachineFunction::iterator Pos = MBB;
-  MF->insert(++Pos, NewMBB);
+  MachineFunction::iterator InsertPos = MBB;
+  MF->insert(++InsertPos, NewMBB);
 
   // Move all the successors of this block to the specified block.
   NewMBB->transferSuccessors(MBB);
 
   // Add an edge from CurMBB to NewMBB for the fall-through.
   MBB->addSuccessor(NewMBB);
-  NewMBB->splice(NewMBB->end(), MBB, ++MBBI, MBB->end());  
+  NewMBB->splice(NewMBB->end(), MBB, ++MBBI, MBB->end());
   return true;
 }
 
index 280fd3ed52bdf036d15053c5eb3ddaa995945f5b..8c19b9f5a6249433d3c52d79904fcae0503d4f97 100644 (file)
@@ -503,3 +503,46 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
   Offset = (isSub) ? -Offset : Offset;
   return Offset == 0;
 }
+
+/// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
+/// two-addrss instruction inserted by two-address pass.
+void
+Thumb2InstrInfo::scheduleTwoAddrSource(MachineInstr *SrcMI,
+                                       MachineInstr *UseMI,
+                                       const TargetRegisterInfo &TRI) const {
+  if (SrcMI->getOpcode() != ARM::tMOVgpr2gpr ||
+      SrcMI->getOperand(1).isKill())
+    return;
+
+  unsigned PredReg = 0;
+  ARMCC::CondCodes CC = llvm::getInstrPredicate(UseMI, PredReg);
+  if (CC == ARMCC::AL || PredReg != ARM::CPSR)
+    return;
+
+  // Schedule the copy so it doesn't come between previous instructions
+  // and UseMI which can form an IT block.
+  unsigned SrcReg = SrcMI->getOperand(1).getReg();
+  ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
+  MachineBasicBlock *MBB = UseMI->getParent();
+  MachineBasicBlock::iterator MBBI = SrcMI;
+  unsigned NumInsts = 0;
+  while (--MBBI != MBB->begin()) {
+    if (MBBI->isDebugValue())
+      continue;
+
+    MachineInstr *NMI = &*MBBI;
+    ARMCC::CondCodes NCC = llvm::getInstrPredicate(NMI, PredReg);
+    if (!(NCC == CC || NCC == OCC) ||
+        NMI->modifiesRegister(SrcReg, &TRI) ||
+        NMI->definesRegister(ARM::CPSR))
+      break;
+    if (++NumInsts == 4)
+      // Too many in a row!
+      return;
+  }
+
+  if (NumInsts) {
+    MBB->remove(SrcMI);
+    MBB->insert(++MBBI, SrcMI);
+  }
+}
index 29487700d19bf2dd28f77b59a3ae471a34c6cc17..3f233c47868b216c314628cf1a4a958d072ed98b 100644 (file)
@@ -50,6 +50,11 @@ public:
                             const TargetRegisterClass *RC,
                             const TargetRegisterInfo *TRI) const;
 
+  /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
+  /// two-addrss instruction inserted by two-address pass.
+  void scheduleTwoAddrSource(MachineInstr *SrcMI, MachineInstr *UseMI,
+                             const TargetRegisterInfo &TRI) const;
+
   /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
   /// such, whenever a client has an instance of instruction info, it should
   /// always be able to get register info as well (through this method).