blob: 6e68c3760187776162ef5a47ea4862a48a314d6f [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"
16#include "PTXRegisterInfo.h"
17#include "llvm/Support/ErrorHandling.h"
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000018#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/MachineRegisterInfo.h"
Eric Christopher50880d02010-09-18 18:52:28 +000020#include "llvm/CodeGen/SelectionDAG.h"
21#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
22
23using namespace llvm;
24
25PTXTargetLowering::PTXTargetLowering(TargetMachine &TM)
26 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
27 // Set up the register classes.
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000028 addRegisterClass(MVT::i1, PTX::PredsRegisterClass);
29 addRegisterClass(MVT::i32, PTX::RRegs32RegisterClass);
Eric Christopher50880d02010-09-18 18:52:28 +000030
31 // Compute derived properties from the register classes
32 computeRegisterProperties();
33}
34
35const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
36 switch (Opcode) {
37 default: llvm_unreachable("Unknown opcode");
38 case PTXISD::EXIT: return "PTXISD::EXIT";
Che-Liang Chiouf9930da2010-09-25 07:46:17 +000039 case PTXISD::RET: return "PTXISD::RET";
Eric Christopher50880d02010-09-18 18:52:28 +000040 }
41}
42
43//===----------------------------------------------------------------------===//
44// Calling Convention Implementation
45//===----------------------------------------------------------------------===//
46
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000047static struct argmap_entry {
48 MVT::SimpleValueType VT;
49 TargetRegisterClass *RC;
50 TargetRegisterClass::iterator loc;
51
52 argmap_entry(MVT::SimpleValueType _VT, TargetRegisterClass *_RC)
53 : VT(_VT), RC(_RC), loc(_RC->begin()) {}
54
55 void reset(void) { loc = RC->begin(); }
56 bool operator==(MVT::SimpleValueType _VT) { return VT == _VT; }
57} argmap[] = {
58 argmap_entry(MVT::i1, PTX::PredsRegisterClass),
59 argmap_entry(MVT::i32, PTX::RRegs32RegisterClass)
60};
61
62static SDValue lower_kernel_argument(int i,
63 SDValue Chain,
64 DebugLoc dl,
65 MVT::SimpleValueType VT,
66 argmap_entry *entry,
67 SelectionDAG &DAG,
68 unsigned *argreg) {
69 // TODO
70 llvm_unreachable("Not implemented yet");
71}
72
73static SDValue lower_device_argument(int i,
74 SDValue Chain,
75 DebugLoc dl,
76 MVT::SimpleValueType VT,
77 argmap_entry *entry,
78 SelectionDAG &DAG,
79 unsigned *argreg) {
80 MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();
81
82 unsigned preg = *++(entry->loc); // allocate start from register 1
83 unsigned vreg = RegInfo.createVirtualRegister(entry->RC);
84 RegInfo.addLiveIn(preg, vreg);
85
86 *argreg = preg;
87 return DAG.getCopyFromReg(Chain, dl, vreg, VT);
88}
89
90typedef SDValue (*lower_argument_func)(int i,
91 SDValue Chain,
92 DebugLoc dl,
93 MVT::SimpleValueType VT,
94 argmap_entry *entry,
95 SelectionDAG &DAG,
96 unsigned *argreg);
97
Eric Christopher50880d02010-09-18 18:52:28 +000098SDValue PTXTargetLowering::
99 LowerFormalArguments(SDValue Chain,
100 CallingConv::ID CallConv,
101 bool isVarArg,
102 const SmallVectorImpl<ISD::InputArg> &Ins,
103 DebugLoc dl,
104 SelectionDAG &DAG,
105 SmallVectorImpl<SDValue> &InVals) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000106 if (isVarArg) llvm_unreachable("PTX does not support varargs");
107
108 lower_argument_func lower_argument;
109
110 switch (CallConv) {
111 default:
112 llvm_unreachable("Unsupported calling convention");
113 break;
114 case CallingConv::PTX_Kernel:
115 lower_argument = lower_kernel_argument;
116 break;
117 case CallingConv::PTX_Device:
118 lower_argument = lower_device_argument;
119 break;
120 }
121
122 // Reset argmap before allocation
123 for (struct argmap_entry *i = argmap, *e = argmap + array_lengthof(argmap);
124 i != e; ++ i)
125 i->reset();
126
127 for (int i = 0, e = Ins.size(); i != e; ++ i) {
128 MVT::SimpleValueType VT = Ins[i].VT.getSimpleVT().SimpleTy;
129
130 struct argmap_entry *entry = std::find(argmap,
131 argmap + array_lengthof(argmap), VT);
132 if (entry == argmap + array_lengthof(argmap))
133 llvm_unreachable("Type of argument is not supported");
134
135 unsigned reg;
136 SDValue arg = lower_argument(i, Chain, dl, VT, entry, DAG, &reg);
137 InVals.push_back(arg);
138 }
139
Eric Christopher50880d02010-09-18 18:52:28 +0000140 return Chain;
141}
142
143SDValue PTXTargetLowering::
144 LowerReturn(SDValue Chain,
145 CallingConv::ID CallConv,
146 bool isVarArg,
147 const SmallVectorImpl<ISD::OutputArg> &Outs,
148 const SmallVectorImpl<SDValue> &OutVals,
149 DebugLoc dl,
150 SelectionDAG &DAG) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000151 if (isVarArg) llvm_unreachable("PTX does not support varargs");
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000152
153 switch (CallConv) {
154 default:
155 llvm_unreachable("Unsupported calling convention.");
156 case CallingConv::PTX_Kernel:
157 assert(Outs.size() == 0 && "Kernel must return void.");
158 return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
159 case CallingConv::PTX_Device:
160 assert(Outs.size() <= 1 && "Can at most return one value.");
161 break;
162 }
163
164 // PTX_Device
165
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000166 // return void
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000167 if (Outs.size() == 0)
168 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
169
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000170 assert(Outs[0].VT == MVT::i32 && "Can return only basic types");
171
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000172 SDValue Flag;
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000173 unsigned reg = PTX::R0;
174
175 // If this is the first return lowered for this function, add the regs to the
176 // liveout set for the function
177 if (DAG.getMachineFunction().getRegInfo().liveout_empty())
178 DAG.getMachineFunction().getRegInfo().addLiveOut(reg);
179
180 // Copy the result values into the output registers
181 Chain = DAG.getCopyToReg(Chain, dl, reg, OutVals[0], Flag);
182
183 // Guarantee that all emitted copies are stuck together,
184 // avoiding something bad
185 Flag = Chain.getValue(1);
186
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000187 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);
Eric Christopher50880d02010-09-18 18:52:28 +0000188}