Recommitting parts of r48130. These do not appear to cause the observed failures.
[oota-llvm.git] / lib / CodeGen / LowerSubregs.cpp
1 //===-- LowerSubregs.cpp - Subregister Lowering instruction pass ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #define DEBUG_TYPE "lowersubregs"
11 #include "llvm/CodeGen/Passes.h"
12 #include "llvm/Function.h"
13 #include "llvm/CodeGen/MachineFunctionPass.h"
14 #include "llvm/CodeGen/MachineInstr.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 #include "llvm/Target/TargetRegisterInfo.h"
17 #include "llvm/Target/TargetInstrInfo.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/Compiler.h"
21 using namespace llvm;
22
23 namespace {
24   struct VISIBILITY_HIDDEN LowerSubregsInstructionPass
25    : public MachineFunctionPass {
26     static char ID; // Pass identification, replacement for typeid
27     LowerSubregsInstructionPass() : MachineFunctionPass((intptr_t)&ID) {}
28     
29     const char *getPassName() const {
30       return "Subregister lowering instruction pass";
31     }
32
33     /// runOnMachineFunction - pass entry point
34     bool runOnMachineFunction(MachineFunction&);
35     
36     bool LowerExtract(MachineInstr *MI);
37     bool LowerInsert(MachineInstr *MI);
38   };
39
40   char LowerSubregsInstructionPass::ID = 0;
41 }
42
43 FunctionPass *llvm::createLowerSubregsPass() { 
44   return new LowerSubregsInstructionPass(); 
45 }
46
47 bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
48    MachineBasicBlock *MBB = MI->getParent();
49    MachineFunction &MF = *MBB->getParent();
50    const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo();
51    const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
52    
53    assert(MI->getOperand(0).isRegister() && MI->getOperand(0).isDef() &&
54           MI->getOperand(1).isRegister() && MI->getOperand(1).isUse() &&
55           MI->getOperand(2).isImmediate() && "Malformed extract_subreg");
56
57    unsigned SuperReg = MI->getOperand(1).getReg();
58    unsigned SubIdx = MI->getOperand(2).getImm();
59
60    assert(TargetRegisterInfo::isPhysicalRegister(SuperReg) &&
61           "Extract supperg source must be a physical register");
62    unsigned SrcReg = TRI.getSubReg(SuperReg, SubIdx);
63    unsigned DstReg = MI->getOperand(0).getReg();
64
65    DOUT << "subreg: CONVERTING: " << *MI;
66
67    if (SrcReg != DstReg) {
68      const TargetRegisterClass *TRC = 0;
69      if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
70        TRC = TRI.getPhysicalRegisterRegClass(DstReg);
71      } else {
72        TRC = MF.getRegInfo().getRegClass(DstReg);
73      }
74      assert(TRC == TRI.getPhysicalRegisterRegClass(SrcReg) &&
75              "Extract subreg and Dst must be of same register class");
76
77      TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC, TRC);
78      MachineBasicBlock::iterator dMI = MI;
79      DOUT << "subreg: " << *(--dMI);
80    }
81
82    DOUT << "\n";
83    MBB->remove(MI);
84    return true;
85 }
86
87
88 bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) {
89   MachineBasicBlock *MBB = MI->getParent();
90   MachineFunction &MF = *MBB->getParent();
91   const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); 
92   const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
93   assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
94          ((MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) || 
95             MI->getOperand(1).isImmediate()) &&
96          (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
97           MI->getOperand(3).isImmediate() && "Invalid insert_subreg");
98           
99   unsigned DstReg = MI->getOperand(0).getReg();
100   unsigned SrcReg = 0;
101   // Check if we're inserting into an implicit value.
102   if (MI->getOperand(1).isImmediate())
103     SrcReg = DstReg;
104   else
105     SrcReg = MI->getOperand(1).getReg();
106   unsigned InsReg = MI->getOperand(2).getReg();
107   unsigned SubIdx = MI->getOperand(3).getImm();     
108
109   assert(SubIdx != 0 && "Invalid index for extract_subreg");
110   unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
111
112   assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
113          "Insert superreg source must be in a physical register");
114   assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
115          "Insert destination must be in a physical register");
116   assert(TargetRegisterInfo::isPhysicalRegister(InsReg) &&
117          "Inserted value must be in a physical register");
118
119   DOUT << "subreg: CONVERTING: " << *MI;
120        
121   // If the inserted register is already allocated into a subregister
122   // of the destination, we copy the subreg into the source
123   // However, this is only safe if the insert instruction is the kill
124   // of the source register
125   bool revCopyOrder = TRI.isSubRegister(DstReg, InsReg);
126   if (revCopyOrder && InsReg != DstSubReg) {
127     if (MI->getOperand(1).isKill()) {
128       DstSubReg = TRI.getSubReg(SrcReg, SubIdx);
129       // Insert sub-register copy
130       const TargetRegisterClass *TRC1 = 0;
131       if (TargetRegisterInfo::isPhysicalRegister(InsReg)) {
132         TRC1 = TRI.getPhysicalRegisterRegClass(InsReg);
133       } else {
134         TRC1 = MF.getRegInfo().getRegClass(InsReg);
135       }
136       TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1);
137
138 #ifndef NDEBUG
139       MachineBasicBlock::iterator dMI = MI;
140       DOUT << "subreg: " << *(--dMI);
141 #endif
142     } else {
143       assert(0 && "Don't know how to convert this insert");
144     }
145   }
146 #ifndef NDEBUG
147   if (InsReg == DstSubReg) {
148      DOUT << "subreg: Eliminated subreg copy\n";
149   }
150 #endif
151
152   if (SrcReg != DstReg) {
153     // Insert super-register copy
154     const TargetRegisterClass *TRC0 = 0;
155     if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
156       TRC0 = TRI.getPhysicalRegisterRegClass(DstReg);
157     } else {
158       TRC0 = MF.getRegInfo().getRegClass(DstReg);
159     }
160     assert(TRC0 == TRI.getPhysicalRegisterRegClass(SrcReg) &&
161             "Insert superreg and Dst must be of same register class");
162
163     TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0, TRC0);
164
165 #ifndef NDEBUG
166     MachineBasicBlock::iterator dMI = MI;
167     DOUT << "subreg: " << *(--dMI);
168 #endif
169   }
170   
171 #ifndef NDEBUG
172   if (SrcReg == DstReg) {
173      DOUT << "subreg: Eliminated superreg copy\n";
174   }
175 #endif
176
177   if (!revCopyOrder && InsReg != DstSubReg) {
178     // Insert sub-register copy
179     const TargetRegisterClass *TRC1 = 0;
180     if (TargetRegisterInfo::isPhysicalRegister(InsReg)) {
181       TRC1 = TRI.getPhysicalRegisterRegClass(InsReg);
182     } else {
183       TRC1 = MF.getRegInfo().getRegClass(InsReg);
184     }
185     TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1);
186
187 #ifndef NDEBUG
188     MachineBasicBlock::iterator dMI = MI;
189     DOUT << "subreg: " << *(--dMI);
190 #endif
191   }
192
193   DOUT << "\n";
194   MBB->remove(MI);
195   return true;                    
196 }
197
198 /// runOnMachineFunction - Reduce subregister inserts and extracts to register
199 /// copies.
200 ///
201 bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) {
202   DOUT << "Machine Function\n";
203   
204   bool MadeChange = false;
205
206   DOUT << "********** LOWERING SUBREG INSTRS **********\n";
207   DOUT << "********** Function: " << MF.getFunction()->getName() << '\n';
208
209   for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end();
210        mbbi != mbbe; ++mbbi) {
211     for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end();
212          mi != me;) {
213       MachineInstr *MI = mi++;
214            
215       if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
216         MadeChange |= LowerExtract(MI);
217       } else if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
218         MadeChange |= LowerInsert(MI);
219       }
220     }
221   }
222
223   return MadeChange;
224 }