]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/HexagonISelLowering.h
MFV r336991, r337001:
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Hexagon / HexagonISelLowering.h
1 //===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//
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 the interfaces that Hexagon uses to lower LLVM code into a
11 // selection DAG.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
16 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
17
18 #include "Hexagon.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/CodeGen/ISDOpcodes.h"
21 #include "llvm/CodeGen/MachineValueType.h"
22 #include "llvm/CodeGen/SelectionDAGNodes.h"
23 #include "llvm/CodeGen/TargetLowering.h"
24 #include "llvm/CodeGen/ValueTypes.h"
25 #include "llvm/IR/CallingConv.h"
26 #include "llvm/IR/InlineAsm.h"
27 #include <cstdint>
28 #include <utility>
29
30 namespace llvm {
31
32 namespace HexagonISD {
33
34     enum NodeType : unsigned {
35       OP_BEGIN = ISD::BUILTIN_OP_END,
36
37       CONST32 = OP_BEGIN,
38       CONST32_GP,  // For marking data present in GP.
39       ALLOCA,
40
41       AT_GOT,      // Index in GOT.
42       AT_PCREL,    // Offset relative to PC.
43
44       CALL,        // Function call.
45       CALLnr,      // Function call that does not return.
46       CALLR,
47
48       RET_FLAG,    // Return with a flag operand.
49       BARRIER,     // Memory barrier.
50       JT,          // Jump table.
51       CP,          // Constant pool.
52
53       COMBINE,
54       VSPLAT,
55       VASL,
56       VASR,
57       VLSR,
58
59       INSERT,
60       INSERTRP,
61       EXTRACTU,
62       EXTRACTURP,
63       VCOMBINE,
64       VPACKE,
65       VPACKO,
66       VEXTRACTW,
67       VINSERTW0,
68       VROR,
69       TC_RETURN,
70       EH_RETURN,
71       DCFETCH,
72       READCYCLE,
73       VZERO,
74
75       OP_END
76     };
77
78 } // end namespace HexagonISD
79
80   class HexagonSubtarget;
81
82   class HexagonTargetLowering : public TargetLowering {
83     int VarArgsFrameOffset;   // Frame offset to start of varargs area.
84     const HexagonTargetMachine &HTM;
85     const HexagonSubtarget &Subtarget;
86
87     bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
88         const;
89     void promoteLdStType(MVT VT, MVT PromotedLdStVT);
90
91   public:
92     explicit HexagonTargetLowering(const TargetMachine &TM,
93                                    const HexagonSubtarget &ST);
94
95     bool isHVXVectorType(MVT Ty) const;
96
97     /// IsEligibleForTailCallOptimization - Check whether the call is eligible
98     /// for tail call optimization. Targets which want to do tail call
99     /// optimization should implement this function.
100     bool IsEligibleForTailCallOptimization(SDValue Callee,
101         CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
102         bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
103         const SmallVectorImpl<SDValue> &OutVals,
104         const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
105
106     bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
107                             MachineFunction &MF,
108                             unsigned Intrinsic) const override;
109
110     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
111     bool isTruncateFree(EVT VT1, EVT VT2) const override;
112
113     bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
114
115     /// Return true if an FMA operation is faster than a pair of mul and add
116     /// instructions. fmuladd intrinsics will be expanded to FMAs when this
117     /// method returns true (and FMAs are legal), otherwise fmuladd is
118     /// expanded to mul + add.
119     bool isFMAFasterThanFMulAndFAdd(EVT) const override;
120
121     // Should we expand the build vector with shuffles?
122     bool shouldExpandBuildVectorWithShuffles(EVT VT,
123         unsigned DefinedValues) const override;
124
125     bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override;
126     TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(EVT VT)
127         const override;
128
129     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
130     const char *getTargetNodeName(unsigned Opcode) const override;
131
132     SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
133     SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
134     SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
135     SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
136     SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
137     SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
138     SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
139     SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const;
140
141     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
142     SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
143     SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
144     SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
145     SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
146     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
147     SDValue
148     LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
149                          const SmallVectorImpl<ISD::InputArg> &Ins,
150                          const SDLoc &dl, SelectionDAG &DAG,
151                          SmallVectorImpl<SDValue> &InVals) const override;
152     SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
153     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
154     SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
155     SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
156         SelectionDAG &DAG) const;
157     SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
158         SelectionDAG &DAG) const;
159     SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
160         SelectionDAG &DAG) const;
161     SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
162         GlobalAddressSDNode *GA, SDValue InFlag, EVT PtrVT,
163         unsigned ReturnReg, unsigned char OperandFlags) const;
164     SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
165
166     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
167         SmallVectorImpl<SDValue> &InVals) const override;
168     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
169                             CallingConv::ID CallConv, bool isVarArg,
170                             const SmallVectorImpl<ISD::InputArg> &Ins,
171                             const SDLoc &dl, SelectionDAG &DAG,
172                             SmallVectorImpl<SDValue> &InVals,
173                             const SmallVectorImpl<SDValue> &OutVals,
174                             SDValue Callee) const;
175
176     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
177     SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
178     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
179     SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
180     SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
181
182     bool CanLowerReturn(CallingConv::ID CallConv,
183                         MachineFunction &MF, bool isVarArg,
184                         const SmallVectorImpl<ISD::OutputArg> &Outs,
185                         LLVMContext &Context) const override;
186
187     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
188                         const SmallVectorImpl<ISD::OutputArg> &Outs,
189                         const SmallVectorImpl<SDValue> &OutVals,
190                         const SDLoc &dl, SelectionDAG &DAG) const override;
191
192     bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
193
194     /// If a physical register, this returns the register that receives the
195     /// exception address on entry to an EH pad.
196     unsigned
197     getExceptionPointerRegister(const Constant *PersonalityFn) const override {
198       return Hexagon::R0;
199     }
200
201     /// If a physical register, this returns the register that receives the
202     /// exception typeid on entry to a landing pad.
203     unsigned
204     getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
205       return Hexagon::R1;
206     }
207
208     SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
209     SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
210     SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
211
212     EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
213                            EVT VT) const override {
214       if (!VT.isVector())
215         return MVT::i1;
216       else
217         return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
218     }
219
220     bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
221                                     SDValue &Base, SDValue &Offset,
222                                     ISD::MemIndexedMode &AM,
223                                     SelectionDAG &DAG) const override;
224
225     ConstraintType getConstraintType(StringRef Constraint) const override;
226
227     std::pair<unsigned, const TargetRegisterClass *>
228     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
229                                  StringRef Constraint, MVT VT) const override;
230
231     unsigned
232     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
233       if (ConstraintCode == "o")
234         return InlineAsm::Constraint_o;
235       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
236     }
237
238     // Intrinsics
239     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
240     SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
241     /// isLegalAddressingMode - Return true if the addressing mode represented
242     /// by AM is legal for this target, for a load/store of the specified type.
243     /// The type may be VoidTy, in which case only return true if the addressing
244     /// mode is legal for a load/store of any legal type.
245     /// TODO: Handle pre/postinc as well.
246     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
247                                Type *Ty, unsigned AS,
248                                Instruction *I = nullptr) const override;
249     /// Return true if folding a constant offset with the given GlobalAddress
250     /// is legal.  It is frequently not legal in PIC relocation models.
251     bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
252
253     bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
254
255     /// isLegalICmpImmediate - Return true if the specified immediate is legal
256     /// icmp immediate, that is the target has icmp instructions which can
257     /// compare a register against the immediate without having to materialize
258     /// the immediate into a register.
259     bool isLegalICmpImmediate(int64_t Imm) const override;
260
261     EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
262         unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
263         MachineFunction &MF) const override;
264
265     bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
266         unsigned Align, bool *Fast) const override;
267
268     /// Returns relocation base for the given PIC jumptable.
269     SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
270                                      const override;
271
272     // Handling of atomic RMW instructions.
273     Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
274         AtomicOrdering Ord) const override;
275     Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
276         Value *Addr, AtomicOrdering Ord) const override;
277     AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
278     bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
279     bool shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
280
281     AtomicExpansionKind
282     shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
283       return AtomicExpansionKind::LLSC;
284     }
285
286   private:
287     bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy,
288                                  SelectionDAG &DAG,
289                                  MutableArrayRef<ConstantInt*> Consts) const;
290     SDValue buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
291                           SelectionDAG &DAG) const;
292     SDValue buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
293                           SelectionDAG &DAG) const;
294     SDValue extractVector(SDValue VecV, SDValue IdxV, const SDLoc &dl,
295                           MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;
296     SDValue insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
297                          const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;
298     bool isUndef(SDValue Op) const {
299       if (Op.isMachineOpcode())
300         return Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF;
301       return Op.getOpcode() == ISD::UNDEF;
302     }
303     SDValue getNode(unsigned MachineOpc, const SDLoc &dl, MVT Ty,
304                     ArrayRef<SDValue> Ops, SelectionDAG &DAG) const {
305       SDNode *N = DAG.getMachineNode(MachineOpc, dl, Ty, Ops);
306       return SDValue(N, 0);
307     }
308     SDValue getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG) const;
309
310     using VectorPair = std::pair<SDValue, SDValue>;
311     using TypePair = std::pair<MVT, MVT>;
312
313     SDValue getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops,
314                    const SDLoc &dl, SelectionDAG &DAG) const;
315
316     MVT ty(SDValue Op) const {
317       return Op.getValueType().getSimpleVT();
318     }
319     TypePair ty(const VectorPair &Ops) const {
320       return { Ops.first.getValueType().getSimpleVT(),
321                Ops.second.getValueType().getSimpleVT() };
322     }
323     MVT tyScalar(MVT Ty) const {
324       if (!Ty.isVector())
325         return Ty;
326       return MVT::getIntegerVT(Ty.getSizeInBits());
327     }
328     MVT tyVector(MVT Ty, MVT ElemTy) const {
329       if (Ty.isVector() && Ty.getVectorElementType() == ElemTy)
330         return Ty;
331       unsigned TyWidth = Ty.getSizeInBits(), ElemWidth = ElemTy.getSizeInBits();
332       assert((TyWidth % ElemWidth) == 0);
333       return MVT::getVectorVT(ElemTy, TyWidth/ElemWidth);
334     }
335
336     MVT typeJoin(const TypePair &Tys) const;
337     TypePair typeSplit(MVT Ty) const;
338     MVT typeExtElem(MVT VecTy, unsigned Factor) const;
339     MVT typeTruncElem(MVT VecTy, unsigned Factor) const;
340
341     SDValue opJoin(const VectorPair &Ops, const SDLoc &dl,
342                    SelectionDAG &DAG) const;
343     VectorPair opSplit(SDValue Vec, const SDLoc &dl, SelectionDAG &DAG) const;
344     SDValue opCastElem(SDValue Vec, MVT ElemTy, SelectionDAG &DAG) const;
345
346     SDValue convertToByteIndex(SDValue ElemIdx, MVT ElemTy,
347                                SelectionDAG &DAG) const;
348     SDValue getIndexInWord32(SDValue Idx, MVT ElemTy, SelectionDAG &DAG) const;
349     SDValue getByteShuffle(const SDLoc &dl, SDValue Op0, SDValue Op1,
350                            ArrayRef<int> Mask, SelectionDAG &DAG) const;
351
352     MVT getVecBoolVT() const;
353
354     SDValue buildHvxVectorSingle(ArrayRef<SDValue> Values, const SDLoc &dl,
355                                  MVT VecTy, SelectionDAG &DAG) const;
356     SDValue buildHvxVectorPred(ArrayRef<SDValue> Values, const SDLoc &dl,
357                                MVT VecTy, SelectionDAG &DAG) const;
358
359     SDValue LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG) const;
360     SDValue LowerHvxExtractElement(SDValue Op, SelectionDAG &DAG) const;
361     SDValue LowerHvxInsertElement(SDValue Op, SelectionDAG &DAG) const;
362     SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const;
363     SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const;
364     SDValue LowerHvxMul(SDValue Op, SelectionDAG &DAG) const;
365     SDValue LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
366     SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const;
367
368     std::pair<const TargetRegisterClass*, uint8_t>
369     findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
370         const override;
371   };
372
373 } // end namespace llvm
374
375 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H