1249259Sdim//===-- AMDGPUISelLowering.h - AMDGPU Lowering Interface --------*- C++ -*-===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim/// \file
11249259Sdim/// \brief Interface definition of the TargetLowering class that is common
12249259Sdim/// to all AMD GPUs.
13249259Sdim//
14249259Sdim//===----------------------------------------------------------------------===//
15249259Sdim
16249259Sdim#ifndef AMDGPUISELLOWERING_H
17249259Sdim#define AMDGPUISELLOWERING_H
18249259Sdim
19249259Sdim#include "llvm/Target/TargetLowering.h"
20249259Sdim
21249259Sdimnamespace llvm {
22249259Sdim
23263508Sdimclass AMDGPUMachineFunction;
24249259Sdimclass MachineRegisterInfo;
25249259Sdim
26249259Sdimclass AMDGPUTargetLowering : public TargetLowering {
27249259Sdimprivate:
28263508Sdim  void ExtractVectorElements(SDValue Op, SelectionDAG &DAG,
29263508Sdim                             SmallVectorImpl<SDValue> &Args,
30263508Sdim                             unsigned Start, unsigned Count) const;
31263508Sdim  SDValue LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const;
32263508Sdim  SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
33263508Sdim  SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
34249259Sdim  SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
35263508Sdim  /// \brief Lower vector stores by merging the vector elements into an integer
36263508Sdim  /// of the same bitwidth.
37263508Sdim  SDValue MergeVectorStore(const SDValue &Op, SelectionDAG &DAG) const;
38263508Sdim  /// \brief Split a vector store into multiple scalar stores.
39263508Sdim  /// \returns The resulting chain.
40249259Sdim  SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
41263508Sdim  SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
42249259Sdim
43249259Sdimprotected:
44249259Sdim
45249259Sdim  /// \brief Helper function that adds Reg to the LiveIn list of the DAG's
46249259Sdim  /// MachineFunction.
47249259Sdim  ///
48249259Sdim  /// \returns a RegisterSDNode representing Reg.
49263508Sdim  virtual SDValue CreateLiveInRegister(SelectionDAG &DAG,
50263508Sdim                                       const TargetRegisterClass *RC,
51263508Sdim                                       unsigned Reg, EVT VT) const;
52263508Sdim  SDValue LowerGlobalAddress(AMDGPUMachineFunction *MFI, SDValue Op,
53263508Sdim                             SelectionDAG &DAG) const;
54263508Sdim  /// \brief Split a vector load into multiple scalar loads.
55263508Sdim  SDValue SplitVectorLoad(const SDValue &Op, SelectionDAG &DAG) const;
56263508Sdim  SDValue SplitVectorStore(SDValue Op, SelectionDAG &DAG) const;
57263508Sdim  SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
58249259Sdim  bool isHWTrueValue(SDValue Op) const;
59249259Sdim  bool isHWFalseValue(SDValue Op) const;
60249259Sdim
61263508Sdim  /// The SelectionDAGBuilder will automatically promote function arguments
62263508Sdim  /// with illegal types.  However, this does not work for the AMDGPU targets
63263508Sdim  /// since the function arguments are stored in memory as these illegal types.
64263508Sdim  /// In order to handle this properly we need to get the origianl types sizes
65263508Sdim  /// from the LLVM IR Function and fixup the ISD:InputArg values before
66263508Sdim  /// passing them to AnalyzeFormalArguments()
67263508Sdim  void getOriginalFunctionArgs(SelectionDAG &DAG,
68263508Sdim                               const Function *F,
69263508Sdim                               const SmallVectorImpl<ISD::InputArg> &Ins,
70263508Sdim                               SmallVectorImpl<ISD::InputArg> &OrigIns) const;
71249259Sdim  void AnalyzeFormalArguments(CCState &State,
72249259Sdim                              const SmallVectorImpl<ISD::InputArg> &Ins) const;
73249259Sdim
74249259Sdimpublic:
75249259Sdim  AMDGPUTargetLowering(TargetMachine &TM);
76249259Sdim
77263508Sdim  virtual bool isFAbsFree(EVT VT) const;
78263508Sdim  virtual bool isFNegFree(EVT VT) const;
79263508Sdim  virtual MVT getVectorIdxTy() const;
80263508Sdim  virtual bool isLoadBitCastBeneficial(EVT, EVT) const LLVM_OVERRIDE;
81249259Sdim  virtual SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv,
82249259Sdim                              bool isVarArg,
83249259Sdim                              const SmallVectorImpl<ISD::OutputArg> &Outs,
84249259Sdim                              const SmallVectorImpl<SDValue> &OutVals,
85263508Sdim                              SDLoc DL, SelectionDAG &DAG) const;
86249259Sdim  virtual SDValue LowerCall(CallLoweringInfo &CLI,
87249259Sdim                            SmallVectorImpl<SDValue> &InVals) const {
88249259Sdim    CLI.Callee.dump();
89249259Sdim    llvm_unreachable("Undefined function");
90249259Sdim  }
91249259Sdim
92249259Sdim  virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
93249259Sdim  SDValue LowerIntrinsicIABS(SDValue Op, SelectionDAG &DAG) const;
94249259Sdim  SDValue LowerIntrinsicLRP(SDValue Op, SelectionDAG &DAG) const;
95249259Sdim  SDValue LowerMinMax(SDValue Op, SelectionDAG &DAG) const;
96249259Sdim  virtual const char* getTargetNodeName(unsigned Opcode) const;
97249259Sdim
98249259Sdim  virtual SDNode *PostISelFolding(MachineSDNode *N, SelectionDAG &DAG) const {
99249259Sdim    return N;
100249259Sdim  }
101249259Sdim
102249259Sdim// Functions defined in AMDILISelLowering.cpp
103249259Sdimpublic:
104249259Sdim
105249259Sdim  /// \brief Determine which of the bits specified in \p Mask are known to be
106249259Sdim  /// either zero or one and return them in the \p KnownZero and \p KnownOne
107249259Sdim  /// bitsets.
108249259Sdim  virtual void computeMaskedBitsForTargetNode(const SDValue Op,
109249259Sdim                                              APInt &KnownZero,
110249259Sdim                                              APInt &KnownOne,
111249259Sdim                                              const SelectionDAG &DAG,
112249259Sdim                                              unsigned Depth = 0) const;
113249259Sdim
114249259Sdim  virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
115249259Sdim                                  const CallInst &I, unsigned Intrinsic) const;
116249259Sdim
117249259Sdim  /// We want to mark f32/f64 floating point values as legal.
118249259Sdim  bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
119249259Sdim
120249259Sdim  /// We don't want to shrink f64/f32 constants.
121249259Sdim  bool ShouldShrinkFPConstant(EVT VT) const;
122249259Sdim
123249259Sdimprivate:
124249259Sdim  void InitAMDILLowering();
125249259Sdim  SDValue LowerSREM(SDValue Op, SelectionDAG &DAG) const;
126249259Sdim  SDValue LowerSREM8(SDValue Op, SelectionDAG &DAG) const;
127249259Sdim  SDValue LowerSREM16(SDValue Op, SelectionDAG &DAG) const;
128249259Sdim  SDValue LowerSREM32(SDValue Op, SelectionDAG &DAG) const;
129249259Sdim  SDValue LowerSREM64(SDValue Op, SelectionDAG &DAG) const;
130249259Sdim  SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG) const;
131249259Sdim  SDValue LowerSDIV24(SDValue Op, SelectionDAG &DAG) const;
132249259Sdim  SDValue LowerSDIV32(SDValue Op, SelectionDAG &DAG) const;
133249259Sdim  SDValue LowerSDIV64(SDValue Op, SelectionDAG &DAG) const;
134249259Sdim  SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const;
135249259Sdim  EVT genIntType(uint32_t size = 32, uint32_t numEle = 1) const;
136249259Sdim  SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
137249259Sdim  SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
138249259Sdim};
139249259Sdim
140249259Sdimnamespace AMDGPUISD {
141249259Sdim
142249259Sdimenum {
143249259Sdim  // AMDIL ISD Opcodes
144249259Sdim  FIRST_NUMBER = ISD::BUILTIN_OP_END,
145249259Sdim  CALL,        // Function call based on a single integer
146249259Sdim  UMUL,        // 32bit unsigned multiplication
147249259Sdim  DIV_INF,      // Divide with infinity returned on zero divisor
148249259Sdim  RET_FLAG,
149249259Sdim  BRANCH_COND,
150249259Sdim  // End AMDIL ISD Opcodes
151249259Sdim  DWORDADDR,
152249259Sdim  FRACT,
153263508Sdim  COS_HW,
154263508Sdim  SIN_HW,
155249259Sdim  FMAX,
156249259Sdim  SMAX,
157249259Sdim  UMAX,
158249259Sdim  FMIN,
159249259Sdim  SMIN,
160249259Sdim  UMIN,
161249259Sdim  URECIP,
162263508Sdim  DOT4,
163263508Sdim  TEXTURE_FETCH,
164249259Sdim  EXPORT,
165249259Sdim  CONST_ADDRESS,
166249259Sdim  REGISTER_LOAD,
167249259Sdim  REGISTER_STORE,
168263508Sdim  LOAD_INPUT,
169263508Sdim  SAMPLE,
170263508Sdim  SAMPLEB,
171263508Sdim  SAMPLED,
172263508Sdim  SAMPLEL,
173263508Sdim  FIRST_MEM_OPCODE_NUMBER = ISD::FIRST_TARGET_MEMORY_OPCODE,
174263508Sdim  STORE_MSKOR,
175263508Sdim  LOAD_CONSTANT,
176263508Sdim  TBUFFER_STORE_FORMAT,
177249259Sdim  LAST_AMDGPU_ISD_NUMBER
178249259Sdim};
179249259Sdim
180249259Sdim
181249259Sdim} // End namespace AMDGPUISD
182249259Sdim
183249259Sdim} // End namespace llvm
184249259Sdim
185249259Sdim#endif // AMDGPUISELLOWERING_H
186