Cleanup of the [SU]ADDO type legalization code. Patch by Duncan!
[oota-llvm.git] / lib / CodeGen / LowerSubregs.cpp
index dbf7968a744636997052f8747d89c856b715488b..6d7c5ccee6009657f43f9e5e2b5a18ff68687e0b 100644 (file)
@@ -2,8 +2,15 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Christopher Lamb and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a MachineFunction pass which runs after register
+// allocation that turns subreg insert/extract instructions into register
+// copies, as needed. This ensures correct codegen even if the coalescer
+// isn't able to remove all subreg instructions.
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,8 +19,8 @@
 #include "llvm/Function.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/SSARegMap.h"
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/Debug.h"
@@ -24,17 +31,24 @@ namespace {
   struct VISIBILITY_HIDDEN LowerSubregsInstructionPass
    : public MachineFunctionPass {
     static char ID; // Pass identification, replacement for typeid
-    LowerSubregsInstructionPass() : MachineFunctionPass((intptr_t)&ID) {}
+    LowerSubregsInstructionPass() : MachineFunctionPass(&ID) {}
     
     const char *getPassName() const {
       return "Subregister lowering instruction pass";
     }
 
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addPreservedID(MachineLoopInfoID);
+      AU.addPreservedID(MachineDominatorsID);
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+
     /// runOnMachineFunction - pass entry point
     bool runOnMachineFunction(MachineFunction&);
     
     bool LowerExtract(MachineInstr *MI);
     bool LowerInsert(MachineInstr *MI);
+    bool LowerSubregToReg(MachineInstr *MI);
   };
 
   char LowerSubregsInstructionPass::ID = 0;
@@ -44,170 +58,125 @@ FunctionPass *llvm::createLowerSubregsPass() {
   return new LowerSubregsInstructionPass(); 
 }
 
-// Returns the Register Class of a physical register.
-static const TargetRegisterClass *getPhysicalRegisterRegClass(
-        const MRegisterInfo &MRI,
-        unsigned reg) {
-  assert(MRegisterInfo::isPhysicalRegister(reg) &&
-         "reg must be a physical register");
-  // Pick the register class of the right type that contains this physreg.
-  for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(),
-         E = MRI.regclass_end(); I != E; ++I)
-    if ((*I)->contains(reg))
-      return *I;
-  assert(false && "Couldn't find the register class");
-  return 0;
-}
-
 bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
    MachineBasicBlock *MBB = MI->getParent();
    MachineFunction &MF = *MBB->getParent();
-   const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo();
+   const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();
+   const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
    
-   assert(MI->getOperand(0).isRegister() && MI->getOperand(0).isDef() &&
-          MI->getOperand(1).isRegister() && MI->getOperand(1).isUse() &&
+   assert(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
+          MI->getOperand(1).isReg() && MI->getOperand(1).isUse() &&
           MI->getOperand(2).isImm() && "Malformed extract_subreg");
 
+   unsigned DstReg   = MI->getOperand(0).getReg();
    unsigned SuperReg = MI->getOperand(1).getReg();
-   unsigned SubIdx = MI->getOperand(2).getImm();
+   unsigned SubIdx   = MI->getOperand(2).getImm();
+   unsigned SrcReg   = TRI.getSubReg(SuperReg, SubIdx);
 
-   assert(MRegisterInfo::isPhysicalRegister(SuperReg) &&
+   assert(TargetRegisterInfo::isPhysicalRegister(SuperReg) &&
           "Extract supperg source must be a physical register");
-   unsigned SrcReg = MRI.getSubReg(SuperReg, SubIdx);
-   unsigned DstReg = MI->getOperand(0).getReg();
-
+   assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
+          "Insert destination must be in a physical register");
+          
    DOUT << "subreg: CONVERTING: " << *MI;
 
    if (SrcReg != DstReg) {
-     const TargetRegisterClass *TRC = 0;
-     if (MRegisterInfo::isPhysicalRegister(DstReg)) {
-       TRC = getPhysicalRegisterRegClass(MRI, DstReg);
-     } else {
-       TRC = MF.getSSARegMap()->getRegClass(DstReg);
-     }
-     assert(TRC == getPhysicalRegisterRegClass(MRI, SrcReg) &&
+     const TargetRegisterClass *TRC = TRI.getPhysicalRegisterRegClass(DstReg);
+     assert(TRC == TRI.getPhysicalRegisterRegClass(SrcReg) &&
              "Extract subreg and Dst must be of same register class");
-
-     MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC);
+     TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC, TRC);
+     
+#ifndef NDEBUG
      MachineBasicBlock::iterator dMI = MI;
      DOUT << "subreg: " << *(--dMI);
+#endif
    }
 
    DOUT << "\n";
