/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Hexagon/HexagonISelLowering.h
Line | Count | Source (jump to first uncovered line) |
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/ValueTypes.h" |
24 | | #include "llvm/IR/CallingConv.h" |
25 | | #include "llvm/IR/InlineAsm.h" |
26 | | #include "llvm/Target/TargetLowering.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 | | PACKHL, |
55 | | VSPLAT, |
56 | | VASL, |
57 | | VASR, |
58 | | VLSR, |
59 | | |
60 | | INSERT, |
61 | | INSERTRP, |
62 | | EXTRACTU, |
63 | | EXTRACTURP, |
64 | | VCOMBINE, |
65 | | VPACKE, |
66 | | VPACKO, |
67 | | TC_RETURN, |
68 | | EH_RETURN, |
69 | | DCFETCH, |
70 | | READCYCLE, |
71 | | |
72 | | OP_END |
73 | | }; |
74 | | |
75 | | } // end namespace HexagonISD |
76 | | |
77 | | class HexagonSubtarget; |
78 | | |
79 | | class HexagonTargetLowering : public TargetLowering { |
80 | | int VarArgsFrameOffset; // Frame offset to start of varargs area. |
81 | | const HexagonTargetMachine &HTM; |
82 | | const HexagonSubtarget &Subtarget; |
83 | | |
84 | | bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize) |
85 | | const; |
86 | | void promoteLdStType(MVT VT, MVT PromotedLdStVT); |
87 | | |
88 | | public: |
89 | | explicit HexagonTargetLowering(const TargetMachine &TM, |
90 | | const HexagonSubtarget &ST); |
91 | | |
92 | | /// IsEligibleForTailCallOptimization - Check whether the call is eligible |
93 | | /// for tail call optimization. Targets which want to do tail call |
94 | | /// optimization should implement this function. |
95 | | bool IsEligibleForTailCallOptimization(SDValue Callee, |
96 | | CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet, |
97 | | bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs, |
98 | | const SmallVectorImpl<SDValue> &OutVals, |
99 | | const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const; |
100 | | |
101 | | bool isTruncateFree(Type *Ty1, Type *Ty2) const override; |
102 | | bool isTruncateFree(EVT VT1, EVT VT2) const override; |
103 | | |
104 | | bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override; |
105 | | |
106 | | /// Return true if an FMA operation is faster than a pair of mul and add |
107 | | /// instructions. fmuladd intrinsics will be expanded to FMAs when this |
108 | | /// method returns true (and FMAs are legal), otherwise fmuladd is |
109 | | /// expanded to mul + add. |
110 | | bool isFMAFasterThanFMulAndFAdd(EVT) const override; |
111 | | |
112 | | // Should we expand the build vector with shuffles? |
113 | | bool shouldExpandBuildVectorWithShuffles(EVT VT, |
114 | | unsigned DefinedValues) const override; |
115 | | |
116 | | bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override; |
117 | | |
118 | | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
119 | | const char *getTargetNodeName(unsigned Opcode) const override; |
120 | | SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const; |
121 | | SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const; |
122 | | SDValue LowerEXTRACT_SUBVECTOR_HVX(SDValue Op, SelectionDAG &DAG) const; |
123 | | SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const; |
124 | | SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; |
125 | | SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const; |
126 | | SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; |
127 | | SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; |
128 | | SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; |
129 | | SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const; |
130 | | SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const; |
131 | | SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const; |
132 | | SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; |
133 | | SDValue |
134 | | LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
135 | | const SmallVectorImpl<ISD::InputArg> &Ins, |
136 | | const SDLoc &dl, SelectionDAG &DAG, |
137 | | SmallVectorImpl<SDValue> &InVals) const override; |
138 | | SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const; |
139 | | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
140 | | SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; |
141 | | SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, |
142 | | SelectionDAG &DAG) const; |
143 | | SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA, |
144 | | SelectionDAG &DAG) const; |
145 | | SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA, |
146 | | SelectionDAG &DAG) const; |
147 | | SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain, |
148 | | GlobalAddressSDNode *GA, SDValue InFlag, EVT PtrVT, |
149 | | unsigned ReturnReg, unsigned char OperandFlags) const; |
150 | | SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const; |
151 | | |
152 | | SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, |
153 | | SmallVectorImpl<SDValue> &InVals) const override; |
154 | | SDValue LowerCallResult(SDValue Chain, SDValue InFlag, |
155 | | CallingConv::ID CallConv, bool isVarArg, |
156 | | const SmallVectorImpl<ISD::InputArg> &Ins, |
157 | | const SDLoc &dl, SelectionDAG &DAG, |
158 | | SmallVectorImpl<SDValue> &InVals, |
159 | | const SmallVectorImpl<SDValue> &OutVals, |
160 | | SDValue Callee) const; |
161 | | |
162 | | SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; |
163 | | SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const; |
164 | | SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; |
165 | | SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const; |
166 | | SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; |
167 | | |
168 | | bool CanLowerReturn(CallingConv::ID CallConv, |
169 | | MachineFunction &MF, bool isVarArg, |
170 | | const SmallVectorImpl<ISD::OutputArg> &Outs, |
171 | | LLVMContext &Context) const override; |
172 | | |
173 | | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
174 | | const SmallVectorImpl<ISD::OutputArg> &Outs, |
175 | | const SmallVectorImpl<SDValue> &OutVals, |
176 | | const SDLoc &dl, SelectionDAG &DAG) const override; |
177 | | |
178 | | bool mayBeEmittedAsTailCall(const CallInst *CI) const override; |
179 | | |
180 | | /// If a physical register, this returns the register that receives the |
181 | | /// exception address on entry to an EH pad. |
182 | | unsigned |
183 | 5.87k | getExceptionPointerRegister(const Constant *PersonalityFn) const override { |
184 | 5.87k | return Hexagon::R0; |
185 | 5.87k | } |
186 | | |
187 | | /// If a physical register, this returns the register that receives the |
188 | | /// exception typeid on entry to a landing pad. |
189 | | unsigned |
190 | 5.87k | getExceptionSelectorRegister(const Constant *PersonalityFn) const override { |
191 | 5.87k | return Hexagon::R1; |
192 | 5.87k | } |
193 | | |
194 | | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
195 | | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
196 | | SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; |
197 | | |
198 | | EVT getSetCCResultType(const DataLayout &, LLVMContext &C, |
199 | 366 | EVT VT) const override { |
200 | 366 | if (!VT.isVector()) |
201 | 366 | return MVT::i1; |
202 | 366 | else |
203 | 0 | return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements()); |
204 | 366 | } |
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 |
218 | 5 | getInlineAsmMemConstraint(StringRef ConstraintCode) const override { |
219 | 5 | if (ConstraintCode == "o") |
220 | 0 | return InlineAsm::Constraint_o; |
221 | 5 | return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); |
222 | 5 | } |
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, |
234 | | Instruction *I = nullptr) const override; |
235 | | /// Return true if folding a constant offset with the given GlobalAddress |
236 | | /// is legal. It is frequently not legal in PIC relocation models. |
237 | | bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; |
238 | | |
239 | | bool isFPImmLegal(const APFloat &Imm, EVT VT) const override; |
240 | | |
241 | | /// isLegalICmpImmediate - Return true if the specified immediate is legal |
242 | | /// icmp immediate, that is the target has icmp instructions which can |
243 | | /// compare a register against the immediate without having to materialize |
244 | | /// the immediate into a register. |
245 | | bool isLegalICmpImmediate(int64_t Imm) const override; |
246 | | |
247 | | EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, |
248 | | unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc, |
249 | | MachineFunction &MF) const override; |
250 | | |
251 | | bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, |
252 | | unsigned Align, bool *Fast) const override; |
253 | | |
254 | | /// Returns relocation base for the given PIC jumptable. |
255 | | SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) |
256 | | const override; |
257 | | |
258 | | // Handling of atomic RMW instructions. |
259 | | Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr, |
260 | | AtomicOrdering Ord) const override; |
261 | | Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val, |
262 | | Value *Addr, AtomicOrdering Ord) const override; |
263 | | AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override; |
264 | | bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override; |
265 | | bool shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override; |
266 | | |
267 | | AtomicExpansionKind |
268 | 26 | shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override { |
269 | 26 | return AtomicExpansionKind::LLSC; |
270 | 26 | } |
271 | | |
272 | | protected: |
273 | | std::pair<const TargetRegisterClass*, uint8_t> |
274 | | findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) |
275 | | const override; |
276 | | }; |
277 | | |
278 | | } // end namespace llvm |
279 | | |
280 | | #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H |