blob: 935064d025821c7f91b9e40f048d7edf806b744e [file] [log] [blame]
Scott Michel266bc8f2007-12-04 22:23:35 +00001//===-- SPUISelDAGToDAG.cpp - CellSPU -pattern matching inst selector -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by a team from the Computer Systems Research
Scott Michel2466c372007-12-05 01:40:25 +00006// Department at The Aerospace Corporation and is distributed under the
7// University of Illinois Open Source License. See LICENSE.TXT for details.
Scott Michel266bc8f2007-12-04 22:23:35 +00008//
9//===----------------------------------------------------------------------===//
10//
11// This file defines a pattern matching instruction selector for the Cell SPU,
12// converting from a legalized dag to a SPU-target dag.
13//
14//===----------------------------------------------------------------------===//
15
16#include "SPU.h"
17#include "SPUTargetMachine.h"
18#include "SPUISelLowering.h"
19#include "SPUHazardRecognizers.h"
20#include "SPUFrameInfo.h"
21#include "llvm/CodeGen/MachineConstantPool.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/SSARegMap.h"
25#include "llvm/CodeGen/SelectionDAG.h"
26#include "llvm/CodeGen/SelectionDAGISel.h"
27#include "llvm/Target/TargetOptions.h"
28#include "llvm/ADT/Statistic.h"
29#include "llvm/Constants.h"
30#include "llvm/GlobalValue.h"
31#include "llvm/Intrinsics.h"
32#include "llvm/Support/Debug.h"
33#include "llvm/Support/MathExtras.h"
34#include "llvm/Support/Compiler.h"
35#include <iostream>
36#include <queue>
37#include <set>
38
39using namespace llvm;
40
41namespace {
42 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
43 bool
44 isI64IntS10Immediate(ConstantSDNode *CN)
45 {
46 return isS10Constant(CN->getValue());
47 }
48
49 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
50 bool
51 isI32IntS10Immediate(ConstantSDNode *CN)
52 {
53 return isS10Constant((int) CN->getValue());
54 }
55
56#if 0
57 //! SDNode predicate for sign-extended, 10-bit immediate values
58 bool
59 isI32IntS10Immediate(SDNode *N)
60 {
61 return (N->getOpcode() == ISD::Constant
62 && isI32IntS10Immediate(cast<ConstantSDNode>(N)));
63 }
64#endif
65
66 //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
67 bool
68 isI16IntS10Immediate(ConstantSDNode *CN)
69 {
70 return isS10Constant((short) CN->getValue());
71 }
72
73 //! SDNode predicate for i16 sign-extended, 10-bit immediate values
74 bool
75 isI16IntS10Immediate(SDNode *N)
76 {
77 return (N->getOpcode() == ISD::Constant
78 && isI16IntS10Immediate(cast<ConstantSDNode>(N)));
79 }
80
81 //! ConstantSDNode predicate for signed 16-bit values
82 /*!
83 \arg CN The constant SelectionDAG node holding the value
84 \arg Imm The returned 16-bit value, if returning true
85
86 This predicate tests the value in \a CN to see whether it can be
87 represented as a 16-bit, sign-extended quantity. Returns true if
88 this is the case.
89 */
90 bool
91 isIntS16Immediate(ConstantSDNode *CN, short &Imm)
92 {
93 MVT::ValueType vt = CN->getValueType(0);
94 Imm = (short) CN->getValue();
95 if (vt >= MVT::i1 && vt <= MVT::i16) {
96 return true;
97 } else if (vt == MVT::i32) {
98 int32_t i_val = (int32_t) CN->getValue();
99 short s_val = (short) i_val;
100 return i_val == s_val;
101 } else {
102 int64_t i_val = (int64_t) CN->getValue();
103 short s_val = (short) i_val;
104 return i_val == s_val;
105 }
106
107 return false;
108 }
109
110 //! SDNode predicate for signed 16-bit values.
111 bool
112 isIntS16Immediate(SDNode *N, short &Imm)
113 {
114 return (N->getOpcode() == ISD::Constant
115 && isIntS16Immediate(cast<ConstantSDNode>(N), Imm));
116 }
117
118 //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
119 static bool
120 isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
121 {
122 MVT::ValueType vt = FPN->getValueType(0);
123 if (vt == MVT::f32) {
124 const APFloat &apf = FPN->getValueAPF();
125 float fval = apf.convertToFloat();
126 int val = *((int *) &fval);
127 int sval = (int) ((val << 16) >> 16);
128 Imm = (short) val;
129 return val == sval;
130 }
131
132 return false;
133 }
134
135 //===------------------------------------------------------------------===//
136 //! MVT::ValueType to useful stuff structure:
137
138 struct valtype_map_s {
139 MVT::ValueType VT;
140 unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined)
141 int prefslot_byte; /// Byte offset of the "preferred" slot
142 unsigned brcc_eq_ins; /// br_cc equal instruction
143 unsigned brcc_neq_ins; /// br_cc not equal instruction
144 };
145
146 const valtype_map_s valtype_map[] = {
147 { MVT::i1, 0, 3, 0, 0 },
148 { MVT::i8, 0, 3, 0, 0 },
149 { MVT::i16, SPU::ORHIr16, 2, SPU::BRHZ, SPU::BRHNZ },
150 { MVT::i32, SPU::ORIr32, 0, SPU::BRZ, SPU::BRNZ },
151 { MVT::i64, SPU::ORIr64, 0, 0, 0 },
152 { MVT::f32, SPU::ORIf32, 0, 0, 0 },
153 { MVT::f64, SPU::ORIf64, 0, 0, 0 }
154 };
155
156 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
157
158 const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT)
159 {
160 const valtype_map_s *retval = 0;
161 for (size_t i = 0; i < n_valtype_map; ++i) {
162 if (valtype_map[i].VT == VT) {
163 retval = valtype_map + i;
164 break;
165 }
166 }
167
168
169#ifndef NDEBUG
170 if (retval == 0) {
171 cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
172 << MVT::getValueTypeString(VT)
173 << "\n";
174 abort();
175 }
176#endif
177
178 return retval;
179 }
180}
181
182//===--------------------------------------------------------------------===//
183/// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
184/// instructions for SelectionDAG operations.
185///
186class SPUDAGToDAGISel :
187 public SelectionDAGISel
188{
189 SPUTargetMachine &TM;
190 SPUTargetLowering &SPUtli;
191 unsigned GlobalBaseReg;
192
193public:
194 SPUDAGToDAGISel(SPUTargetMachine &tm) :
195 SelectionDAGISel(*tm.getTargetLowering()),
196 TM(tm),
197 SPUtli(*tm.getTargetLowering())
198 {}
199
200 virtual bool runOnFunction(Function &Fn) {
201 // Make sure we re-emit a set of the global base reg if necessary
202 GlobalBaseReg = 0;
203 SelectionDAGISel::runOnFunction(Fn);
204 return true;
205 }
206
207 /// getI32Imm - Return a target constant with the specified value, of type
208 /// i32.
209 inline SDOperand getI32Imm(uint32_t Imm) {
210 return CurDAG->getTargetConstant(Imm, MVT::i32);
211 }
212
213 /// getI64Imm - Return a target constant with the specified value, of type
214 /// i64.
215 inline SDOperand getI64Imm(uint64_t Imm) {
216 return CurDAG->getTargetConstant(Imm, MVT::i64);
217 }
218
219 /// getSmallIPtrImm - Return a target constant of pointer type.
220 inline SDOperand getSmallIPtrImm(unsigned Imm) {
221 return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
222 }
223
224 /// Select - Convert the specified operand from a target-independent to a
225 /// target-specific node if it hasn't already been changed.
226 SDNode *Select(SDOperand Op);
227
228 /// Return true if the address N is a RI7 format address [r+imm]
229 bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
230 SDOperand &Base);
231
232 //! Returns true if the address N is an A-form (local store) address
233 bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
234 SDOperand &Index);
235
236 //! D-form address predicate
237 bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
238 SDOperand &Index);
239
240 //! Address predicate if N can be expressed as an indexed [r+r] operation.
241 bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
242 SDOperand &Index);
243
244 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
245 /// inline asm expressions.
246 virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
247 char ConstraintCode,
248 std::vector<SDOperand> &OutOps,
249 SelectionDAG &DAG) {
250 SDOperand Op0, Op1;
251 switch (ConstraintCode) {
252 default: return true;
253 case 'm': // memory
254 if (!SelectDFormAddr(Op, Op, Op0, Op1)
255 && !SelectAFormAddr(Op, Op, Op0, Op1))
256 SelectXFormAddr(Op, Op, Op0, Op1);
257 break;
258 case 'o': // offsetable
259 if (!SelectDFormAddr(Op, Op, Op0, Op1)
260 && !SelectAFormAddr(Op, Op, Op0, Op1)) {
261 Op0 = Op;
262 AddToISelQueue(Op0); // r+0.
263 Op1 = getSmallIPtrImm(0);
264 }
265 break;
266 case 'v': // not offsetable
267#if 1
268 assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
269#else
270 SelectAddrIdxOnly(Op, Op, Op0, Op1);
271#endif
272 break;
273 }
274
275 OutOps.push_back(Op0);
276 OutOps.push_back(Op1);
277 return false;
278 }
279
280 /// InstructionSelectBasicBlock - This callback is invoked by
281 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
282 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
283
284 virtual const char *getPassName() const {
285 return "Cell SPU DAG->DAG Pattern Instruction Selection";
286 }
287
288 /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
289 /// this target when scheduling the DAG.
290 virtual HazardRecognizer *CreateTargetHazardRecognizer() {
291 const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo();
292 assert(II && "No InstrInfo?");
293 return new SPUHazardRecognizer(*II);
294 }
295
296 // Include the pieces autogenerated from the target description.
297#include "SPUGenDAGISel.inc"
298};
299
300/// InstructionSelectBasicBlock - This callback is invoked by
301/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
302void
303SPUDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG)
304{
305 DEBUG(BB->dump());
306
307 // Select target instructions for the DAG.
308 DAG.setRoot(SelectRoot(DAG.getRoot()));
309 DAG.RemoveDeadNodes();
310
311 // Emit machine code to BB.
312 ScheduleAndEmitDAG(DAG);
313}
314
315bool
316SPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
317 SDOperand &Base) {
318 unsigned Opc = N.getOpcode();
319 unsigned VT = N.getValueType();
320 MVT::ValueType PtrVT = SPUtli.getPointerTy();
321 ConstantSDNode *CN = 0;
322 int Imm;
323
324 if (Opc == ISD::ADD) {
325 SDOperand Op0 = N.getOperand(0);
326 SDOperand Op1 = N.getOperand(1);
327 if (Op1.getOpcode() == ISD::Constant ||
328 Op1.getOpcode() == ISD::TargetConstant) {
329 CN = cast<ConstantSDNode>(Op1);
330 Imm = int(CN->getValue());
331 if (Imm <= 0xff) {
332 Disp = CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
333 Base = Op0;
334 return true;
335 }
336 }
337 } else if (Opc == ISD::GlobalAddress
338 || Opc == ISD::TargetGlobalAddress
339 || Opc == ISD::Register) {
340 // Plain old local store address:
341 Disp = CurDAG->getTargetConstant(0, VT);
342 Base = N;
343 return true;
344 } else if (Opc == SPUISD::DFormAddr) {
345 // D-Form address: This is pretty straightforward, naturally...
346 CN = cast<ConstantSDNode>(N.getOperand(1));
347 assert(CN != 0 && "SelectDFormAddr/SPUISD::DForm2Addr expecting constant");
348 Imm = unsigned(CN->getValue());
349 if (Imm < 0xff) {
350 Disp = CurDAG->getTargetConstant(CN->getValue(), PtrVT);
351 Base = N.getOperand(0);
352 return true;
353 }
354 }
355
356 return false;
357}
358
359/*!
360 \arg Op The ISD instructio operand
361 \arg N The address to be tested
362 \arg Base The base address
363 \arg Index The base address index
364 */
365bool
366SPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
367 SDOperand &Index) {
368 // These match the addr256k operand type:
369 MVT::ValueType PtrVT = SPUtli.getPointerTy();
370 MVT::ValueType OffsVT = MVT::i16;
371
372 switch (N.getOpcode()) {
373 case ISD::Constant:
374 case ISD::TargetConstant: {
375 // Loading from a constant address.
376 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
377 int Imm = (int)CN->getValue();
378 if (Imm < 0x3ffff && (Imm & 0x3) == 0) {
379 Base = CurDAG->getTargetConstant(Imm, PtrVT);
380 // Note that this operand will be ignored by the assembly printer...
381 Index = CurDAG->getTargetConstant(0, OffsVT);
382 return true;
383 }
384 }
385 case ISD::ConstantPool:
386 case ISD::TargetConstantPool: {
387 // The constant pool address is N. Base is a dummy that will be ignored by
388 // the assembly printer.
389 Base = N;
390 Index = CurDAG->getTargetConstant(0, OffsVT);
391 return true;
392 }
393
394 case ISD::GlobalAddress:
395 case ISD::TargetGlobalAddress: {
396 // The global address is N. Base is a dummy that is ignored by the
397 // assembly printer.
398 Base = N;
399 Index = CurDAG->getTargetConstant(0, OffsVT);
400 return true;
401 }
402 }
403
404 return false;
405}
406
407/*!
408 \arg Op The ISD instruction (ignored)
409 \arg N The address to be tested
410 \arg Base Base address register/pointer
411 \arg Index Base address index
412
413 Examine the input address by a base register plus a signed 10-bit
414 displacement, [r+I10] (D-form address).
415
416 \return true if \a N is a D-form address with \a Base and \a Index set
417 to non-empty SDOperand instances.
418*/
419bool
420SPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
421 SDOperand &Index) {
422 unsigned Opc = N.getOpcode();
423 unsigned PtrTy = SPUtli.getPointerTy();
424
425 if (Opc == ISD::Register) {
426 Base = N;
427 Index = CurDAG->getTargetConstant(0, PtrTy);
428 return true;
429 } else if (Opc == ISD::FrameIndex) {
430 // Stack frame index must be less than 512 (divided by 16):
431 FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
432 DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
433 << FI->getIndex() << "\n");
434 if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
435 Base = CurDAG->getTargetConstant(0, PtrTy);
436 Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
437 return true;
438 }
439 } else if (Opc == ISD::ADD) {
440 // Generated by getelementptr
441 const SDOperand Op0 = N.getOperand(0); // Frame index/base
442 const SDOperand Op1 = N.getOperand(1); // Offset within base
443 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
444
445 // Not a constant?
446 if (CN == 0)
447 return false;
448
449 int32_t offset = (int32_t) CN->getSignExtended();
450 unsigned Opc0 = Op0.getOpcode();
451
452 if ((offset & 0xf) != 0) {
453 cerr << "SelectDFormAddr: unaligned offset = " << offset << "\n";
454 abort();
455 /*NOTREACHED*/
456 }
457
458 if (Opc0 == ISD::FrameIndex) {
459 FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0);
460 DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
461 << " frame index = " << FI->getIndex() << "\n");
462
463 if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
464 Base = CurDAG->getTargetConstant(offset, PtrTy);
465 Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
466 return true;
467 }
468 } else if (offset > SPUFrameInfo::minFrameOffset()
469 && offset < SPUFrameInfo::maxFrameOffset()) {
470 Base = CurDAG->getTargetConstant(offset, PtrTy);
471 if (Opc0 == ISD::GlobalAddress) {
472 // Convert global address to target global address
473 GlobalAddressSDNode *GV = dyn_cast<GlobalAddressSDNode>(Op0);
474 Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy);
475 return true;
476 } else {
477 // Otherwise, just take operand 0
478 Index = Op0;
479 return true;
480 }
481 }
482 } else if (Opc == SPUISD::DFormAddr) {
483 // D-Form address: This is pretty straightforward, naturally...
484 ConstantSDNode *CN = cast<ConstantSDNode>(N.getOperand(1));
485 assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant");
486 Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy);
487 Index = N.getOperand(0);
488 return true;
489 }
490
491 return false;
492}
493
494/*!
495 \arg Op The ISD instruction operand
496 \arg N The address operand
497 \arg Base The base pointer operand
498 \arg Index The offset/index operand
499
500 If the address \a N can be expressed as a [r + s10imm] address, returns false.
501 Otherwise, creates two operands, Base and Index that will become the [r+r]
502 address.
503*/
504bool
505SPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
506 SDOperand &Index) {
507 if (SelectAFormAddr(Op, N, Base, Index)
508 || SelectDFormAddr(Op, N, Base, Index))
509 return false;
510
511 unsigned Opc = N.getOpcode();
512
513 if (Opc == ISD::ADD) {
514 SDOperand N1 = N.getOperand(0);
515 SDOperand N2 = N.getOperand(1);
516 unsigned N1Opc = N1.getOpcode();
517 unsigned N2Opc = N2.getOpcode();
518
519 if ((N1Opc == SPUISD::Hi && N2Opc == SPUISD::Lo)
520 || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi)) {
521 Base = N.getOperand(0);
522 Index = N.getOperand(1);
523 return true;
524 } else {
525 cerr << "SelectXFormAddr: Unhandled ADD operands:\n";
526 N1.Val->dump();
527 cerr << "\n";
528 N2.Val->dump();
529 cerr << "\n";
530 abort();
531 /*UNREACHED*/
532 }
533 } else if (N.getNumOperands() == 2) {
534 SDOperand N1 = N.getOperand(0);
535 SDOperand N2 = N.getOperand(1);
536 unsigned N1Opc = N1.getOpcode();
537 unsigned N2Opc = N2.getOpcode();
538
539 if ((N1Opc == ISD::CopyToReg || N1Opc == ISD::Register)
540 && (N2Opc == ISD::CopyToReg || N2Opc == ISD::Register)) {
541 Base = N.getOperand(0);
542 Index = N.getOperand(1);
543 return true;
544 /*UNREACHED*/
545 } else {
546 cerr << "SelectXFormAddr: 2-operand unhandled operand:\n";
547 N.Val->dump();
548 cerr << "\n";
549 abort();
550 /*UNREACHED*/
551 }
552 } else {
553 cerr << "SelectXFormAddr: Unhandled operand type:\n";
554 N.Val->dump();
555 cerr << "\n";
556 abort();
557 /*UNREACHED*/
558 }
559
560 return false;
561}
562
563//! Convert the operand from a target-independent to a target-specific node
564/*!
565 */
566SDNode *
567SPUDAGToDAGISel::Select(SDOperand Op) {
568 SDNode *N = Op.Val;
569 unsigned Opc = N->getOpcode();
570
571 if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) {
572 return NULL; // Already selected.
573 } else if (Opc == ISD::FrameIndex) {
574 // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm.
575 int FI = cast<FrameIndexSDNode>(N)->getIndex();
576 SDOperand TFI = CurDAG->getTargetFrameIndex(FI, SPUtli.getPointerTy());
577
578 DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 TFI, 0\n");
579 return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI,
580 CurDAG->getTargetConstant(0, MVT::i32));
581 } else if (Opc == SPUISD::LDRESULT) {
582 // Custom select instructions for LDRESULT
583 unsigned VT = N->getValueType(0);
584 SDOperand Arg = N->getOperand(0);
585 SDOperand Chain = N->getOperand(1);
586 SDOperand Zero = CurDAG->getTargetConstant(0, VT);
587 SDNode *Result;
588 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
589
590 if (vtm->ldresult_ins == 0) {
591 cerr << "LDRESULT for unsupported type: "
592 << MVT::getValueTypeString(VT)
593 << "\n";
594 abort();
595 } else
596 Opc = vtm->ldresult_ins;
597
598 AddToISelQueue(Arg);
599 AddToISelQueue(Zero);
600 AddToISelQueue(Chain);
601 Result = CurDAG->SelectNodeTo(N, Opc, VT, MVT::Other, Arg, Zero, Chain);
602 Chain = SDOperand(Result, 1);
603 return Result;
604 }
605
606 return SelectCode(Op);
607}
608
609/// createPPCISelDag - This pass converts a legalized DAG into a
610/// SPU-specific DAG, ready for instruction scheduling.
611///
612FunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
613 return new SPUDAGToDAGISel(TM);
614}