-   MBB->remove(MI);
+   MBB->erase(MI);
    return true;
 }
 
-
-bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
+bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) {
   MachineBasicBlock *MBB = MI->getParent();
   MachineFunction &MF = *MBB->getParent();
-  const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo(); 
-  unsigned DstReg = 0;
-  unsigned SrcReg = 0;
-  unsigned InsReg = 0;
-  unsigned SubIdx = 0;
-
-  // If only have 3 operands, then the source superreg is undef
-  // and we can supress the copy from the undef value
-  if (MI->getNumOperands() == 3) {
-    assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
-           (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
-            MI->getOperand(2).isImm() && "Invalid extract_subreg");
-    DstReg = MI->getOperand(0).getReg();
-    SrcReg = DstReg;
-    InsReg = MI->getOperand(1).getReg();
-    SubIdx = MI->getOperand(2).getImm();
-  } else if (MI->getNumOperands() == 4) {
-    assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
-           (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
-           (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
-            MI->getOperand(3).isImm() && "Invalid extract_subreg");
-    DstReg = MI->getOperand(0).getReg();
-    SrcReg = MI->getOperand(1).getReg();
-    InsReg = MI->getOperand(2).getReg();
-    SubIdx = MI->getOperand(3).getImm();     
-  } else 
-    assert(0 && "Malformed extract_subreg");
-
-  assert(SubIdx != 0 && "Invalid index for extract_subreg");
-  unsigned DstSubReg = MRI.getSubReg(DstReg, SubIdx);
-
-  assert(MRegisterInfo::isPhysicalRegister(SrcReg) &&
-         "Insert superreg source must be in a physical register");
-  assert(MRegisterInfo::isPhysicalRegister(DstReg) &&
+  const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); 
+  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
+  assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&
+         MI->getOperand(1).isImm() &&
+         (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) &&
+          MI->getOperand(3).isImm() && "Invalid subreg_to_reg");
+          
+  unsigned DstReg  = MI->getOperand(0).getReg();
+  unsigned InsReg  = MI->getOperand(2).getReg();
+  unsigned SubIdx  = MI->getOperand(3).getImm();     
+
+  assert(SubIdx != 0 && "Invalid index for insert_subreg");
+  unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
+  
+  assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
          "Insert destination must be in a physical register");
