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