Cleanup of the [SU]ADDO type legalization code. Patch by Duncan!
[oota-llvm.git] / lib / CodeGen / LowerSubregs.cpp
index 1cdd34b77f456eeb21f6afe6dc1447b401a9c12f..6d7c5ccee6009657f43f9e5e2b5a18ff68687e0b 100644 (file)
@@ -6,6 +6,13 @@
 // 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.
+//
+//===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "lowersubregs"
 #include "llvm/CodeGen/Passes.h"
@@ -24,12 +31,18 @@ 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&);
     
@@ -51,9 +64,9 @@ bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
    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() &&
-          MI->getOperand(2).isImmediate() && "Malformed extract_subreg");
+   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();
@@ -89,10 +102,10 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) {
   MachineFunction &MF = *MBB->getParent();
   const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); 
   const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
-  assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
-         MI->getOperand(1).isImmediate() &&
-         (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
-          MI->getOperand(3).isImmediate() && "Invalid subreg_to_reg");
+  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();
@@ -108,15 +121,20 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) {
 
   DOUT << "subreg: CONVERTING: " << *MI;
 
-  // Insert sub-register copy
-  const TargetRegisterClass *TRC0= TRI.getPhysicalRegisterRegClass(DstSubReg);
-  const TargetRegisterClass *TRC1= TRI.getPhysicalRegisterRegClass(InsReg);
-  TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC0, TRC1);
+  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);
+    MachineBasicBlock::iterator dMI = MI;
+    DOUT << "subreg: " << *(--dMI);
 #endif
+  }
 
   DOUT << "\n";
   MBB->erase(MI);
@@ -128,13 +146,15 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
   MachineFunction &MF = *MBB->getParent();
   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()) &&
-         (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
-          MI->getOperand(3).isImmediate() && "Invalid insert_subreg");
+  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
   unsigned SrcReg = MI->getOperand(1).getReg();
+#endif
   unsigned InsReg = MI->getOperand(2).getReg();
   unsigned SubIdx = MI->getOperand(3).getImm();