blob: ae6920805a346fd6ccd7ea4f95a580cbeeb6b73b [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
32 // Compute derived properties from the register classes
33 computeRegisterProperties();
34}
35
36const char *PTXTargetLowering::getTargetNodeName(unsigned Opcode) const {
37 switch (Opcode) {
38 default: llvm_unreachable("Unknown opcode");
39 case PTXISD::EXIT: return "PTXISD::EXIT";
Che-Liang Chiouf9930da2010-09-25 07:46:17 +000040 case PTXISD::RET: return "PTXISD::RET";
Eric Christopher50880d02010-09-18 18:52:28 +000041 }
42}
43
44//===----------------------------------------------------------------------===//
45// Calling Convention Implementation
46//===----------------------------------------------------------------------===//
47
Benjamin Kramera3ac4272010-10-22 17:35:07 +000048namespace {
49struct argmap_entry {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000050 MVT::SimpleValueType VT;
51 TargetRegisterClass *RC;
52 TargetRegisterClass::iterator loc;
53
54 argmap_entry(MVT::SimpleValueType _VT, TargetRegisterClass *_RC)
55 : VT(_VT), RC(_RC), loc(_RC->begin()) {}
56
Benjamin Kramera3ac4272010-10-22 17:35:07 +000057 void reset() { loc = RC->begin(); }
58 bool operator==(MVT::SimpleValueType _VT) const { return VT == _VT; }
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000059} argmap[] = {
60 argmap_entry(MVT::i1, PTX::PredsRegisterClass),
61 argmap_entry(MVT::i32, PTX::RRegs32RegisterClass)
62};
Benjamin Kramera3ac4272010-10-22 17:35:07 +000063} // end anonymous namespace
Che-Liang Chioub48f2c22010-10-19 13:14:40 +000064
65static SDValue lower_kernel_argument(int i,
66 SDValue Chain,
67 DebugLoc dl,
68 MVT::SimpleValueType VT,
69 argmap_entry *entry,
70 SelectionDAG &DAG,
71 unsigned *argreg) {
72 // TODO
73 llvm_unreachable("Not implemented yet");
74}
75
76static SDValue lower_device_argument(int i,
77 SDValue Chain,
78 DebugLoc dl,
79 MVT::SimpleValueType VT,
80 argmap_entry *entry,
81 SelectionDAG &DAG,
82 unsigned *argreg) {
83 MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();
84
85 unsigned preg = *++(entry->loc); // allocate start from register 1
86 unsigned vreg = RegInfo.createVirtualRegister(entry->RC);
87 RegInfo.addLiveIn(preg, vreg);
88
89 *argreg = preg;
90 return DAG.getCopyFromReg(Chain, dl, vreg, VT);
91}
92
93typedef SDValue (*lower_argument_func)(int i,
94 SDValue Chain,
95 DebugLoc dl,
96 MVT::SimpleValueType VT,
97 argmap_entry *entry,
98 SelectionDAG &DAG,
99 unsigned *argreg);
100
Eric Christopher50880d02010-09-18 18:52:28 +0000101SDValue PTXTargetLowering::
102 LowerFormalArguments(SDValue Chain,
103 CallingConv::ID CallConv,
104 bool isVarArg,
105 const SmallVectorImpl<ISD::InputArg> &Ins,
106 DebugLoc dl,
107 SelectionDAG &DAG,
108 SmallVectorImpl<SDValue> &InVals) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000109 if (isVarArg) llvm_unreachable("PTX does not support varargs");
110
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000111 MachineFunction &MF = DAG.getMachineFunction();
112 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
113
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000114 lower_argument_func lower_argument;
115
116 switch (CallConv) {
117 default:
118 llvm_unreachable("Unsupported calling convention");
119 break;
120 case CallingConv::PTX_Kernel:
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000121 MFI->setKernel();
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000122 lower_argument = lower_kernel_argument;
123 break;
124 case CallingConv::PTX_Device:
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000125 MFI->setKernel(false);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000126 lower_argument = lower_device_argument;
127 break;
128 }
129
130 // Reset argmap before allocation
131 for (struct argmap_entry *i = argmap, *e = argmap + array_lengthof(argmap);
132 i != e; ++ i)
133 i->reset();
134
135 for (int i = 0, e = Ins.size(); i != e; ++ i) {
Duncan Sands1440e8b2010-11-03 11:35:31 +0000136 MVT::SimpleValueType VT = Ins[i].VT.SimpleTy;
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000137
138 struct argmap_entry *entry = std::find(argmap,
139 argmap + array_lengthof(argmap), VT);
140 if (entry == argmap + array_lengthof(argmap))
141 llvm_unreachable("Type of argument is not supported");
142
143 unsigned reg;
144 SDValue arg = lower_argument(i, Chain, dl, VT, entry, DAG, &reg);
145 InVals.push_back(arg);
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000146
147 if (!MFI->isDoneAddArg())
148 MFI->addArgReg(reg);
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000149 }
150
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000151 // Make sure we don't add argument registers twice
152 if (!MFI->isDoneAddArg())
153 MFI->doneAddArg();
154
Eric Christopher50880d02010-09-18 18:52:28 +0000155 return Chain;
156}
157
158SDValue PTXTargetLowering::
159 LowerReturn(SDValue Chain,
160 CallingConv::ID CallConv,
161 bool isVarArg,
162 const SmallVectorImpl<ISD::OutputArg> &Outs,
163 const SmallVectorImpl<SDValue> &OutVals,
164 DebugLoc dl,
165 SelectionDAG &DAG) const {
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000166 if (isVarArg) llvm_unreachable("PTX does not support varargs");
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000167
168 switch (CallConv) {
169 default:
170 llvm_unreachable("Unsupported calling convention.");
171 case CallingConv::PTX_Kernel:
172 assert(Outs.size() == 0 && "Kernel must return void.");
173 return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain);
174 case CallingConv::PTX_Device:
175 assert(Outs.size() <= 1 && "Can at most return one value.");
176 break;
177 }
178
179 // PTX_Device
180
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000181 // return void
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000182 if (Outs.size() == 0)
183 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain);
184
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000185 assert(Outs[0].VT == MVT::i32 && "Can return only basic types");
186
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000187 SDValue Flag;
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000188 unsigned reg = PTX::R0;
189
Che-Liang Chiou3278c422010-11-08 03:00:52 +0000190 MachineFunction &MF = DAG.getMachineFunction();
191 PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>();
192 MFI->setRetReg(reg);
193
Che-Liang Chioub48f2c22010-10-19 13:14:40 +0000194 // If this is the first return lowered for this function, add the regs to the
195 // liveout set for the function
196 if (DAG.getMachineFunction().getRegInfo().liveout_empty())
197 DAG.getMachineFunction().getRegInfo().addLiveOut(reg);
198
199 // Copy the result values into the output registers
200 Chain = DAG.getCopyToReg(Chain, dl, reg, OutVals[0], Flag);
201
202 // Guarantee that all emitted copies are stuck together,
203 // avoiding something bad
204 Flag = Chain.getValue(1);
205
Che-Liang Chiouf9930da2010-09-25 07:46:17 +0000206 return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag);
Eric Christopher50880d02010-09-18 18:52:28 +0000207}