R600: Match 24-bit arithmetic patterns in a Target DAGCombine
[oota-llvm.git] / lib / Target / R600 / AMDGPUISelDAGToDAG.cpp
1 //===-- AMDILISelDAGToDAG.cpp - A dag to dag inst selector for AMDIL ------===//
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 /// \file
11 /// \brief Defines an instruction selector for the AMDGPU target.
12 //
13 //===----------------------------------------------------------------------===//
14 #include "AMDGPUInstrInfo.h"
15 #include "AMDGPUISelLowering.h" // For AMDGPUISD
16 #include "AMDGPURegisterInfo.h"
17 #include "R600InstrInfo.h"
18 #include "SIISelLowering.h"
19 #include "llvm/Analysis/ValueTracking.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/PseudoSourceValue.h"
22 #include "llvm/CodeGen/SelectionDAG.h"
23 #include "llvm/CodeGen/SelectionDAGISel.h"
24 #include "llvm/IR/ValueMap.h"
25 #include "llvm/Support/Compiler.h"
26 #include <list>
27 #include <queue>
28
29 using namespace llvm;
30
31 //===----------------------------------------------------------------------===//
32 // Instruction Selector Implementation
33 //===----------------------------------------------------------------------===//
34
35 namespace {
36 /// AMDGPU specific code to select AMDGPU machine instructions for
37 /// SelectionDAG operations.
38 class AMDGPUDAGToDAGISel : public SelectionDAGISel {
39   // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can
40   // make the right decision when generating code for different targets.
41   const AMDGPUSubtarget &Subtarget;
42 public:
43   AMDGPUDAGToDAGISel(TargetMachine &TM);
44   virtual ~AMDGPUDAGToDAGISel();
45
46   SDNode *Select(SDNode *N);
47   virtual const char *getPassName() const;
48   virtual void PostprocessISelDAG();
49
50 private:
51   bool isInlineImmediate(SDNode *N) const;
52   inline SDValue getSmallIPtrImm(unsigned Imm);
53   bool FoldOperand(SDValue &Src, SDValue &Sel, SDValue &Neg, SDValue &Abs,
54                    const R600InstrInfo *TII);
55   bool FoldOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &);
56   bool FoldDotOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &);
57
58   // Complex pattern selectors
59   bool SelectADDRParam(SDValue Addr, SDValue& R1, SDValue& R2);
60   bool SelectADDR(SDValue N, SDValue &R1, SDValue &R2);
61   bool SelectADDR64(SDValue N, SDValue &R1, SDValue &R2);
62
63   static bool checkType(const Value *ptr, unsigned int addrspace);
64
65   static bool isGlobalStore(const StoreSDNode *N);
66   static bool isPrivateStore(const StoreSDNode *N);
67   static bool isLocalStore(const StoreSDNode *N);
68   static bool isRegionStore(const StoreSDNode *N);
69
70   bool isCPLoad(const LoadSDNode *N) const;
71   bool isConstantLoad(const LoadSDNode *N, int cbID) const;
72   bool isGlobalLoad(const LoadSDNode *N) const;
73   bool isParamLoad(const LoadSDNode *N) const;
74   bool isPrivateLoad(const LoadSDNode *N) const;
75   bool isLocalLoad(const LoadSDNode *N) const;
76   bool isRegionLoad(const LoadSDNode *N) const;
77
78   const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const;
79   bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr);
80   bool SelectGlobalValueVariableOffset(SDValue Addr,
81       SDValue &BaseReg, SDValue& Offset);
82   bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
83   bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset);
84
85   // Include the pieces autogenerated from the target description.
86 #include "AMDGPUGenDAGISel.inc"
87 };
88 }  // end anonymous namespace
89
90 /// \brief This pass converts a legalized DAG into a AMDGPU-specific
91 // DAG, ready for instruction scheduling.
92 FunctionPass *llvm::createAMDGPUISelDag(TargetMachine &TM
93                                        ) {
94   return new AMDGPUDAGToDAGISel(TM);
95 }
96
97 AMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM)
98   : SelectionDAGISel(TM), Subtarget(TM.getSubtarget<AMDGPUSubtarget>()) {
99 }
100
101 AMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() {
102 }
103
104 bool AMDGPUDAGToDAGISel::isInlineImmediate(SDNode *N) const {
105   const SITargetLowering *TL
106       = static_cast<const SITargetLowering *>(getTargetLowering());
107   return TL->analyzeImmediate(N) == 0;
108 }
109
110 /// \brief Determine the register class for \p OpNo
111 /// \returns The register class of the virtual register that will be used for
112 /// the given operand number \OpNo or NULL if the register class cannot be
113 /// determined.
114 const TargetRegisterClass *AMDGPUDAGToDAGISel::getOperandRegClass(SDNode *N,
115                                                           unsigned OpNo) const {
116   if (!N->isMachineOpcode()) {
117     return NULL;
118   }
119   switch (N->getMachineOpcode()) {
120   default: {
121     const MCInstrDesc &Desc = TM.getInstrInfo()->get(N->getMachineOpcode());
122     unsigned OpIdx = Desc.getNumDefs() + OpNo;
123     if (OpIdx >= Desc.getNumOperands())
124       return NULL;
125     int RegClass = Desc.OpInfo[OpIdx].RegClass;
126     if (RegClass == -1) {
127       return NULL;
128     }
129     return TM.getRegisterInfo()->getRegClass(RegClass);
130   }
131   case AMDGPU::REG_SEQUENCE: {
132     const TargetRegisterClass *SuperRC = TM.getRegisterInfo()->getRegClass(
133                       cast<ConstantSDNode>(N->getOperand(0))->getZExtValue());
134     unsigned SubRegIdx =
135             dyn_cast<ConstantSDNode>(N->getOperand(OpNo + 1))->getZExtValue();
136     return TM.getRegisterInfo()->getSubClassWithSubReg(SuperRC, SubRegIdx);
137   }
138   }
139 }
140
141 SDValue AMDGPUDAGToDAGISel::getSmallIPtrImm(unsigned int Imm) {
142   return CurDAG->getTargetConstant(Imm, MVT::i32);
143 }
144
145 bool AMDGPUDAGToDAGISel::SelectADDRParam(
146     SDValue Addr, SDValue& R1, SDValue& R2) {
147
148   if (Addr.getOpcode() == ISD::FrameIndex) {
149     if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
150       R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
151       R2 = CurDAG->getTargetConstant(0, MVT::i32);
152     } else {
153       R1 = Addr;
154       R2 = CurDAG->getTargetConstant(0, MVT::i32);
155     }
156   } else if (Addr.getOpcode() == ISD::ADD) {
157     R1 = Addr.getOperand(0);
158     R2 = Addr.getOperand(1);
159   } else {
160     R1 = Addr;
161     R2 = CurDAG->getTargetConstant(0, MVT::i32);
162   }
163   return true;
164 }
165
166 bool AMDGPUDAGToDAGISel::SelectADDR(SDValue Addr, SDValue& R1, SDValue& R2) {
167   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
168       Addr.getOpcode() == ISD::TargetGlobalAddress) {
169     return false;
170   }
171   return SelectADDRParam(Addr, R1, R2);
172 }
173
174
175 bool AMDGPUDAGToDAGISel::SelectADDR64(SDValue Addr, SDValue& R1, SDValue& R2) {
176   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
177       Addr.getOpcode() == ISD::TargetGlobalAddress) {
178     return false;
179   }
180
181   if (Addr.getOpcode() == ISD::FrameIndex) {
182     if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
183       R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
184       R2 = CurDAG->getTargetConstant(0, MVT::i64);
185     } else {
186       R1 = Addr;
187       R2 = CurDAG->getTargetConstant(0, MVT::i64);
188     }
189   } else if (Addr.getOpcode() == ISD::ADD) {
190     R1 = Addr.getOperand(0);
191     R2 = Addr.getOperand(1);
192   } else {
193     R1 = Addr;
194     R2 = CurDAG->getTargetConstant(0, MVT::i64);
195   }
196   return true;
197 }
198
199 SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) {
200   unsigned int Opc = N->getOpcode();
201   if (N->isMachineOpcode()) {
202     N->setNodeId(-1);
203     return NULL;   // Already selected.
204   }
205   switch (Opc) {
206   default: break;
207   // We are selecting i64 ADD here instead of custom lower it during
208   // DAG legalization, so we can fold some i64 ADDs used for address
209   // calculation into the LOAD and STORE instructions.
210   case ISD::ADD: {
211     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
212     if (N->getValueType(0) != MVT::i64 ||
213         ST.getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS)
214       break;
215
216     SDLoc DL(N);
217     SDValue LHS = N->getOperand(0);
218     SDValue RHS = N->getOperand(1);
219
220     SDValue Sub0 = CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32);
221     SDValue Sub1 = CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32);
222
223     SDNode *Lo0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
224                                          DL, MVT::i32, LHS, Sub0);
225     SDNode *Hi0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
226                                          DL, MVT::i32, LHS, Sub1);
227
228     SDNode *Lo1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
229                                          DL, MVT::i32, RHS, Sub0);
230     SDNode *Hi1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
231                                          DL, MVT::i32, RHS, Sub1);
232
233     SDVTList VTList = CurDAG->getVTList(MVT::i32, MVT::Glue);
234
235     SmallVector<SDValue, 8> AddLoArgs;
236     AddLoArgs.push_back(SDValue(Lo0, 0));
237     AddLoArgs.push_back(SDValue(Lo1, 0));
238
239     SDNode *AddLo = CurDAG->getMachineNode(AMDGPU::S_ADD_I32, DL,
240                                            VTList, AddLoArgs);
241     SDValue Carry = SDValue(AddLo, 1);
242     SDNode *AddHi = CurDAG->getMachineNode(AMDGPU::S_ADDC_U32, DL,
243                                            MVT::i32, SDValue(Hi0, 0),
244                                            SDValue(Hi1, 0), Carry);
245
246     SDValue Args[5] = {
247       CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, MVT::i32),
248       SDValue(AddLo,0),
249       Sub0,
250       SDValue(AddHi,0),
251       Sub1,
252     };
253     return CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, MVT::i64, Args, 5);
254   }
255   case ISD::BUILD_VECTOR: {
256     unsigned RegClassID;
257     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
258     const AMDGPURegisterInfo *TRI =
259                    static_cast<const AMDGPURegisterInfo*>(TM.getRegisterInfo());
260     const SIRegisterInfo *SIRI =
261                    static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
262     EVT VT = N->getValueType(0);
263     unsigned NumVectorElts = VT.getVectorNumElements();
264     assert(VT.getVectorElementType().bitsEq(MVT::i32));
265     if (ST.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) {
266       bool UseVReg = true;
267       for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
268                                                     U != E; ++U) {
269         if (!U->isMachineOpcode()) {
270           continue;
271         }
272         const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo());
273         if (!RC) {
274           continue;
275         }
276         if (SIRI->isSGPRClass(RC)) {
277           UseVReg = false;
278         }
279       }
280       switch(NumVectorElts) {
281       case 1: RegClassID = UseVReg ? AMDGPU::VReg_32RegClassID :
282                                      AMDGPU::SReg_32RegClassID;
283         break;
284       case 2: RegClassID = UseVReg ? AMDGPU::VReg_64RegClassID :
285                                      AMDGPU::SReg_64RegClassID;
286         break;
287       case 4: RegClassID = UseVReg ? AMDGPU::VReg_128RegClassID :
288                                      AMDGPU::SReg_128RegClassID;
289         break;
290       case 8: RegClassID = UseVReg ? AMDGPU::VReg_256RegClassID :
291                                      AMDGPU::SReg_256RegClassID;
292         break;
293       case 16: RegClassID = UseVReg ? AMDGPU::VReg_512RegClassID :
294                                       AMDGPU::SReg_512RegClassID;
295         break;
296       default: llvm_unreachable("Do not know how to lower this BUILD_VECTOR");
297       }
298     } else {
299       // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG
300       // that adds a 128 bits reg copy when going through TwoAddressInstructions
301       // pass. We want to avoid 128 bits copies as much as possible because they
302       // can't be bundled by our scheduler.
303       switch(NumVectorElts) {
304       case 2: RegClassID = AMDGPU::R600_Reg64RegClassID; break;
305       case 4: RegClassID = AMDGPU::R600_Reg128RegClassID; break;
306       default: llvm_unreachable("Do not know how to lower this BUILD_VECTOR");
307       }
308     }
309
310     SDValue RegClass = CurDAG->getTargetConstant(RegClassID, MVT::i32);
311
312     if (NumVectorElts == 1) {
313       return CurDAG->SelectNodeTo(N, AMDGPU::COPY_TO_REGCLASS,
314                                   VT.getVectorElementType(),
315                                   N->getOperand(0), RegClass);
316     }
317
318     assert(NumVectorElts <= 16 && "Vectors with more than 16 elements not "
319                                   "supported yet");
320     // 16 = Max Num Vector Elements
321     // 2 = 2 REG_SEQUENCE operands per element (value, subreg index)
322     // 1 = Vector Register Class
323     SDValue RegSeqArgs[16 * 2 + 1];
324
325     RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, MVT::i32);
326     bool IsRegSeq = true;
327     for (unsigned i = 0; i < N->getNumOperands(); i++) {
328       // XXX: Why is this here?
329       if (dyn_cast<RegisterSDNode>(N->getOperand(i))) {
330         IsRegSeq = false;
331         break;
332       }
333       RegSeqArgs[1 + (2 * i)] = N->getOperand(i);
334       RegSeqArgs[1 + (2 * i) + 1] =
335               CurDAG->getTargetConstant(TRI->getSubRegFromChannel(i), MVT::i32);
336     }
337     if (!IsRegSeq)
338       break;
339     return CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, N->getVTList(),
340         RegSeqArgs, 2 * N->getNumOperands() + 1);
341   }
342   case ISD::BUILD_PAIR: {
343     SDValue RC, SubReg0, SubReg1;
344     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
345     if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
346       break;
347     }
348     if (N->getValueType(0) == MVT::i128) {
349       RC = CurDAG->getTargetConstant(AMDGPU::SReg_128RegClassID, MVT::i32);
350       SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0_sub1, MVT::i32);
351       SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub2_sub3, MVT::i32);
352     } else if (N->getValueType(0) == MVT::i64) {
353       RC = CurDAG->getTargetConstant(AMDGPU::VSrc_64RegClassID, MVT::i32);
354       SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32);
355       SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32);
356     } else {
357       llvm_unreachable("Unhandled value type for BUILD_PAIR");
358     }
359     const SDValue Ops[] = { RC, N->getOperand(0), SubReg0,
360                             N->getOperand(1), SubReg1 };
361     return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
362                                   SDLoc(N), N->getValueType(0), Ops);
363   }
364
365   case ISD::Constant:
366   case ISD::ConstantFP: {
367     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
368     if (ST.getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS ||
369         N->getValueType(0).getSizeInBits() != 64 || isInlineImmediate(N))
370       break;
371
372     uint64_t Imm;
373     if (ConstantFPSDNode *FP = dyn_cast<ConstantFPSDNode>(N))
374       Imm = FP->getValueAPF().bitcastToAPInt().getZExtValue();
375     else {
376       ConstantSDNode *C = cast<ConstantSDNode>(N);
377       Imm = C->getZExtValue();
378     }
379
380     SDNode *Lo = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SDLoc(N), MVT::i32,
381                                 CurDAG->getConstant(Imm & 0xFFFFFFFF, MVT::i32));
382     SDNode *Hi = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SDLoc(N), MVT::i32,
383                                 CurDAG->getConstant(Imm >> 32, MVT::i32));
384     const SDValue Ops[] = {
385       CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, MVT::i32),
386       SDValue(Lo, 0), CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32),
387       SDValue(Hi, 0), CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32)
388     };
389
390     return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, SDLoc(N),
391                                   N->getValueType(0), Ops);
392   }
393
394   case AMDGPUISD::REGISTER_LOAD: {
395     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
396     if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS)
397       break;
398     SDValue Addr, Offset;
399
400     SelectADDRIndirect(N->getOperand(1), Addr, Offset);
401     const SDValue Ops[] = {
402       Addr,
403       Offset,
404       CurDAG->getTargetConstant(0, MVT::i32),
405       N->getOperand(0),
406     };
407     return CurDAG->getMachineNode(AMDGPU::SI_RegisterLoad, SDLoc(N),
408                                   CurDAG->getVTList(MVT::i32, MVT::i64, MVT::Other),
409                                   Ops);
410   }
411   case AMDGPUISD::REGISTER_STORE: {
412     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
413     if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS)
414       break;
415     SDValue Addr, Offset;
416     SelectADDRIndirect(N->getOperand(2), Addr, Offset);
417     const SDValue Ops[] = {
418       N->getOperand(1),
419       Addr,
420       Offset,
421       CurDAG->getTargetConstant(0, MVT::i32),
422       N->getOperand(0),
423     };
424     return CurDAG->getMachineNode(AMDGPU::SI_RegisterStorePseudo, SDLoc(N),
425                                         CurDAG->getVTList(MVT::Other),
426                                         Ops);
427   }
428   }
429   return SelectCode(N);
430 }
431
432
433 bool AMDGPUDAGToDAGISel::checkType(const Value *ptr, unsigned int addrspace) {
434   if (!ptr) {
435     return false;
436   }
437   Type *ptrType = ptr->getType();
438   return dyn_cast<PointerType>(ptrType)->getAddressSpace() == addrspace;
439 }
440
441 bool AMDGPUDAGToDAGISel::isGlobalStore(const StoreSDNode *N) {
442   return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS);
443 }
444
445 bool AMDGPUDAGToDAGISel::isPrivateStore(const StoreSDNode *N) {
446   return (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS)
447           && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS)
448           && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS));
449 }
450
451 bool AMDGPUDAGToDAGISel::isLocalStore(const StoreSDNode *N) {
452   return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS);
453 }
454
455 bool AMDGPUDAGToDAGISel::isRegionStore(const StoreSDNode *N) {
456   return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS);
457 }
458
459 bool AMDGPUDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int CbId) const {
460   if (CbId == -1) {
461     return checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS);
462   }
463   return checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_BUFFER_0 + CbId);
464 }
465
466 bool AMDGPUDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) const {
467   if (N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS) {
468     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
469     if (ST.getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS ||
470         N->getMemoryVT().bitsLT(MVT::i32)) {
471       return true;
472     }
473   }
474   return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS);
475 }
476
477 bool AMDGPUDAGToDAGISel::isParamLoad(const LoadSDNode *N) const {
478   return checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS);
479 }
480
481 bool AMDGPUDAGToDAGISel::isLocalLoad(const  LoadSDNode *N) const {
482   return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS);
483 }
484
485 bool AMDGPUDAGToDAGISel::isRegionLoad(const  LoadSDNode *N) const {
486   return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS);
487 }
488
489 bool AMDGPUDAGToDAGISel::isCPLoad(const LoadSDNode *N) const {
490   MachineMemOperand *MMO = N->getMemOperand();
491   if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) {
492     if (MMO) {
493       const Value *V = MMO->getValue();
494       const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V);
495       if (PSV && PSV == PseudoSourceValue::getConstantPool()) {
496         return true;
497       }
498     }
499   }
500   return false;
501 }
502
503 bool AMDGPUDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) const {
504   if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) {
505     // Check to make sure we are not a constant pool load or a constant load
506     // that is marked as a private load
507     if (isCPLoad(N) || isConstantLoad(N, -1)) {
508       return false;
509     }
510   }
511   if (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS)
512       && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS)
513       && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS)
514       && !checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS)
515       && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_D_ADDRESS)
516       && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS)) {
517     return true;
518   }
519   return false;
520 }
521
522 const char *AMDGPUDAGToDAGISel::getPassName() const {
523   return "AMDGPU DAG->DAG Pattern Instruction Selection";
524 }
525
526 #ifdef DEBUGTMP
527 #undef INT64_C
528 #endif
529 #undef DEBUGTMP
530
531 //===----------------------------------------------------------------------===//
532 // Complex Patterns
533 //===----------------------------------------------------------------------===//
534
535 bool AMDGPUDAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr,
536     SDValue& IntPtr) {
537   if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) {
538     IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, true);
539     return true;
540   }
541   return false;
542 }
543
544 bool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr,
545     SDValue& BaseReg, SDValue &Offset) {
546   if (!dyn_cast<ConstantSDNode>(Addr)) {
547     BaseReg = Addr;
548     Offset = CurDAG->getIntPtrConstant(0, true);
549     return true;
550   }
551   return false;
552 }
553
554 bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
555                                            SDValue &Offset) {
556   ConstantSDNode * IMMOffset;
557
558   if (Addr.getOpcode() == ISD::ADD
559       && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
560       && isInt<16>(IMMOffset->getZExtValue())) {
561
562       Base = Addr.getOperand(0);
563       Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
564       return true;
565   // If the pointer address is constant, we can move it to the offset field.
566   } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr))
567              && isInt<16>(IMMOffset->getZExtValue())) {
568     Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
569                                   SDLoc(CurDAG->getEntryNode()),
570                                   AMDGPU::ZERO, MVT::i32);
571     Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
572     return true;
573   }
574
575   // Default case, no offset
576   Base = Addr;
577   Offset = CurDAG->getTargetConstant(0, MVT::i32);
578   return true;
579 }
580
581 bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base,
582                                             SDValue &Offset) {
583   ConstantSDNode *C;
584
585   if ((C = dyn_cast<ConstantSDNode>(Addr))) {
586     Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32);
587     Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32);
588   } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) &&
589             (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) {
590     Base = Addr.getOperand(0);
591     Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32);
592   } else {
593     Base = Addr;
594     Offset = CurDAG->getTargetConstant(0, MVT::i32);
595   }
596
597   return true;
598 }
599
600 void AMDGPUDAGToDAGISel::PostprocessISelDAG() {
601   const AMDGPUTargetLowering& Lowering =
602     (*(const AMDGPUTargetLowering*)getTargetLowering());
603   bool IsModified = false;
604   do {
605     IsModified = false;
606     // Go over all selected nodes and try to fold them a bit more
607     for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
608          E = CurDAG->allnodes_end(); I != E; ++I) {
609
610       SDNode *Node = I;
611
612       MachineSDNode *MachineNode = dyn_cast<MachineSDNode>(I);
613       if (!MachineNode)
614         continue;
615
616       SDNode *ResNode = Lowering.PostISelFolding(MachineNode, *CurDAG);
617       if (ResNode != Node) {
618         ReplaceUses(Node, ResNode);
619         IsModified = true;
620       }
621     }
622     CurDAG->RemoveDeadNodes();
623   } while (IsModified);
624 }