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