blob: f05bd47b7fe588b7c79f722139be8e7847741630 [file] [log] [blame]
Eric Christopher50880d02010-09-18 18:52:28 +00001//===-- PTXISelLowering.cpp - PTX DAG Lowering Implementation -------------===//
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 implements the PTXTargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000014#include "PTX.h"
Eric Christopher50880d02010-09-18 18:52:28 +000015#include "PTXISelLowering.h"
Che-Liang Chiou3278c422010-11-08 03:00:52 +000016#include "PTXMachineFunctionInfo.h"
Eric Christopher50880d02010-09-18 18:52:28 +000017#include "PTXRegisterInfo.h"
18#include "llvm/Support/ErrorHandling.h"
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000019#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineRegisterInfo.h"
Eric Christopher50880d02010-09-18 18:52:28 +000021#include "llvm/CodeGen/SelectionDAG.h"
22#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
23
24using namespace llvm;
25
26PTXTargetLowering::PTXTargetLowering(TargetMachine &TM)
27 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
28 // Set up the register classes.
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000029 addRegisterClass(MVT::i1, PTX::PredsRegisterClass);
30 addRegisterClass(MVT::i32, PTX::RRegs32RegisterClass);
Eric Christopher50880d02010-09-18 18:52:28 +000031
Che-Liang Chioufc7072c2010-12-22 10:38:51 +000032 setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
33
34 // Customize translation of memory addresses
35 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
36
Eric Christopher50880d02010-09-18 18:52:28 +000037 // Compute derived properties from the register classes
38 computeRegisterProperties();
39}
40
Che-Liang Chioufc7072c2010-12-22 10:38:51 +000041SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
42 switch (Op.getOpcode()) {
43 default: llvm_unreachable("Unimplemented operand");
44 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
45 }
46}
47
Eric Christopher50880d02010-09-18 18:52:28 +000048const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
49 switch (Opcode) {
50 default: llvm_unreachable("Unknown opcode");
51 case PTXISD::EXIT: return "PTXISD::EXIT";
Che-Liang Chiouf9930da2010-09-25 07:46:17 +000052 case PTXISD::RET: return "PTXISD::RET";
Eric Christopher50880d02010-09-18 18:52:28 +000053 }
54}
55
56//===----------------------------------------------------------------------===//
Che-Liang Chioufc7072c2010-12-22 10:38:51 +000057// Custom Lower Operation
58//===----------------------------------------------------------------------===//
59
60SDValue PTXTargetLowering::
61LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
62 EVT PtrVT = getPointerTy();
63 DebugLoc dl = Op.getDebugLoc();
64 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
65 return DAG.getTargetGlobalAddress(GV, dl, PtrVT);
66}
67
68//===----------------------------------------------------------------------===//
Eric Christopher50880d02010-09-18 18:52:28 +000069// Calling Convention Implementation
70//===----------------------------------------------------------------------===//
71
Benjamin Kramera3ac4272010-10-22 17:35:07 +000072namespace {
73struct argmap_entry {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000074 MVT::SimpleValueType VT;
75 TargetRegisterClass *RC;
76 TargetRegisterClass::iterator loc;
77
78 argmap_entry(MVT::SimpleValueType _VT, TargetRegisterClass *_RC)
79 : VT(_VT), RC(_RC), loc(_RC->begin()) {}
80
Benjamin Kramera3ac4272010-10-22 17:35:07 +000081 void reset() { loc = RC->begin(); }
82 bool operator==(MVT::SimpleValueType _VT) const { return VT == _VT; }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000083} argmap[] = {
84 argmap_entry(MVT::i1, PTX::PredsRegisterClass),
85 argmap_entry(MVT::i32, PTX::RRegs32RegisterClass)
86};
Benjamin Kramera3ac4272010-10-22 17:35:07 +000087} // end anonymous namespace
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000088
89static SDValue lower_kernel_argument(int i,
90 SDValue Chain,
91 DebugLoc dl,
92 MVT::SimpleValueType VT,
93 argmap_entry *entry,
94 SelectionDAG &DAG,
95 unsigned *argreg) {
96 // TODO
97 llvm_unreachable("Not implemented yet");
98}
99
100static SDValue lower_device_argument(int i,
101 SDValue Chain,
102 DebugLoc dl,
103 MVT::SimpleValueType VT,
104 argmap_entry *entry,
105 SelectionDAG &DAG,
106 unsigned *argreg) {
107 MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();
108
109 unsigned preg = *++(entry->loc); // allocate start from register 1
110 unsigned vreg = RegInfo.createVirtualRegister(entry->RC);
111 RegInfo.addLiveIn(preg, vreg);
112
113 *argreg = preg;
114 return DAG.getCopyFromReg(Chain, dl, vreg, VT);
115}
116
117typedef SDValue (*lower_argument_func)(int i,
118 SDValue Chain,
119 DebugLoc dl,
120 MVT::SimpleValueType VT,
121 argmap_entry *entry,
122 SelectionDAG &DAG,
123 unsigned *argreg);
124
Eric Christopher50880d02010-09-18 18:52:28 +0000125SDValue PTXTargetLowering::
126 LowerFormalArguments(SDValue Chain,
127 CallingConv::ID CallConv,
128 bool isVarArg,
129 const SmallVectorImpl<ISD::InputArg> &Ins,
130 DebugLoc dl,
131 SelectionDAG &DAG,
132 SmallVectorImpl<SDValue> &InVals) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000133 if (isVarArg) llvm_unreachable("PTX does not support varargs");
134
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000135 MachineFunction &MF = DAG.getMachineFunction();
136 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
137
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000138 lower_argument_func lower_argument;
139
140 switch (CallConv) {
141 default:
142 llvm_unreachable("Unsupported calling convention");
143 break;
144 case CallingConv::PTX_Kernel:
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000145 MFI->setKernel();
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000146 lower_argument = lower_kernel_argument;
147 break;
148 case CallingConv::PTX_Device:
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000149 MFI->setKernel(false);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000150 lower_argument = lower_device_argument;
151 break;
152 }
153
154 // Reset argmap before allocation
155 for (struct argmap_entry *i = argmap, *e = argmap + array_lengthof(argmap);
156 i != e; ++ i)
157 i->reset();
158
159 for (int i = 0, e = Ins.size(); i != e; ++ i) {
Duncan Sands1440e8b2010-11-03 11:35:31 +0000160 MVT::SimpleValueType VT = Ins[i].VT.SimpleTy;
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000161
162 struct argmap_entry *entry = std::find(argmap,
163 argmap + array_lengthof(argmap), VT);
164 if (entry == argmap + array_lengthof(argmap))
165 llvm_unreachable("Type of argument is not supported");
166
167 unsigned reg;
168 SDValue arg = lower_argument(i, Chain, dl, VT, entry, DAG, &reg);
169 InVals.push_back(arg);
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000170
171 if (!MFI->isDoneAddArg())
172 MFI->addArgReg(reg);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000173 }
174
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000175 // Make sure we don't add argument registers twice
176 if (!MFI->isDoneAddArg())
177 MFI->doneAddArg();
178
Eric Christopher50880d02010-09-18 18:52:28 +0000179 return Chain;
180}
181
182SDValue PTXTargetLowering::
183 LowerReturn(SDValue Chain,
184 CallingConv::ID CallConv,
185 bool isVarArg,
186 const SmallVectorImpl<ISD::OutputArg> &Outs,
187 const SmallVectorImpl<SDValue> &OutVals,
188 DebugLoc dl,
189 SelectionDAG &DAG) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000190 if (isVarArg) llvm_unreachable("PTX does not support varargs");
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000191
192 switch (CallConv) {
193 default:
194 llvm_unreachable("Unsupported calling convention.");
195 case CallingConv::PTX_Kernel:
196 assert(Outs.size() == 0 && "Kernel must return void.");
197 return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
198 case CallingConv::PTX_Device:
199 assert(Outs.size() <= 1 && "Can at most return one value.");
200 break;
201 }
202
203 // PTX_Device
204
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000205 // return void
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000206 if (Outs.size() == 0)
207 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
208
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000209 assert(Outs[0].VT == MVT::i32 && "Can return only basic types");
210
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000211 SDValue Flag;
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000212 unsigned reg = PTX::R0;
213
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000214 MachineFunction &MF = DAG.getMachineFunction();
215 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
216 MFI->setRetReg(reg);
217
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000218 // If this is the first return lowered for this function, add the regs to the
219 // liveout set for the function
220 if (DAG.getMachineFunction().getRegInfo().liveout_empty())
221 DAG.getMachineFunction().getRegInfo().addLiveOut(reg);
222
223 // Copy the result values into the output registers
224 Chain = DAG.getCopyToReg(Chain, dl, reg, OutVals[0], Flag);
225
226 // Guarantee that all emitted copies are stuck together,
227 // avoiding something bad
228 Flag = Chain.getValue(1);
229
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000230 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);
Eric Christopher50880d02010-09-18 18:52:28 +0000231}