- Eliminate MCCodeEmitter's dependency on TargetMachine. It now uses MCInstrInfo
[oota-llvm.git] / lib / Target / PTX / PTXInstrInfo.cpp
1 //===- PTXInstrInfo.cpp - PTX Instruction Information ---------------------===//
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 // This file contains the PTX implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "ptx-instrinfo"
15
16 #include "PTX.h"
17 #include "PTXInstrInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/SelectionDAGNodes.h"
21 #include "llvm/Target/TargetRegistry.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/raw_ostream.h"
24
25 #define GET_INSTRINFO_CTOR
26 #define GET_INSTRINFO_MC_DESC
27 #include "PTXGenInstrInfo.inc"
28
29 using namespace llvm;
30
31 PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
32   : PTXGenInstrInfo(),
33     RI(_TM, *this), TM(_TM) {}
34
35 static const struct map_entry {
36   const TargetRegisterClass *cls;
37   const int opcode;
38 } map[] = {
39   { &PTX::RegI16RegClass, PTX::MOVU16rr },
40   { &PTX::RegI32RegClass, PTX::MOVU32rr },
41   { &PTX::RegI64RegClass, PTX::MOVU64rr },
42   { &PTX::RegF32RegClass, PTX::MOVF32rr },
43   { &PTX::RegF64RegClass, PTX::MOVF64rr },
44   { &PTX::RegPredRegClass,   PTX::MOVPREDrr }
45 };
46
47 void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
48                                MachineBasicBlock::iterator I, DebugLoc DL,
49                                unsigned DstReg, unsigned SrcReg,
50                                bool KillSrc) const {
51   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
52     if (map[i].cls->contains(DstReg, SrcReg)) {
53       const MCInstrDesc &MCID = get(map[i].opcode);
54       MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).
55         addReg(SrcReg, getKillRegState(KillSrc));
56       AddDefaultPredicate(MI);
57       return;
58     }
59   }
60
61   llvm_unreachable("Impossible reg-to-reg copy");
62 }
63
64 bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
65                                 MachineBasicBlock::iterator I,
66                                 unsigned DstReg, unsigned SrcReg,
67                                 const TargetRegisterClass *DstRC,
68                                 const TargetRegisterClass *SrcRC,
69                                 DebugLoc DL) const {
70   if (DstRC != SrcRC)
71     return false;
72
73   for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
74     if (DstRC == map[i].cls) {
75       const MCInstrDesc &MCID = get(map[i].opcode);
76       MachineInstr *MI = BuildMI(MBB, I, DL, MCID, DstReg).addReg(SrcReg);
77       AddDefaultPredicate(MI);
78       return true;
79     }
80
81   return false;
82 }
83
84 bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
85                                unsigned &SrcReg, unsigned &DstReg,
86                                unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
87   switch (MI.getOpcode()) {
88     default:
89       return false;
90     case PTX::MOVU16rr:
91     case PTX::MOVU32rr:
92     case PTX::MOVU64rr:
93     case PTX::MOVF32rr:
94     case PTX::MOVF64rr:
95     case PTX::MOVPREDrr:
96       assert(MI.getNumOperands() >= 2 &&
97              MI.getOperand(0).isReg() && MI.getOperand(1).isReg() &&
98              "Invalid register-register move instruction");
99       SrcSubIdx = DstSubIdx = 0; // No sub-registers
100       DstReg = MI.getOperand(0).getReg();
101       SrcReg = MI.getOperand(1).getReg();
102       return true;
103   }
104 }
105
106 // predicate support
107
108 bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
109   int i = MI->findFirstPredOperandIdx();
110   return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
111 }
112
113 bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
114   return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
115 }
116
117 bool PTXInstrInfo::
118 PredicateInstruction(MachineInstr *MI,
119                      const SmallVectorImpl<MachineOperand> &Pred) const {
120   if (Pred.size() < 2)
121     llvm_unreachable("lesser than 2 predicate operands are provided");
122
123   int i = MI->findFirstPredOperandIdx();
124   if (i == -1)
125     llvm_unreachable("missing predicate operand");
126
127   MI->getOperand(i).setReg(Pred[0].getReg());
128   MI->getOperand(i+1).setImm(Pred[1].getImm());
129
130   return true;
131 }
132
133 bool PTXInstrInfo::
134 SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
135                   const SmallVectorImpl<MachineOperand> &Pred2) const {
136   const MachineOperand &PredReg1 = Pred1[0];
137   const MachineOperand &PredReg2 = Pred2[0];
138   if (PredReg1.getReg() != PredReg2.getReg())
139     return false;
140
141   const MachineOperand &PredOp1 = Pred1[1];
142   const MachineOperand &PredOp2 = Pred2[1];
143   if (PredOp1.getImm() != PredOp2.getImm())
144     return false;
145
146   return true;
147 }
148
149 bool PTXInstrInfo::
150 DefinesPredicate(MachineInstr *MI,
151                  std::vector<MachineOperand> &Pred) const {
152   // If an instruction sets a predicate register, it defines a predicate.
153
154   // TODO supprot 5-operand format of setp instruction
155
156   if (MI->getNumOperands() < 1)
157     return false;
158
159   const MachineOperand &MO = MI->getOperand(0);
160
161   if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::RegPredRegClass)
162     return false;
163
164   Pred.push_back(MO);
165   Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL));
166   return true;
167 }
168
169 // branch support
170
171 bool PTXInstrInfo::
172 AnalyzeBranch(MachineBasicBlock &MBB,
173               MachineBasicBlock *&TBB,
174               MachineBasicBlock *&FBB,
175               SmallVectorImpl<MachineOperand> &Cond,
176               bool AllowModify) const {
177   // TODO implement cases when AllowModify is true
178
179   if (MBB.empty())
180     return true;
181
182   MachineBasicBlock::const_iterator iter = MBB.end();
183   const MachineInstr& instLast1 = *--iter;
184   const MCInstrDesc &desc1 = instLast1.getDesc();
185   // for special case that MBB has only 1 instruction
186   const bool IsSizeOne = MBB.size() == 1;
187   // if IsSizeOne is true, *--iter and instLast2 are invalid
188   // we put a dummy value in instLast2 and desc2 since they are used
189   const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter;
190   const MCInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();
191
192   DEBUG(dbgs() << "\n");
193   DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n");
194   DEBUG(dbgs() << "AnalyzeBranch: MBB:    " << MBB.getName().str() << "\n");
195   DEBUG(dbgs() << "AnalyzeBranch: TBB:    " << TBB << "\n");
196   DEBUG(dbgs() << "AnalyzeBranch: FBB:    " << FBB << "\n");
197
198   // this block ends with no branches
199   if (!IsAnyKindOfBranch(instLast1)) {
200     DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n");
201     return false;
202   }
203
204   // this block ends with only an unconditional branch
205   if (desc1.isUnconditionalBranch() &&
206       // when IsSizeOne is true, it "absorbs" the evaluation of instLast2
207       (IsSizeOne || !IsAnyKindOfBranch(instLast2))) {
208     DEBUG(dbgs() << "AnalyzeBranch: ends with only uncond branch\n");
209     TBB = GetBranchTarget(instLast1);
210     return false;
211   }
212
213   // this block ends with a conditional branch and
214   // it falls through to a successor block
215   if (desc1.isConditionalBranch() &&
216       IsAnySuccessorAlsoLayoutSuccessor(MBB)) {
217     DEBUG(dbgs() << "AnalyzeBranch: ends with cond branch and fall through\n");
218     TBB = GetBranchTarget(instLast1);
219     int i = instLast1.findFirstPredOperandIdx();
220     Cond.push_back(instLast1.getOperand(i));
221     Cond.push_back(instLast1.getOperand(i+1));
222     return false;
223   }
224
225   // when IsSizeOne is true, we are done
226   if (IsSizeOne)
227     return true;
228
229   // this block ends with a conditional branch
230   // followed by an unconditional branch
231   if (desc2.isConditionalBranch() &&
232       desc1.isUnconditionalBranch()) {
233     DEBUG(dbgs() << "AnalyzeBranch: ends with cond and uncond branch\n");
234     TBB = GetBranchTarget(instLast2);
235     FBB = GetBranchTarget(instLast1);
236     int i = instLast2.findFirstPredOperandIdx();
237     Cond.push_back(instLast2.getOperand(i));
238     Cond.push_back(instLast2.getOperand(i+1));
239     return false;
240   }
241
242   // branch cannot be understood
243   DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
244   return true;
245 }
246
247 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
248   unsigned count = 0;
249   while (!MBB.empty())
250     if (IsAnyKindOfBranch(MBB.back())) {
251       MBB.pop_back();
252       ++count;
253     } else
254       break;
255   DEBUG(dbgs() << "RemoveBranch: MBB:   " << MBB.getName().str() << "\n");
256   DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
257   return count;
258 }
259
260 unsigned PTXInstrInfo::
261 InsertBranch(MachineBasicBlock &MBB,
262              MachineBasicBlock *TBB,
263              MachineBasicBlock *FBB,
264              const SmallVectorImpl<MachineOperand> &Cond,
265              DebugLoc DL) const {
266   DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
267   DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
268                         << "\n";
269         else     dbgs() << "InsertBranch: TBB: (NULL)\n");
270   DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
271                         << "\n";
272         else     dbgs() << "InsertBranch: FBB: (NULL)\n");
273   DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
274
275   assert(TBB && "TBB is NULL");
276
277   if (FBB) {
278     BuildMI(&MBB, DL, get(PTX::BRAdp))
279       .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
280     BuildMI(&MBB, DL, get(PTX::BRAd))
281       .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
282     return 2;
283   } else if (Cond.size()) {
284     BuildMI(&MBB, DL, get(PTX::BRAdp))
285       .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
286     return 1;
287   } else {
288     BuildMI(&MBB, DL, get(PTX::BRAd))
289       .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
290     return 1;
291   }
292 }
293
294 // Memory operand folding for spills
295 void PTXInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
296                                        MachineBasicBlock::iterator MII,
297                                      unsigned SrcReg, bool isKill, int FrameIdx,
298                                        const TargetRegisterClass *RC,
299                                        const TargetRegisterInfo *TRI) const {
300   MachineInstr& MI = *MII;
301   DebugLoc DL = MI.getDebugLoc();
302
303   DEBUG(dbgs() << "storeRegToStackSlot: " << MI);
304
305   int OpCode;
306
307   // Select the appropriate opcode based on the register class
308   if (RC == PTX::RegI16RegisterClass) {
309     OpCode = PTX::STACKSTOREI16;
310   }  else if (RC == PTX::RegI32RegisterClass) {
311     OpCode = PTX::STACKSTOREI32;
312   }  else if (RC == PTX::RegI64RegisterClass) {
313     OpCode = PTX::STACKSTOREI32;
314   }  else if (RC == PTX::RegF32RegisterClass) {
315     OpCode = PTX::STACKSTOREF32;
316   }  else if (RC == PTX::RegF64RegisterClass) {
317     OpCode = PTX::STACKSTOREF64;
318   } else {
319     llvm_unreachable("Unknown PTX register class!");
320   }
321
322   // Build the store instruction (really a mov)
323   MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
324   MIB.addFrameIndex(FrameIdx);
325   MIB.addReg(SrcReg);
326
327   AddDefaultPredicate(MIB);
328 }
329
330 void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
331                                         MachineBasicBlock::iterator MII,
332                                         unsigned DestReg, int FrameIdx,
333                                         const TargetRegisterClass *RC,
334                                         const TargetRegisterInfo *TRI) const {
335   MachineInstr& MI = *MII;
336   DebugLoc DL = MI.getDebugLoc();
337
338   DEBUG(dbgs() << "loadRegToStackSlot: " << MI);
339
340   int OpCode;
341
342   // Select the appropriate opcode based on the register class
343   if (RC == PTX::RegI16RegisterClass) {
344     OpCode = PTX::STACKLOADI16;
345   } else if (RC == PTX::RegI32RegisterClass) {
346     OpCode = PTX::STACKLOADI32;
347   } else if (RC == PTX::RegI64RegisterClass) {
348     OpCode = PTX::STACKLOADI32;
349   } else if (RC == PTX::RegF32RegisterClass) {
350     OpCode = PTX::STACKLOADF32;
351   } else if (RC == PTX::RegF64RegisterClass) {
352     OpCode = PTX::STACKLOADF64;
353   } else {
354     llvm_unreachable("Unknown PTX register class!");
355   }
356
357   // Build the load instruction (really a mov)
358   MachineInstrBuilder MIB = BuildMI(MBB, MII, DL, get(OpCode));
359   MIB.addReg(DestReg);
360   MIB.addFrameIndex(FrameIdx);
361
362   AddDefaultPredicate(MIB);
363 }
364
365 // static helper routines
366
367 MachineSDNode *PTXInstrInfo::
368 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
369                   DebugLoc dl, EVT VT, SDValue Op1) {
370   SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
371   SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
372   SDValue ops[] = { Op1, predReg, predOp };
373   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
374 }
375
376 MachineSDNode *PTXInstrInfo::
377 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
378                   DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
379   SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
380   SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
381   SDValue ops[] = { Op1, Op2, predReg, predOp };
382   return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
383 }
384
385 void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
386   if (MI->findFirstPredOperandIdx() == -1) {
387     MI->addOperand(MachineOperand::CreateReg(PTX::NoRegister, /*IsDef=*/false));
388     MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL));
389   }
390 }
391
392 bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
393   const MCInstrDesc &desc = inst.getDesc();
394   return desc.isTerminator() || desc.isBranch() || desc.isIndirectBranch();
395 }
396
397 bool PTXInstrInfo::
398 IsAnySuccessorAlsoLayoutSuccessor(const MachineBasicBlock& MBB) {
399   for (MachineBasicBlock::const_succ_iterator
400       i = MBB.succ_begin(), e = MBB.succ_end(); i != e; ++i)
401     if (MBB.isLayoutSuccessor((const MachineBasicBlock*) &*i))
402       return true;
403   return false;
404 }
405
406 MachineBasicBlock *PTXInstrInfo::GetBranchTarget(const MachineInstr& inst) {
407   // FIXME So far all branch instructions put destination in 1st operand
408   const MachineOperand& target = inst.getOperand(0);
409   assert(target.isMBB() && "FIXME: detect branch target operand");
410   return target.getMBB();
411 }
412
413 MCInstrInfo *createPTXMCInstrInfo() {
414   MCInstrInfo *X = new MCInstrInfo();
415   InitPTXMCInstrInfo(X);
416   return X;
417 }
418
419 extern "C" void LLVMInitializePTXMCInstrInfo() {
420   TargetRegistry::RegisterMCInstrInfo(ThePTX32Target, createPTXMCInstrInfo);
421   TargetRegistry::RegisterMCInstrInfo(ThePTX64Target, createPTXMCInstrInfo);
422 }