1 //===-- PTXISelDAGToDAG.cpp - A dag to dag inst selector for PTX ----------===//
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 defines an instruction selector for the PTX target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PTX.h"
15 #include "PTXMachineFunctionInfo.h"
16 #include "PTXTargetMachine.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/raw_ostream.h"
22
23 using namespace llvm;
24
25 namespace {
26 // PTXDAGToDAGISel - PTX specific code to select PTX machine
27 // instructions for SelectionDAG operations.
28 class PTXDAGToDAGISel : public SelectionDAGISel {
29 public:
30 PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel);
31
getPassName() const32 virtual const char *getPassName() const {
33 return "PTX DAG->DAG Pattern Instruction Selection";
34 }
35
36 SDNode *Select(SDNode *Node);
37
38 // Complex Pattern Selectors.
39 bool SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2);
40 bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
41 bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
42 bool SelectADDRlocal(SDValue &Addr, SDValue &Base, SDValue &Offset);
43
44 // Include the pieces auto'gened from the target description
45 #include "PTXGenDAGISel.inc"
46
47 private:
48 // We need this only because we can't match intruction BRAdp
49 // pattern (PTXbrcond bb:$d, ...) in PTXInstrInfo.td
50 SDNode *SelectBRCOND(SDNode *Node);
51
52 SDNode *SelectREADPARAM(SDNode *Node);
53 SDNode *SelectWRITEPARAM(SDNode *Node);
54 SDNode *SelectFrameIndex(SDNode *Node);
55
56 bool isImm(const SDValue &operand);
57 bool SelectImm(const SDValue &operand, SDValue &imm);
58
59 const PTXSubtarget& getSubtarget() const;
60 }; // class PTXDAGToDAGISel
61 } // namespace
62
63 // createPTXISelDag - This pass converts a legalized DAG into a
64 // PTX-specific DAG, ready for instruction scheduling
createPTXISelDag(PTXTargetMachine & TM,CodeGenOpt::Level OptLevel)65 FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM,
66 CodeGenOpt::Level OptLevel) {
67 return new PTXDAGToDAGISel(TM, OptLevel);
68 }
69
PTXDAGToDAGISel(PTXTargetMachine & TM,CodeGenOpt::Level OptLevel)70 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM,
71 CodeGenOpt::Level OptLevel)
72 : SelectionDAGISel(TM, OptLevel) {}
73
Select(SDNode * Node)74 SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
75 switch (Node->getOpcode()) {
76 case ISD::BRCOND:
77 return SelectBRCOND(Node);
78 case PTXISD::READ_PARAM:
79 return SelectREADPARAM(Node);
80 case PTXISD::WRITE_PARAM:
81 return SelectWRITEPARAM(Node);
82 case ISD::FrameIndex:
83 return SelectFrameIndex(Node);
84 default:
85 return SelectCode(Node);
86 }
87 }
88
SelectBRCOND(SDNode * Node)89 SDNode *PTXDAGToDAGISel::SelectBRCOND(SDNode *Node) {
90 assert(Node->getNumOperands() >= 3);
91
92 SDValue Chain = Node->getOperand(0);
93 SDValue Pred = Node->getOperand(1);
94 SDValue Target = Node->getOperand(2); // branch target
95 SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::Normal, MVT::i32);
96 DebugLoc dl = Node->getDebugLoc();
97
98 assert(Target.getOpcode() == ISD::BasicBlock);
99 assert(Pred.getValueType() == MVT::i1);
100
101 // Emit BRAdp
102 SDValue Ops[] = { Target, Pred, PredOp, Chain };
103 return CurDAG->getMachineNode(PTX::BRAdp, dl, MVT::Other, Ops, 4);
104 }
105
SelectREADPARAM(SDNode * Node)106 SDNode *PTXDAGToDAGISel::SelectREADPARAM(SDNode *Node) {
107 SDValue Chain = Node->getOperand(0);
108 SDValue Index = Node->getOperand(1);
109
110 int OpCode;
111
112 // Get the type of parameter we are reading
113 EVT VT = Node->getValueType(0);
114 assert(VT.isSimple() && "READ_PARAM only implemented for MVT types");
115
116 MVT Type = VT.getSimpleVT();
117
118 if (Type == MVT::i1)
119 OpCode = PTX::READPARAMPRED;
120 else if (Type == MVT::i16)
121 OpCode = PTX::READPARAMI16;
122 else if (Type == MVT::i32)
123 OpCode = PTX::READPARAMI32;
124 else if (Type == MVT::i64)
125 OpCode = PTX::READPARAMI64;
126 else if (Type == MVT::f32)
127 OpCode = PTX::READPARAMF32;
128 else {
129 assert(Type == MVT::f64 && "Unexpected type!");
130 OpCode = PTX::READPARAMF64;
131 }
132
133 SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1);
134 SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::None, MVT::i32);
135 DebugLoc dl = Node->getDebugLoc();
136
137 SDValue Ops[] = { Index, Pred, PredOp, Chain };
138 return CurDAG->getMachineNode(OpCode, dl, VT, Ops, 4);
139 }
140
SelectWRITEPARAM(SDNode * Node)141 SDNode *PTXDAGToDAGISel::SelectWRITEPARAM(SDNode *Node) {
142
143 SDValue Chain = Node->getOperand(0);
144 SDValue Value = Node->getOperand(1);
145
146 int OpCode;
147
148 //Node->dumpr(CurDAG);
149
150 // Get the type of parameter we are writing
151 EVT VT = Value->getValueType(0);
152 assert(VT.isSimple() && "WRITE_PARAM only implemented for MVT types");
153
154 MVT Type = VT.getSimpleVT();
155
156 if (Type == MVT::i1)
157 OpCode = PTX::WRITEPARAMPRED;
158 else if (Type == MVT::i16)
159 OpCode = PTX::WRITEPARAMI16;
160 else if (Type == MVT::i32)
161 OpCode = PTX::WRITEPARAMI32;
162 else if (Type == MVT::i64)
163 OpCode = PTX::WRITEPARAMI64;
164 else if (Type == MVT::f32)
165 OpCode = PTX::WRITEPARAMF32;
166 else if (Type == MVT::f64)
167 OpCode = PTX::WRITEPARAMF64;
168 else
169 llvm_unreachable("Invalid type in SelectWRITEPARAM");
170
171 SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1);
172 SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::None, MVT::i32);
173 DebugLoc dl = Node->getDebugLoc();
174
175 SDValue Ops[] = { Value, Pred, PredOp, Chain };
176 SDNode* Ret = CurDAG->getMachineNode(OpCode, dl, MVT::Other, Ops, 4);
177
178 //dbgs() << "SelectWRITEPARAM produced:\n\t";
179 //Ret->dumpr(CurDAG);
180
181 return Ret;
182 }
183
SelectFrameIndex(SDNode * Node)184 SDNode *PTXDAGToDAGISel::SelectFrameIndex(SDNode *Node) {
185 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
186 //dbgs() << "Selecting FrameIndex at index " << FI << "\n";
187 //SDValue TFI = CurDAG->getTargetFrameIndex(FI, Node->getValueType(0));
188
189 PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>();
190
191 SDValue FrameSymbol = CurDAG->getTargetExternalSymbol(MFI->getFrameSymbol(FI),
192 Node->getValueType(0));
193
194 return FrameSymbol.getNode();
195 }
196
197 // Match memory operand of the form [reg+reg]
SelectADDRrr(SDValue & Addr,SDValue & R1,SDValue & R2)198 bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) {
199 if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 ||
200 isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1)))
201 return false;
202
203 assert(Addr.getValueType().isSimple() && "Type must be simple");
204
205 R1 = Addr;
206 R2 = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
207
208 return true;
209 }
210
211 // Match memory operand of the form [reg], [imm+reg], and [reg+imm]
SelectADDRri(SDValue & Addr,SDValue & Base,SDValue & Offset)212 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
213 SDValue &Offset) {
214 // FrameIndex addresses are handled separately
215 //errs() << "SelectADDRri: ";
216 //Addr.getNode()->dumpr();
217 if (isa<FrameIndexSDNode>(Addr)) {
218 //errs() << "Failure\n";
219 return false;
220 }
221
222 if (CurDAG->isBaseWithConstantOffset(Addr)) {
223 Base = Addr.getOperand(0);
224 if (isa<FrameIndexSDNode>(Base)) {
225 //errs() << "Failure\n";
226 return false;
227 }
228 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
229 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
230 //errs() << "Success\n";
231 return true;
232 }
233
234 /*if (Addr.getNumOperands() == 1) {
235 Base = Addr;
236 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
237 errs() << "Success\n";
238 return true;
239 }*/
240
241 //errs() << "SelectADDRri fails on: ";
242 //Addr.getNode()->dumpr();
243
244 if (isImm(Addr)) {
245 //errs() << "Failure\n";
246 return false;
247 }
248
249 Base = Addr;
250 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
251
252 //errs() << "Success\n";
253 return true;
254
255 /*if (Addr.getOpcode() != ISD::ADD) {
256 // let SelectADDRii handle the [imm] case
257 if (isImm(Addr))
258 return false;
259 // it is [reg]
260
261 assert(Addr.getValueType().isSimple() && "Type must be simple");
262 Base = Addr;
263 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
264
265 return true;
266 }
267
268 if (Addr.getNumOperands() < 2)
269 return false;
270
271 // let SelectADDRii handle the [imm+imm] case
272 if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
273 return false;
274
275 // try [reg+imm] and [imm+reg]
276 for (int i = 0; i < 2; i ++)
277 if (SelectImm(Addr.getOperand(1-i), Offset)) {
278 Base = Addr.getOperand(i);
279 return true;
280 }
281
282 // neither [reg+imm] nor [imm+reg]
283 return false;*/
284 }
285
286 // Match memory operand of the form [imm+imm] and [imm]
SelectADDRii(SDValue & Addr,SDValue & Base,SDValue & Offset)287 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
288 SDValue &Offset) {
289 // is [imm+imm]?
290 if (Addr.getOpcode() == ISD::ADD) {
291 return SelectImm(Addr.getOperand(0), Base) &&
292 SelectImm(Addr.getOperand(1), Offset);
293 }
294
295 // is [imm]?
296 if (SelectImm(Addr, Base)) {
297 assert(Addr.getValueType().isSimple() && "Type must be simple");
298
299 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
300
301 return true;
302 }
303
304 return false;
305 }
306
307 // Match memory operand of the form [reg], [imm+reg], and [reg+imm]
SelectADDRlocal(SDValue & Addr,SDValue & Base,SDValue & Offset)308 bool PTXDAGToDAGISel::SelectADDRlocal(SDValue &Addr, SDValue &Base,
309 SDValue &Offset) {
310 //errs() << "SelectADDRlocal: ";
311 //Addr.getNode()->dumpr();
312 if (isa<FrameIndexSDNode>(Addr)) {
313 Base = Addr;
314 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
315 //errs() << "Success\n";
316 return true;
317 }
318
319 if (CurDAG->isBaseWithConstantOffset(Addr)) {
320 Base = Addr.getOperand(0);
321 if (!isa<FrameIndexSDNode>(Base)) {
322 //errs() << "Failure\n";
323 return false;
324 }
325 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
326 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
327 //errs() << "Offset: ";
328 //Offset.getNode()->dumpr();
329 //errs() << "Success\n";
330 return true;
331 }
332
333 //errs() << "Failure\n";
334 return false;
335 }
336
isImm(const SDValue & operand)337 bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
338 return ConstantSDNode::classof(operand.getNode());
339 }
340
SelectImm(const SDValue & operand,SDValue & imm)341 bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
342 SDNode *node = operand.getNode();
343 if (!ConstantSDNode::classof(node))
344 return false;
345
346 ConstantSDNode *CN = cast<ConstantSDNode>(node);
347 imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(),
348 operand.getValueType());
349 return true;
350 }
351
getSubtarget() const352 const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const
353 {
354 return TM.getSubtarget<PTXSubtarget>();
355 }
356
357