1 //===- PTXInstrInfo.cpp - PTX Instruction Information ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the PTX implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "ptx-instrinfo"
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"
26 #define GET_INSTRINFO_CTOR
27 #include "PTXGenInstrInfo.inc"
31 PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
33 RI(_TM, *this), TM(_TM) {}
35 static const struct map_entry {
36 const TargetRegisterClass *cls;
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 }
47 void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
48 MachineBasicBlock::iterator I, DebugLoc DL,
49 unsigned DstReg, unsigned SrcReg,
52 const MachineRegisterInfo& MRI = MBB.getParent()->getRegInfo();
53 //assert(MRI.getRegClass(SrcReg) == MRI.getRegClass(DstReg) &&
54 // "Invalid register copy between two register classes");
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);
66 llvm_unreachable("Impossible reg-to-reg copy");
69 bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
70 MachineBasicBlock::iterator I,
71 unsigned DstReg, unsigned SrcReg,
72 const TargetRegisterClass *DstRC,
73 const TargetRegisterClass *SrcRC,
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);
89 bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
90 unsigned &SrcReg, unsigned &DstReg,
91 unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
92 switch (MI.getOpcode()) {
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();
113 bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
114 int i = MI->findFirstPredOperandIdx();
115 return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
118 bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
119 return !isPredicated(MI) && MI->isTerminator();
123 PredicateInstruction(MachineInstr *MI,
124 const SmallVectorImpl<MachineOperand> &Pred) const {
126 llvm_unreachable("lesser than 2 predicate operands are provided");
128 int i = MI->findFirstPredOperandIdx();
130 llvm_unreachable("missing predicate operand");
132 MI->getOperand(i).setReg(Pred[0].getReg());
133 MI->getOperand(i+1).setImm(Pred[1].getImm());
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())
146 const MachineOperand &PredOp1 = Pred1[1];
147 const MachineOperand &PredOp2 = Pred2[1];
148 if (PredOp1.getImm() != PredOp2.getImm())
155 DefinesPredicate(MachineInstr *MI,
156 std::vector<MachineOperand> &Pred) const {
157 // If an instruction sets a predicate register, it defines a predicate.
159 // TODO supprot 5-operand format of setp instruction
161 if (MI->getNumOperands() < 1)
164 const MachineOperand &MO = MI->getOperand(0);
166 if (!MO.isReg() || RI.getRegClass(MO.getReg()) != &PTX::RegPredRegClass)
170 Pred.push_back(MachineOperand::CreateImm(PTXPredicate::None));
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
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;
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");
201 // this block ends with no branches
202 if (!IsAnyKindOfBranch(instLast1)) {
203 DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n");
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);
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));
228 // when IsSizeOne is true, we are done
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));
245 // branch cannot be understood
246 DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
250 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
253 if (IsAnyKindOfBranch(MBB.back())) {
258 DEBUG(dbgs() << "RemoveBranch: MBB: " << MBB.getName().str() << "\n");
259 DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n");
263 unsigned PTXInstrInfo::
264 InsertBranch(MachineBasicBlock &MBB,
265 MachineBasicBlock *TBB,
266 MachineBasicBlock *FBB,
267 const SmallVectorImpl<MachineOperand> &Cond,
269 DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
270 DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str()
272 else dbgs() << "InsertBranch: TBB: (NULL)\n");
273 DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str()
275 else dbgs() << "InsertBranch: FBB: (NULL)\n");
276 DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
278 assert(TBB && "TBB is NULL");
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);
286 } else if (Cond.size()) {
287 BuildMI(&MBB, DL, get(PTX::BRAdp))
288 .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
291 BuildMI(&MBB, DL, get(PTX::BRAd))
292 .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTXPredicate::None);
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 assert(false && "storeRegToStackSlot should not be called for PTX");
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 assert(false && "loadRegFromStackSlot should not be called for PTX");
314 // static helper routines
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));
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));
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));
341 bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
342 return inst.isTerminator() || inst.isBranch() || inst.isIndirectBranch();
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))
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();