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/SelectionDAG.h"
20 #include "llvm/CodeGen/SelectionDAGNodes.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/raw_ostream.h"
26 #include "PTXGenInstrInfo.inc"
28 PTXInstrInfo::PTXInstrInfo(PTXTargetMachine &_TM)
29 : TargetInstrInfoImpl(PTXInsts, array_lengthof(PTXInsts)),
30 RI(_TM, *this), TM(_TM) {}
32 static const struct map_entry {
33 const TargetRegisterClass *cls;
36 { &PTX::RRegu16RegClass, PTX::MOVU16rr },
37 { &PTX::RRegu32RegClass, PTX::MOVU32rr },
38 { &PTX::RRegu64RegClass, PTX::MOVU64rr },
39 { &PTX::RRegf32RegClass, PTX::MOVF32rr },
40 { &PTX::RRegf64RegClass, PTX::MOVF64rr },
41 { &PTX::PredsRegClass, PTX::MOVPREDrr }
44 void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
45 MachineBasicBlock::iterator I, DebugLoc DL,
46 unsigned DstReg, unsigned SrcReg,
48 for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
49 if (map[i].cls->contains(DstReg, SrcReg)) {
50 const TargetInstrDesc &TID = get(map[i].opcode);
51 MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).
52 addReg(SrcReg, getKillRegState(KillSrc));
53 AddDefaultPredicate(MI);
58 llvm_unreachable("Impossible reg-to-reg copy");
61 bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
62 MachineBasicBlock::iterator I,
63 unsigned DstReg, unsigned SrcReg,
64 const TargetRegisterClass *DstRC,
65 const TargetRegisterClass *SrcRC,
70 for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
71 if (DstRC == map[i].cls) {
72 const TargetInstrDesc &TID = get(map[i].opcode);
73 MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).addReg(SrcReg);
74 AddDefaultPredicate(MI);
81 bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
82 unsigned &SrcReg, unsigned &DstReg,
83 unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
84 switch (MI.getOpcode()) {
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();
105 bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
106 int i = MI->findFirstPredOperandIdx();
107 return i != -1 && MI->getOperand(i).getReg() != PTX::NoRegister;
110 bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
111 return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
115 PredicateInstruction(MachineInstr *MI,
116 const SmallVectorImpl<MachineOperand> &Pred) const {
118 llvm_unreachable("lesser than 2 predicate operands are provided");
120 int i = MI->findFirstPredOperandIdx();
122 llvm_unreachable("missing predicate operand");
124 MI->getOperand(i).setReg(Pred[0].getReg());
125 MI->getOperand(i+1).setImm(Pred[1].getImm());
131 SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
132 const SmallVectorImpl<MachineOperand> &Pred2) const {
133 // TODO Implement SubsumesPredicate
134 // Returns true if the first specified predicate subsumes the second,
135 // e.g. GE subsumes GT.
140 DefinesPredicate(MachineInstr *MI,
141 std::vector<MachineOperand> &Pred) const {
142 // TODO Implement DefinesPredicate
143 // If the specified instruction defines any predicate or condition code
144 // register(s) used for predication, returns true as well as the definition
145 // predicate(s) by reference.
147 switch (MI->getOpcode()) {
150 case PTX::SETPEQu32rr:
151 case PTX::SETPEQu32ri:
152 case PTX::SETPNEu32rr:
153 case PTX::SETPNEu32ri:
154 case PTX::SETPLTu32rr:
155 case PTX::SETPLTu32ri:
156 case PTX::SETPLEu32rr:
157 case PTX::SETPLEu32ri:
158 case PTX::SETPGTu32rr:
159 case PTX::SETPGTu32ri:
160 case PTX::SETPGEu32rr:
161 case PTX::SETPGEu32ri: {
162 const MachineOperand &MO = MI->getOperand(0);
163 assert(MO.isReg() && RI.getRegClass(MO.getReg()) == &PTX::PredsRegClass);
165 Pred.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL));
174 AnalyzeBranch(MachineBasicBlock &MBB,
175 MachineBasicBlock *&TBB,
176 MachineBasicBlock *&FBB,
177 SmallVectorImpl<MachineOperand> &Cond,
178 bool AllowModify) const {
179 // TODO implement cases when AllowModify is true
184 MachineBasicBlock::const_iterator iter = MBB.end();
185 const MachineInstr& instLast1 = *--iter;
186 const TargetInstrDesc &desc1 = instLast1.getDesc();
187 // for special case that MBB has only 1 instruction
188 const bool IsSizeOne = MBB.size() == 1;
189 // if IsSizeOne is true, *--iter and instLast2 are invalid
190 // we put a dummy value in instLast2 and desc2 since they are used
191 const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter;
192 const TargetInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc();
194 DEBUG(dbgs() << "\n");
195 DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n");
196 DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n");
197 DEBUG(dbgs() << "AnalyzeBranch: TBB: " << TBB << "\n");
198 DEBUG(dbgs() << "AnalyzeBranch: FBB: " << FBB << "\n");
200 // this block ends with no branches
201 if (!IsAnyKindOfBranch(instLast1)) {
202 DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n");
206 // this block ends with only an unconditional branch
207 if (desc1.isUnconditionalBranch() &&
208 // when IsSizeOne is true, it "absorbs" the evaluation of instLast2
209 (IsSizeOne || !IsAnyKindOfBranch(instLast2))) {
210 DEBUG(dbgs() << "AnalyzeBranch: ends with only uncond branch\n");
211 TBB = GetBranchTarget(instLast1);
215 // this block ends with a conditional branch and
216 // it falls through to a successor block
217 if (desc1.isConditionalBranch() &&
218 IsAnySuccessorAlsoLayoutSuccessor(MBB)) {
219 DEBUG(dbgs() << "AnalyzeBranch: ends with cond branch and fall through\n");
220 TBB = GetBranchTarget(instLast1);
221 int i = instLast1.findFirstPredOperandIdx();
222 Cond.push_back(instLast1.getOperand(i));
223 Cond.push_back(instLast1.getOperand(i+1));
227 // when IsSizeOne is true, we are done
231 // this block ends with a conditional branch
232 // followed by an unconditional branch
233 if (desc2.isConditionalBranch() &&
234 desc1.isUnconditionalBranch()) {
235 DEBUG(dbgs() << "AnalyzeBranch: ends with cond and uncond branch\n");
236 TBB = GetBranchTarget(instLast2);
237 FBB = GetBranchTarget(instLast1);
238 int i = instLast2.findFirstPredOperandIdx();
239 Cond.push_back(instLast2.getOperand(i));
240 Cond.push_back(instLast2.getOperand(i+1));
244 // branch cannot be understood
245 DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
249 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
251 for (count = 0; IsAnyKindOfBranch(MBB.back()); ++count)
253 DEBUG(dbgs() << "RemoveBranch: MBB: " << MBB.getName().str() << "\n");
254 DEBUG(dbgs() << "RemoveBranch: count: " << count << "\n");
258 unsigned PTXInstrInfo::
259 InsertBranch(MachineBasicBlock &MBB,
260 MachineBasicBlock *TBB,
261 MachineBasicBlock *FBB,
262 const SmallVectorImpl<MachineOperand> &Cond,
264 DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n");
265 DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: "
266 << TBB->getName().str() << "\n";
267 else dbgs() << "InsertBranch: TBB: (NULL)\n");
268 DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: "
269 << FBB->getName().str() << "\n";
270 else dbgs() << "InsertBranch: FBB: (NULL)\n");
271 DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n");
273 assert(TBB && "TBB is NULL");
276 BuildMI(&MBB, DL, get(PTX::BRAdp))
277 .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
278 BuildMI(&MBB, DL, get(PTX::BRAd))
279 .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
281 } else if (Cond.size()) {
282 BuildMI(&MBB, DL, get(PTX::BRAdp))
283 .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm());
286 BuildMI(&MBB, DL, get(PTX::BRAd))
287 .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL);
292 // static helper routines
294 MachineSDNode *PTXInstrInfo::
295 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
296 DebugLoc dl, EVT VT, SDValue Op1) {
297 SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
298 SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
299 SDValue ops[] = { Op1, predReg, predOp };
300 return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
303 MachineSDNode *PTXInstrInfo::
304 GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
305 DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
306 SDValue predReg = DAG->getRegister(PTX::NoRegister, MVT::i1);
307 SDValue predOp = DAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32);
308 SDValue ops[] = { Op1, Op2, predReg, predOp };
309 return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
312 void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
313 if (MI->findFirstPredOperandIdx() == -1) {
314 MI->addOperand(MachineOperand::CreateReg(PTX::NoRegister, /*IsDef=*/false));
315 MI->addOperand(MachineOperand::CreateImm(PTX::PRED_NORMAL));
319 bool PTXInstrInfo::IsAnyKindOfBranch(const MachineInstr& inst) {
320 const TargetInstrDesc &desc = inst.getDesc();
321 return desc.isTerminator() || desc.isBranch() || desc.isIndirectBranch();
325 IsAnySuccessorAlsoLayoutSuccessor(const MachineBasicBlock& MBB) {
326 for (MachineBasicBlock::const_succ_iterator
327 i = MBB.succ_begin(), e = MBB.succ_end(); i != e; ++i)
328 if (MBB.isLayoutSuccessor((const MachineBasicBlock*) &*i))
333 MachineBasicBlock *PTXInstrInfo::GetBranchTarget(const MachineInstr& inst) {
334 // FIXME So far all branch instructions put destination in 1st operand
335 const MachineOperand& target = inst.getOperand(0);
336 assert(target.isMBB() && "FIXME: detect branch target operand");
337 return target.getMBB();