1 //===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the interfaces that Hexagon uses to lower LLVM code into a
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
16 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_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"
32 namespace HexagonISD {
34 enum NodeType : unsigned {
35 OP_BEGIN = ISD::BUILTIN_OP_END,
38 CONST32_GP, // For marking data present in GP.
41 AT_GOT, // Index in GOT.
42 AT_PCREL, // Offset relative to PC.
44 CALL, // Function call.
45 CALLnr, // Function call that does not return.
48 RET_FLAG, // Return with a flag operand.
49 BARRIER, // Memory barrier.
78 } // end namespace HexagonISD
80 class HexagonSubtarget;
82 class HexagonTargetLowering : public TargetLowering {
83 int VarArgsFrameOffset; // Frame offset to start of varargs area.
84 const HexagonTargetMachine &HTM;
85 const HexagonSubtarget &Subtarget;
87 bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
89 void promoteLdStType(MVT VT, MVT PromotedLdStVT);
92 explicit HexagonTargetLowering(const TargetMachine &TM,
93 const HexagonSubtarget &ST);
95 bool isHVXVectorType(MVT Ty) const;
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;
106 bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
108 unsigned Intrinsic) const override;
110 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
111 bool isTruncateFree(EVT VT1, EVT VT2) const override;
113 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
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;
121 // Should we expand the build vector with shuffles?
122 bool shouldExpandBuildVectorWithShuffles(EVT VT,
123 unsigned DefinedValues) const override;
125 bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override;
126 TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(EVT VT)
129 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
130 const char *getTargetNodeName(unsigned Opcode) const override;
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;
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;
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;
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;
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;
182 bool CanLowerReturn(CallingConv::ID CallConv,
183 MachineFunction &MF, bool isVarArg,
184 const SmallVectorImpl<ISD::OutputArg> &Outs,
185 LLVMContext &Context) const override;
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;
192 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
194 /// If a physical register, this returns the register that receives the
195 /// exception address on entry to an EH pad.
197 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
201 /// If a physical register, this returns the register that receives the
202 /// exception typeid on entry to a landing pad.
204 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
208 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
209 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
210 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
212 EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
213 EVT VT) const override {
217 return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
220 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
221 SDValue &Base, SDValue &Offset,
222 ISD::MemIndexedMode &AM,
223 SelectionDAG &DAG) const override;
225 ConstraintType getConstraintType(StringRef Constraint) const override;
227 std::pair<unsigned, const TargetRegisterClass *>
228 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
229 StringRef Constraint, MVT VT) const override;
232 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
233 if (ConstraintCode == "o")
234 return InlineAsm::Constraint_o;
235 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
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;
253 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
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;
261 EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
262 unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
263 MachineFunction &MF) const override;
265 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
266 unsigned Align, bool *Fast) const override;
268 /// Returns relocation base for the given PIC jumptable.
269 SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
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;
282 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
283 return AtomicExpansionKind::LLSC;
287 bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy,
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;
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);
308 SDValue getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG) const;
310 using VectorPair = std::pair<SDValue, SDValue>;
311 using TypePair = std::pair<MVT, MVT>;
313 SDValue getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops,
314 const SDLoc &dl, SelectionDAG &DAG) const;
316 MVT ty(SDValue Op) const {
317 return Op.getValueType().getSimpleVT();
319 TypePair ty(const VectorPair &Ops) const {
320 return { Ops.first.getValueType().getSimpleVT(),
321 Ops.second.getValueType().getSimpleVT() };
323 MVT tyScalar(MVT Ty) const {
326 return MVT::getIntegerVT(Ty.getSizeInBits());
328 MVT tyVector(MVT Ty, MVT ElemTy) const {
329 if (Ty.isVector() && Ty.getVectorElementType() == ElemTy)
331 unsigned TyWidth = Ty.getSizeInBits(), ElemWidth = ElemTy.getSizeInBits();
332 assert((TyWidth % ElemWidth) == 0);
333 return MVT::getVectorVT(ElemTy, TyWidth/ElemWidth);
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;
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;
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;
352 MVT getVecBoolVT() const;
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;
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;
368 std::pair<const TargetRegisterClass*, uint8_t>
369 findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
373 } // end namespace llvm
375 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H