1 //===-- PTXISelLowering.cpp - PTX DAG Lowering Implementation -------------===//
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 implements the PTXTargetLowering class.
12 //===----------------------------------------------------------------------===//
15 #include "PTXISelLowering.h"
16 #include "PTXMachineFunctionInfo.h"
17 #include "PTXRegisterInfo.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/SelectionDAG.h"
22 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
23 #include "llvm/Support/raw_ostream.h"
27 PTXTargetLowering::PTXTargetLowering(TargetMachine
&TM
)
28 : TargetLowering(TM
, new TargetLoweringObjectFileELF()) {
29 // Set up the register classes.
30 addRegisterClass(MVT::i1
, PTX::PredsRegisterClass
);
31 addRegisterClass(MVT::i16
, PTX::RRegu16RegisterClass
);
32 addRegisterClass(MVT::i32
, PTX::RRegu32RegisterClass
);
33 addRegisterClass(MVT::i64
, PTX::RRegu64RegisterClass
);
34 addRegisterClass(MVT::f32
, PTX::RRegf32RegisterClass
);
35 addRegisterClass(MVT::f64
, PTX::RRegf64RegisterClass
);
37 setOperationAction(ISD::EXCEPTIONADDR
, MVT::i32
, Expand
);
39 setOperationAction(ISD::ConstantFP
, MVT::f32
, Legal
);
40 setOperationAction(ISD::ConstantFP
, MVT::f64
, Legal
);
42 // Customize translation of memory addresses
43 setOperationAction(ISD::GlobalAddress
, MVT::i32
, Custom
);
44 setOperationAction(ISD::GlobalAddress
, MVT::i64
, Custom
);
46 // Expand BR_CC into BRCOND
47 setOperationAction(ISD::BR_CC
, MVT::Other
, Expand
);
49 // Compute derived properties from the register classes
50 computeRegisterProperties();
53 SDValue
PTXTargetLowering::LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const {
54 switch (Op
.getOpcode()) {
56 llvm_unreachable("Unimplemented operand");
57 case ISD::GlobalAddress
:
58 return LowerGlobalAddress(Op
, DAG
);
62 const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode
) const {
65 llvm_unreachable("Unknown opcode");
66 case PTXISD::COPY_ADDRESS
:
67 return "PTXISD::COPY_ADDRESS";
68 case PTXISD::READ_PARAM
:
69 return "PTXISD::READ_PARAM";
71 return "PTXISD::EXIT";
77 //===----------------------------------------------------------------------===//
78 // Custom Lower Operation
79 //===----------------------------------------------------------------------===//
81 SDValue
PTXTargetLowering::
82 LowerGlobalAddress(SDValue Op
, SelectionDAG
&DAG
) const {
83 EVT PtrVT
= getPointerTy();
84 DebugLoc dl
= Op
.getDebugLoc();
85 const GlobalValue
*GV
= cast
<GlobalAddressSDNode
>(Op
)->getGlobal();
87 assert(PtrVT
.isSimple() && "Pointer must be to primitive type.");
89 SDValue targetGlobal
= DAG
.getTargetGlobalAddress(GV
, dl
, PtrVT
);
90 SDValue movInstr
= DAG
.getNode(PTXISD::COPY_ADDRESS
,
98 //===----------------------------------------------------------------------===//
99 // Calling Convention Implementation
100 //===----------------------------------------------------------------------===//
103 struct argmap_entry
{
104 MVT::SimpleValueType VT
;
105 TargetRegisterClass
*RC
;
106 TargetRegisterClass::iterator loc
;
108 argmap_entry(MVT::SimpleValueType _VT
, TargetRegisterClass
*_RC
)
109 : VT(_VT
), RC(_RC
), loc(_RC
->begin()) {}
111 void reset() { loc
= RC
->begin(); }
112 bool operator==(MVT::SimpleValueType _VT
) const { return VT
== _VT
; }
114 argmap_entry(MVT::i1
, PTX::PredsRegisterClass
),
115 argmap_entry(MVT::i16
, PTX::RRegu16RegisterClass
),
116 argmap_entry(MVT::i32
, PTX::RRegu32RegisterClass
),
117 argmap_entry(MVT::i64
, PTX::RRegu64RegisterClass
),
118 argmap_entry(MVT::f32
, PTX::RRegf32RegisterClass
),
119 argmap_entry(MVT::f64
, PTX::RRegf64RegisterClass
)
121 } // end anonymous namespace
123 SDValue
PTXTargetLowering::
124 LowerFormalArguments(SDValue Chain
,
125 CallingConv::ID CallConv
,
127 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
130 SmallVectorImpl
<SDValue
> &InVals
) const {
131 if (isVarArg
) llvm_unreachable("PTX does not support varargs");
133 MachineFunction
&MF
= DAG
.getMachineFunction();
134 PTXMachineFunctionInfo
*MFI
= MF
.getInfo
<PTXMachineFunctionInfo
>();
138 llvm_unreachable("Unsupported calling convention");
140 case CallingConv::PTX_Kernel
:
141 MFI
->setKernel(true);
143 case CallingConv::PTX_Device
:
144 MFI
->setKernel(false);
148 // Make sure we don't add argument registers twice
149 if (MFI
->isDoneAddArg())
150 llvm_unreachable("cannot add argument registers twice");
152 // Reset argmap before allocation
153 for (struct argmap_entry
*i
= argmap
, *e
= argmap
+ array_lengthof(argmap
);
157 for (int i
= 0, e
= Ins
.size(); i
!= e
; ++ i
) {
158 MVT::SimpleValueType VT
= Ins
[i
].VT
.SimpleTy
;
160 struct argmap_entry
*entry
= std::find(argmap
,
161 argmap
+ array_lengthof(argmap
), VT
);
162 if (entry
== argmap
+ array_lengthof(argmap
))
163 llvm_unreachable("Type of argument is not supported");
165 if (MFI
->isKernel() && entry
->RC
== PTX::PredsRegisterClass
)
166 llvm_unreachable("cannot pass preds to kernel");
168 MachineRegisterInfo
&RegInfo
= DAG
.getMachineFunction().getRegInfo();
170 unsigned preg
= *++(entry
->loc
); // allocate start from register 1
171 unsigned vreg
= RegInfo
.createVirtualRegister(entry
->RC
);
172 RegInfo
.addLiveIn(preg
, vreg
);
174 MFI
->addArgReg(preg
);
178 inval
= DAG
.getNode(PTXISD::READ_PARAM
, dl
, VT
, Chain
,
179 DAG
.getTargetConstant(i
, MVT::i32
));
181 inval
= DAG
.getCopyFromReg(Chain
, dl
, vreg
, VT
);
182 InVals
.push_back(inval
);
190 SDValue
PTXTargetLowering::
191 LowerReturn(SDValue Chain
,
192 CallingConv::ID CallConv
,
194 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
195 const SmallVectorImpl
<SDValue
> &OutVals
,
197 SelectionDAG
&DAG
) const {
198 if (isVarArg
) llvm_unreachable("PTX does not support varargs");
202 llvm_unreachable("Unsupported calling convention.");
203 case CallingConv::PTX_Kernel
:
204 assert(Outs
.size() == 0 && "Kernel must return void.");
205 return DAG
.getNode(PTXISD::EXIT
, dl
, MVT::Other
, Chain
);
206 case CallingConv::PTX_Device
:
207 assert(Outs
.size() <= 1 && "Can at most return one value.");
214 if (Outs
.size() == 0)
215 return DAG
.getNode(PTXISD::RET
, dl
, MVT::Other
, Chain
);
220 if (Outs
[0].VT
== MVT::i16
) {
223 else if (Outs
[0].VT
== MVT::i32
) {
226 else if (Outs
[0].VT
== MVT::i64
) {
229 else if (Outs
[0].VT
== MVT::f32
) {
233 assert(Outs
[0].VT
== MVT::f64
&& "Can return only basic types");
237 MachineFunction
&MF
= DAG
.getMachineFunction();
238 PTXMachineFunctionInfo
*MFI
= MF
.getInfo
<PTXMachineFunctionInfo
>();
241 // If this is the first return lowered for this function, add the regs to the
242 // liveout set for the function
243 if (DAG
.getMachineFunction().getRegInfo().liveout_empty())
244 DAG
.getMachineFunction().getRegInfo().addLiveOut(reg
);
246 // Copy the result values into the output registers
247 Chain
= DAG
.getCopyToReg(Chain
, dl
, reg
, OutVals
[0], Flag
);
249 // Guarantee that all emitted copies are stuck together,
250 // avoiding something bad
251 Flag
= Chain
.getValue(1);
253 return DAG
.getNode(PTXISD::RET
, dl
, MVT::Other
, Chain
, Flag
);