• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/CodeGen/CallingConvLower.h"
20 #include "llvm/IR/CallingConv.h"
21 #include "llvm/Target/TargetLowering.h"
22 
23 namespace llvm {
24 
25 // Return true when the given node fits in a positive half word.
26 bool isPositiveHalfWord(SDNode *N);
27 
28   namespace HexagonISD {
29     enum NodeType : unsigned {
30       OP_BEGIN = ISD::BUILTIN_OP_END,
31 
32       CONST32 = OP_BEGIN,
33       CONST32_GP,  // For marking data present in GP.
34       FCONST32,
35       ALLOCA,
36       ARGEXTEND,
37 
38       AT_GOT,      // Index in GOT.
39       AT_PCREL,    // Offset relative to PC.
40 
41       CALLv3,      // A V3+ call instruction.
42       CALLv3nr,    // A V3+ call instruction that doesn't return.
43       CALLR,
44 
45       RET_FLAG,    // Return with a flag operand.
46       BARRIER,     // Memory barrier.
47       JT,          // Jump table.
48       CP,          // Constant pool.
49 
50       POPCOUNT,
51       COMBINE,
52       PACKHL,
53       VSPLATB,
54       VSPLATH,
55       SHUFFEB,
56       SHUFFEH,
57       SHUFFOB,
58       SHUFFOH,
59       VSXTBH,
60       VSXTBW,
61       VSRAW,
62       VSRAH,
63       VSRLW,
64       VSRLH,
65       VSHLW,
66       VSHLH,
67       VCMPBEQ,
68       VCMPBGT,
69       VCMPBGTU,
70       VCMPHEQ,
71       VCMPHGT,
72       VCMPHGTU,
73       VCMPWEQ,
74       VCMPWGT,
75       VCMPWGTU,
76 
77       INSERT,
78       INSERTRP,
79       EXTRACTU,
80       EXTRACTURP,
81       VCOMBINE,
82       TC_RETURN,
83       EH_RETURN,
84       DCFETCH,
85 
86       OP_END
87     };
88   }
89 
90   class HexagonSubtarget;
91 
92   class HexagonTargetLowering : public TargetLowering {
93     int VarArgsFrameOffset;   // Frame offset to start of varargs area.
94 
95     bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
96         const;
97     void promoteLdStType(MVT VT, MVT PromotedLdStVT);
98     const HexagonTargetMachine &HTM;
99     const HexagonSubtarget &Subtarget;
100 
101   public:
102     explicit HexagonTargetLowering(const TargetMachine &TM,
103                                    const HexagonSubtarget &ST);
104 
105     /// IsEligibleForTailCallOptimization - Check whether the call is eligible
106     /// for tail call optimization. Targets which want to do tail call
107     /// optimization should implement this function.
108     bool IsEligibleForTailCallOptimization(SDValue Callee,
109         CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
110         bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
111         const SmallVectorImpl<SDValue> &OutVals,
112         const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
113 
114     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
115     bool isTruncateFree(EVT VT1, EVT VT2) const override;
116 
117     bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
118 
119     // Should we expand the build vector with shuffles?
120     bool shouldExpandBuildVectorWithShuffles(EVT VT,
121         unsigned DefinedValues) const override;
122 
123     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
124     const char *getTargetNodeName(unsigned Opcode) const override;
125     SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
126     SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
127     SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
128     SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
129     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
130     SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
131     SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
132     SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
133     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
134     SDValue
135     LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
136                          const SmallVectorImpl<ISD::InputArg> &Ins,
137                          const SDLoc &dl, SelectionDAG &DAG,
138                          SmallVectorImpl<SDValue> &InVals) const override;
139     SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
140     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
141     SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
142     SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
143         SelectionDAG &DAG) const;
144     SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
145         SelectionDAG &DAG) const;
146     SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
147         SelectionDAG &DAG) const;
148     SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
149         GlobalAddressSDNode *GA, SDValue *InFlag, EVT PtrVT,
150         unsigned ReturnReg, unsigned char OperandFlags) const;
151     SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
152 
153     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
154         SmallVectorImpl<SDValue> &InVals) const override;
155     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
156                             CallingConv::ID CallConv, bool isVarArg,
157                             const SmallVectorImpl<ISD::InputArg> &Ins,
158                             const SDLoc &dl, SelectionDAG &DAG,
159                             SmallVectorImpl<SDValue> &InVals,
160                             const SmallVectorImpl<SDValue> &OutVals,
161                             SDValue Callee) const;
162 
163     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
164     SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
165     SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
166     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
167     SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
168     SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
169     SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
170 
171     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
172                         const SmallVectorImpl<ISD::OutputArg> &Outs,
173                         const SmallVectorImpl<SDValue> &OutVals,
174                         const SDLoc &dl, SelectionDAG &DAG) const override;
175 
176     bool mayBeEmittedAsTailCall(CallInst *CI) const override;
177     MachineBasicBlock *
178     EmitInstrWithCustomInserter(MachineInstr &MI,
179                                 MachineBasicBlock *BB) const override;
180 
181     /// If a physical register, this returns the register that receives the
182     /// exception address on entry to an EH pad.
183     unsigned
getExceptionPointerRegister(const Constant * PersonalityFn)184     getExceptionPointerRegister(const Constant *PersonalityFn) const override {
185       return Hexagon::R0;
186     }
187 
188     /// If a physical register, this returns the register that receives the
189     /// exception typeid on entry to a landing pad.
190     unsigned
getExceptionSelectorRegister(const Constant * PersonalityFn)191     getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
192       return Hexagon::R1;
193     }
194 
195     SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
196     SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
197     SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
getSetCCResultType(const DataLayout &,LLVMContext & C,EVT VT)198     EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
199                            EVT VT) const override {
200       if (!VT.isVector())
201         return MVT::i1;
202       else
203         return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
204     }
205 
206     bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
207                                     SDValue &Base, SDValue &Offset,
208                                     ISD::MemIndexedMode &AM,
209                                     SelectionDAG &DAG) const override;
210 
211     ConstraintType getConstraintType(StringRef Constraint) const override;
212 
213     std::pair<unsigned, const TargetRegisterClass *>
214     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
215                                  StringRef Constraint, MVT VT) const override;
216 
217     unsigned
getInlineAsmMemConstraint(StringRef ConstraintCode)218     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
219       if (ConstraintCode == "o")
220         return InlineAsm::Constraint_o;
221       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
222     }
223 
224     // Intrinsics
225     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
226     SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
227     /// isLegalAddressingMode - Return true if the addressing mode represented
228     /// by AM is legal for this target, for a load/store of the specified type.
229     /// The type may be VoidTy, in which case only return true if the addressing
230     /// mode is legal for a load/store of any legal type.
231     /// TODO: Handle pre/postinc as well.
232     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
233                                Type *Ty, unsigned AS) const override;
234     /// Return true if folding a constant offset with the given GlobalAddress
235     /// is legal.  It is frequently not legal in PIC relocation models.
236     bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
237 
238     bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
239 
240     /// isLegalICmpImmediate - Return true if the specified immediate is legal
241     /// icmp immediate, that is the target has icmp instructions which can
242     /// compare a register against the immediate without having to materialize
243     /// the immediate into a register.
244     bool isLegalICmpImmediate(int64_t Imm) const override;
245 
246     bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
247         unsigned Align, bool *Fast) const override;
248 
249     /// Returns relocation base for the given PIC jumptable.
250     SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
251                                      const override;
252 
253     // Handling of atomic RMW instructions.
254     Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
255         AtomicOrdering Ord) const override;
256     Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
257         Value *Addr, AtomicOrdering Ord) const override;
258     AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
259     bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
260     bool shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
261 
262     AtomicExpansionKind
shouldExpandAtomicRMWInIR(AtomicRMWInst * AI)263     shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
264       return AtomicExpansionKind::LLSC;
265     }
266 
267   protected:
268     std::pair<const TargetRegisterClass*, uint8_t>
269     findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
270         const override;
271   };
272 } // end namespace llvm
273 
274 #endif    // Hexagon_ISELLOWERING_H
275