Use TargetRegisterInfo::getPhysicalRegisterRegClass. Remove duplicated code.
[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   unsigned DstReg = 0;
94   unsigned SrcReg = 0;
95   unsigned InsReg = 0;
96   unsigned SubIdx = 0;
97
98   // If only have 3 operands, then the source superreg is undef
99   // and we can supress the copy from the undef value
100   if (MI->getNumOperands() == 3) {
101     assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
102            (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
103             MI->getOperand(2).isImmediate() && "Invalid extract_subreg");
104     DstReg = MI->getOperand(0).getReg();
105     SrcReg = DstReg;
106     InsReg = MI->getOperand(1).getReg();
107     SubIdx = MI->getOperand(2).getImm();
108   } else if (MI->getNumOperands() == 4) {
109     assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) &&
110            (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) &&
111            (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
112             MI->getOperand(3).isImmediate() && "Invalid extract_subreg");
113     DstReg = MI->getOperand(0).getReg();
114     SrcReg = MI->getOperand(1).getReg();
115     InsReg = MI->getOperand(2).getReg();
116     SubIdx = MI->getOperand(3).getImm();     
117   } else 
118     assert(0 && "Malformed extract_subreg");
119
120   assert(SubIdx != 0 && "Invalid index for extract_subreg");
121   unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx);
122
123   assert(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
124          "Insert superreg source must be in a physical register");
125   assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
126          "Insert destination must be in a physical register");
127   assert(TargetRegisterInfo::isPhysicalRegister(InsReg) &&
128          "Inserted value must be in a physical register");
129
130   DOUT << "subreg: CONVERTING: " << *MI;
131        
132   // If the inserted register is already allocated into a subregister
133   // of the destination, we copy the subreg into the source
134   // However, this is only safe if the insert instruction is the kill
135   // of the source register
136   bool revCopyOrder = TRI.isSubRegister(DstReg, InsReg);
137   if (revCopyOrder && InsReg != DstSubReg) {
138     if (MI->getOperand(1).isKill()) {
139       DstSubReg = TRI.getSubReg(SrcReg, SubIdx);
140       // Insert sub-register copy
141       const TargetRegisterClass *TRC1 = 0;
142       if (TargetRegisterInfo::isPhysicalRegister(InsReg)) {
143         TRC1 = TRI.getPhysicalRegisterRegClass(InsReg);
144       } else {
145         TRC1 = MF.getRegInfo().getRegClass(InsReg);
146       }
147       TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1);
148
149 #ifndef NDEBUG
150       MachineBasicBlock::iterator dMI = MI;
151       DOUT << "subreg: " << *(--dMI);
152 #endif
153     } else {
154       assert(0 && "Don't know how to convert this insert");
155     }
156   }
157 #ifndef NDEBUG
158   if (InsReg == DstSubReg) {
159      DOUT << "subreg: Eliminated subreg copy\n";
160   }
161 #endif
162
163   if (SrcReg != DstReg) {
164     // Insert super-register copy
165     const TargetRegisterClass *TRC0 = 0;
166     if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
167       TRC0 = TRI.getPhysicalRegisterRegClass(DstReg);
168     } else {
169       TRC0 = MF.getRegInfo().getRegClass(DstReg);
170     }
171     assert(TRC0 == TRI.getPhysicalRegisterRegClass(SrcReg) &&
172             "Insert superreg and Dst must be of same register class");
173
174     TII.copyRegToReg(*MBB, MI, DstReg, SrcReg, TRC0, TRC0);
175
176 #ifndef NDEBUG
177     MachineBasicBlock::iterator dMI = MI;
178     DOUT << "subreg: " << *(--dMI);
179 #endif
180   }
181   
182 #ifndef NDEBUG
183   if (SrcReg == DstReg) {
184      DOUT << "subreg: Eliminated superreg copy\n";
185   }
186 #endif
187
188   if (!revCopyOrder && InsReg != DstSubReg) {
189     // Insert sub-register copy
190     const TargetRegisterClass *TRC1 = 0;
191     if (TargetRegisterInfo::isPhysicalRegister(InsReg)) {
192       TRC1 = TRI.getPhysicalRegisterRegClass(InsReg);
193     } else {
194       TRC1 = MF.getRegInfo().getRegClass(InsReg);
195     }
196     TII.copyRegToReg(*MBB, MI, DstSubReg, InsReg, TRC1, TRC1);
197
198 #ifndef NDEBUG
199     MachineBasicBlock::iterator dMI = MI;
200     DOUT << "subreg: " << *(--dMI);
201 #endif
202   }
203
204   DOUT << "\n";
205   MBB->remove(MI);
206   return true;                    
207 }
208
209 /// runOnMachineFunction - Reduce subregister inserts and extracts to register
210 /// copies.
211 ///
212 bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) {
213   DOUT << "Machine Function\n";
214   
215   bool MadeChange = false;
216
217   DOUT << "********** LOWERING SUBREG INSTRS **********\n";
218   DOUT << "********** Function: " << MF.getFunction()->getName() << '\n';
219
220   for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end();
221        mbbi != mbbe; ++mbbi) {
222     for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end();
223          mi != me;) {
224       MachineInstr *MI = mi++;
225            
226       if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
227         MadeChange |= LowerExtract(MI);
228       } else if (MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
229         MadeChange |= LowerInsert(MI);
230       }
231     }
232   }
233
234   return MadeChange;
235 }