-  assert(MRegisterInfo::isPhysicalRegister(InsReg) &&
+  assert(TargetRegisterInfo::isPhysicalRegister(InsReg) &&
          "Inserted value must be in a physical register");
 
   DOUT << "subreg: CONVERTING: " << *MI;
-       
-  // If the inserted register is already allocated into a subregister
-  // of the destination, we copy the subreg into the source
-  // However, this is only safe if the insert instruction is the kill
-  // of the source register
-  bool revCopyOrder = MRI.isSubRegOf(InsReg, DstReg);    
-  if (revCopyOrder && InsReg != DstSubReg) {
-    if (MI->getOperand(1).isKill()) {
-      DstSubReg = MRI.getSubReg(SrcReg, SubIdx);
-      // Insert sub-register copy
-      const TargetRegisterClass *TRC1 = 0;
-      if (MRegisterInfo::isPhysicalRegister(InsReg)) {
-        TRC1 = getPhysicalRegisterRegClass(MRI, InsReg);
-      } else {
-        TRC1 = MF.getSSARegMap()->getRegClass(InsReg);
-      }
-      MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1);
 
-#ifndef NDEBUG
-      MachineBasicBlock::iterator dMI = MI;
-      DOUT << "subreg: " << *(--dMI);
-#endif
-    } else {
-      assert(0 && "Don't know how to convert this insert");
-    }
-  }
-#ifndef NDEBUG
-  if (InsReg == DstSubReg) {
-     DOUT << "subreg: Eliminated subreg copy\n";
-  }
-#endif
-
-  if (SrcReg != DstReg) {
-    // Insert super-register copy
-    const TargetRegisterClass *TRC0 = 0;
-    if (MRegisterInfo::isPhysicalRegister(DstReg)) {
-      TRC0 = getPhysicalRegisterRegClass(MRI, DstReg);
-    } else {
-      TRC0 = MF.getSSARegMap()->getRegClass(DstReg);
-    }
-    assert(TRC0 == getPhysicalRegisterRegClass(MRI, SrcReg) &&
-            "Insert superreg and Dst must be of same register class");
-
-    MRI.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0);
+  if (DstSubReg == InsReg) {
+    // No need to insert an identify copy instruction.
+    DOUT << "subreg: eliminated!";
+  } else {
+    // Insert sub-register copy
+    const TargetRegisterClass *TRC0= TRI.getPhysicalRegisterRegClass(DstSubReg);
+    const TargetRegisterClass *TRC1= TRI.getPhysicalRegisterRegClass(InsReg);
+    TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1);
 
 #ifndef NDEBUG
     MachineBasicBlock::iterator dMI = MI;
     DOUT << "subreg: " << *(--dMI);
 #endif
   }
-  
+
+  DOUT << "\n";
+  MBB->erase(MI);
+  return true;                    
+}
+
+bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
+  MachineBasicBlock *MBB = MI->getParent();
+  MachineFunction &MF = *MBB->getParent();
+  const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); 
+  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
+  assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&
+         (MI->getOperand(1).isReg() && MI->getOperand(1).isUse()) &&
+         (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) &&
+          MI->getOperand(3).isImm() && "Invalid insert_subreg");
+          
+  unsigned DstReg = MI->getOperand(0).getReg();
 #ifndef NDEBUG
-  if (SrcReg == DstReg) {
-     DOUT << "subreg: Eliminated superreg copy\n";
-  }
+  unsigned SrcReg = MI->getOperand(1).getReg();
 #endif
+  unsigned InsReg = MI->getOperand(2).getReg();
+  unsigned SubIdx = MI->getOperand(3).getImm();     
 
-  if (!revCopyOrder && InsReg != DstSubReg) {
-    // Insert sub-register copy
-    const TargetRegisterClass *TRC1 = 0;
-    if (MRegisterInfo::isPhysicalRegister(InsReg)) {
-      TRC1 = getPhysicalRegisterRegClass(MRI, InsReg);
-    } else {
-      TRC1 = MF.getSSARegMap()->getRegClass(InsReg);
-    }
-    MRI.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1);
+  assert(DstReg == SrcReg && "insert_subreg not a two-address instruction?");
+  assert(SubIdx != 0 && "Invalid index for insert_subreg");
+  unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
+  
+  assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
+         "Insert superreg source must be in a physical register");
+  assert(TargetRegisterInfo::isPhysicalRegister(InsReg) &&
+         "Inserted value must be in a physical register");
 
+  DOUT << "subreg: CONVERTING: " << *MI;
+
+  if (DstSubReg == InsReg) {
+    // No need to insert an identify copy instruction.
+    DOUT << "subreg: eliminated!";
+  } else {
+    // Insert sub-register copy
+    const TargetRegisterClass *TRC0= TRI.getPhysicalRegisterRegClass(DstSubReg);
+    const TargetRegisterClass *TRC1= TRI.getPhysicalRegisterRegClass(InsReg);
+    TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1);
 #ifndef NDEBUG
     MachineBasicBlock::iterator dMI = MI;
     DOUT << "subreg: " << *(--dMI);
@@ -215,7 +184,7 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
   }
 
   DOUT << "\n";
-  MBB->remove(MI);
+  MBB->erase(MI);
   return true;                    
 }
 
@@ -240,6 +209,8 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) {
         MadeChange |= LowerExtract(MI);
       } else if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
         MadeChange |= LowerInsert(MI);
+      } else if (MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG) {
+        MadeChange |= LowerSubregToReg(MI);
       }
     }
   }