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