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"
24 #define GET_INSTRINFO_CTOR
25 #define GET_INSTRINFO_MC_DESC
26 #include "PTXGenInstrInfo.inc"
30 PTXInstrInfo::PTXInstrInfo(PTXTargetMachine
&_TM
)
32 RI(_TM
, *this), TM(_TM
) {}
34 static const struct map_entry
{
35 const TargetRegisterClass
*cls
;
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
,
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
);
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
,
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
);
83 bool PTXInstrInfo::isMoveInstr(const MachineInstr
& MI
,
84 unsigned &SrcReg
, unsigned &DstReg
,
85 unsigned &SrcSubIdx
, unsigned &DstSubIdx
) const {
86 switch (MI
.getOpcode()) {
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();
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();
117 PredicateInstruction(MachineInstr
*MI
,
118 const SmallVectorImpl
<MachineOperand
> &Pred
) const {
120 llvm_unreachable("lesser than 2 predicate operands are provided");
122 int i
= MI
->findFirstPredOperandIdx();
124 llvm_unreachable("missing predicate operand");
126 MI
->getOperand(i
).setReg(Pred
[0].getReg());
127 MI
->getOperand(i
+1).setImm(Pred
[1].getImm());
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())
140 const MachineOperand
&PredOp1
= Pred1
[1];
141 const MachineOperand
&PredOp2
= Pred2
[1];
142 if (PredOp1
.getImm() != PredOp2
.getImm())
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)
158 const MachineOperand
&MO
= MI
->getOperand(0);
160 if (!MO
.isReg() || RI
.getRegClass(MO
.getReg()) != &PTX::RegPredRegClass
)
164 Pred
.push_back(MachineOperand::CreateImm(PTX::PRED_NORMAL
));
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
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");
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
);
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));
224 // when IsSizeOne is true, we are done
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));
241 // branch cannot be understood
242 DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n");
246 unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const {
249 if (IsAnyKindOfBranch(MBB
.back())) {
254 DEBUG(dbgs() << "RemoveBranch: MBB: " << MBB
.getName().str() << "\n");
255 DEBUG(dbgs() << "RemoveBranch: remove " << count
<< " branch inst\n");
259 unsigned PTXInstrInfo::
260 InsertBranch(MachineBasicBlock
&MBB
,
261 MachineBasicBlock
*TBB
,
262 MachineBasicBlock
*FBB
,
263 const SmallVectorImpl
<MachineOperand
> &Cond
,
265 DEBUG(dbgs() << "InsertBranch: MBB: " << MBB
.getName().str() << "\n");
266 DEBUG(if (TBB
) dbgs() << "InsertBranch: TBB: " << TBB
->getName().str()
268 else dbgs() << "InsertBranch: TBB: (NULL)\n");
269 DEBUG(if (FBB
) dbgs() << "InsertBranch: FBB: " << FBB
->getName().str()
271 else dbgs() << "InsertBranch: FBB: (NULL)\n");
272 DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond
.size() << "\n");
274 assert(TBB
&& "TBB is NULL");
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
);
282 } else if (Cond
.size()) {
283 BuildMI(&MBB
, DL
, get(PTX::BRAdp
))
284 .addMBB(TBB
).addReg(Cond
[0].getReg()).addImm(Cond
[1].getImm());
287 BuildMI(&MBB
, DL
, get(PTX::BRAd
))
288 .addMBB(TBB
).addReg(PTX::NoRegister
).addImm(PTX::PRED_NORMAL
);
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
);
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
;
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
);
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
);
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
;
353 llvm_unreachable("Unknown PTX register class!");
356 // Build the load instruction (really a mov)
357 MachineInstrBuilder MIB
= BuildMI(MBB
, MII
, DL
, get(OpCode
));
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();
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
))
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();