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