LLVM 22.0.0git
HexagonISelLowering.h
Go to the documentation of this file.
1//===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that Hexagon uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
15#define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
16
17#include "Hexagon.h"
19#include "llvm/ADT/StringRef.h"
25#include "llvm/IR/CallingConv.h"
26#include "llvm/IR/InlineAsm.h"
27#include <cstdint>
28#include <utility>
29
30namespace llvm {
31
32namespace HexagonISD {
33
34// clang-format off
35enum NodeType : unsigned {
37
39 CONST32_GP, // For marking data present in GP.
40 ADDC, // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
41 SUBC, // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
43
44 AT_GOT, // Index in GOT.
45 AT_PCREL, // Offset relative to PC.
46
47 CALL, // Function call.
48 CALLnr, // Function call that does not return.
50
51 RET_GLUE, // Return with a glue operand.
52 BARRIER, // Memory barrier.
53 JT, // Jump table.
54 CP, // Constant pool.
55
57 VASL, // Vector shifts by a scalar value
60 MFSHL, // Funnel shifts with the shift amount guaranteed to be
61 MFSHR, // within the range of the bit width of the element.
62
63 SSAT, // Signed saturate.
64 USAT, // Unsigned saturate.
65 SMUL_LOHI, // Same as ISD::SMUL_LOHI, but opaque to the combiner.
66 UMUL_LOHI, // Same as ISD::UMUL_LOHI, but opaque to the combiner.
67 // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
68 // combiner will keep rewriting it back to MULH[SU].
69 USMUL_LOHI, // Like SMUL_LOHI, but unsigned*signed.
70
85 D2P, // Convert 8-byte value to 8-bit predicate register. [*]
86 P2D, // Convert 8-bit predicate register to 8-byte value. [*]
87 V2Q, // Convert HVX vector to a vector predicate reg. [*]
88 Q2V, // Convert vector predicate to an HVX vector. [*]
89 // [*] The equivalence is defined as "Q <=> (V != 0)",
90 // where the != operation compares bytes.
91 // Note: V != 0 is implemented as V >u 0.
95
96 TL_EXTEND, // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
97 TL_TRUNCATE, // from auto-folding operations, e.g.
98 // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
99 // To simplify the type legalization, we want to keep these
100 // single steps separate during type legalization.
101 // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
102 // * Inp is the original input to extend/truncate,
103 // * _ is a dummy operand with an illegal type (can be undef),
104 // * Opc is the original opcode.
105 // The legalization process (in Hexagon lowering code) will
106 // first deal with the "real" types (i.e. Inp and the result),
107 // and once all of them are processed, the wrapper node will
108 // be replaced with the original ISD node. The dummy illegal
109 // operand is there to make sure that the legalization hooks
110 // are called again after everything else is legal, giving
111 // us the opportunity to undo the wrapping.
112
113 TYPECAST, // No-op that's used to convert between different legal
114 // types in a register.
115 VALIGN, // Align two vectors (in Op0, Op1) to one that would have
116 // been loaded from address in Op2.
117 VALIGNADDR, // Align vector address: Op0 & -Op1, except when it is
118 // an address in a vector load, then it's a no-op.
119 ISEL, // Marker for nodes that were created during ISel, and
120 // which need explicit selection (would have been left
121 // unselected otherwise).
123};
124
125} // end namespace HexagonISD
126// clang-format on
127
128class HexagonSubtarget;
129
131 int VarArgsFrameOffset; // Frame offset to start of varargs area.
132 const HexagonTargetMachine &HTM;
133 const HexagonSubtarget &Subtarget;
134
135public:
136 explicit HexagonTargetLowering(const TargetMachine &TM,
137 const HexagonSubtarget &ST);
138
139 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
140 /// for tail call optimization. Targets which want to do tail call
141 /// optimization should implement this function.
143 CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
144 bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
145 const SmallVectorImpl<SDValue> &OutVals,
146 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
147
149 MachineFunction &MF,
150 unsigned Intrinsic) const override;
151
152 bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
153 bool isTruncateFree(EVT VT1, EVT VT2) const override;
154
155 bool isCheapToSpeculateCttz(Type *) const override { return true; }
156 bool isCheapToSpeculateCtlz(Type *) const override { return true; }
157 bool isCtlzFast() const override { return true; }
158
159 bool hasBitTest(SDValue X, SDValue Y) const override;
160
161 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
162
163 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
164
165 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
166
167 /// Return true if an FMA operation is faster than a pair of mul and add
168 /// instructions. fmuladd intrinsics will be expanded to FMAs when this
169 /// method returns true (and FMAs are legal), otherwise fmuladd is
170 /// expanded to mul + add.
172 EVT) const override;
173
174 // Should we expand the build vector with shuffles?
176 unsigned DefinedValues) const override;
177 bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
178 unsigned Index) const override;
179
180 bool isTargetCanonicalConstantNode(SDValue Op) const override;
181
182 bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override;
183 LegalizeTypeAction getPreferredVectorAction(MVT VT) const override;
185
186 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
188 SelectionDAG &DAG) const override;
190 SelectionDAG &DAG) const override;
191
192 const char *getTargetNodeName(unsigned Opcode) const override;
193 std::pair<MVT, unsigned>
195 EVT VT) const;
196
215
224 SDValue
225 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
227 const SDLoc &dl, SelectionDAG &DAG,
228 SmallVectorImpl<SDValue> &InVals) const override;
233 SelectionDAG &DAG) const;
235 SelectionDAG &DAG) const;
237 SelectionDAG &DAG) const;
239 GlobalAddressSDNode *GA, SDValue InGlue, EVT PtrVT,
240 unsigned ReturnReg, unsigned char OperandGlues) const;
242
244 SmallVectorImpl<SDValue> &InVals) const override;
246 CallingConv::ID CallConv, bool isVarArg,
248 const SDLoc &dl, SelectionDAG &DAG,
250 const SmallVectorImpl<SDValue> &OutVals,
251 SDValue Callee) const;
252
258
259 bool CanLowerReturn(CallingConv::ID CallConv,
260 MachineFunction &MF, bool isVarArg,
262 LLVMContext &Context, const Type *RetTy) const override;
263
264 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
266 const SmallVectorImpl<SDValue> &OutVals,
267 const SDLoc &dl, SelectionDAG &DAG) const override;
268
269 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
270
271 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
272
273 Register getRegisterByName(const char* RegName, LLT VT,
274 const MachineFunction &MF) const override;
275
277 CallingConv::ID CC, EVT VT,
278 EVT &IntermediateVT,
279 unsigned &NumIntermediates,
280 MVT &RegisterVT) const override;
281
283 EVT VT) const override;
284 /// If a physical register, this returns the register that receives the
285 /// exception address on entry to an EH pad.
287 getExceptionPointerRegister(const Constant *PersonalityFn) const override {
288 return Hexagon::R0;
289 }
290
291 /// If a physical register, this returns the register that receives the
292 /// exception typeid on entry to a landing pad.
294 getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
295 return Hexagon::R1;
296 }
297
302
304 EVT VT) const override {
305 if (!VT.isVector())
306 return MVT::i1;
307 else
308 return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
309 }
310
314 SelectionDAG &DAG) const override;
315
316 ConstraintType getConstraintType(StringRef Constraint) const override;
317
318 std::pair<unsigned, const TargetRegisterClass *>
320 StringRef Constraint, MVT VT) const override;
321
322 // Intrinsics
325 /// isLegalAddressingMode - Return true if the addressing mode represented
326 /// by AM is legal for this target, for a load/store of the specified type.
327 /// The type may be VoidTy, in which case only return true if the addressing
328 /// mode is legal for a load/store of any legal type.
329 /// TODO: Handle pre/postinc as well.
330 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
331 Type *Ty, unsigned AS,
332 Instruction *I = nullptr) const override;
333 /// Return true if folding a constant offset with the given GlobalAddress
334 /// is legal. It is frequently not legal in PIC relocation models.
335 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
336
337 bool isFPImmLegal(const APFloat &Imm, EVT VT,
338 bool ForCodeSize) const override;
339
340 /// isLegalICmpImmediate - Return true if the specified immediate is legal
341 /// icmp immediate, that is the target has icmp instructions which can
342 /// compare a register against the immediate without having to materialize
343 /// the immediate into a register.
344 bool isLegalICmpImmediate(int64_t Imm) const override;
345
346 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
347 const AttributeList &FuncAttributes) const override;
348
349 bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT,
350 unsigned AddrSpace, Align Alignment,
352 unsigned *Fast) const override;
353
354 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
355 Align Alignment,
357 unsigned *Fast) const override;
358
359 /// Returns relocation base for the given PIC jumptable.
361 const override;
362
363 /// Returns true if it is beneficial to convert a load of a constant
364 /// to just the constant itself.
366 Type *Ty) const override;
367
368 bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,
369 std::optional<unsigned> ByteOffset) const override;
370
372 SDNode *Node) const override;
373
374 // Handling of atomic RMW instructions.
375 Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,
376 AtomicOrdering Ord) const override;
377 Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,
378 AtomicOrdering Ord) const override;
383
388 bool softPromoteHalfType() const override { return true; }
389
390private:
391 void initializeHVXLowering();
392 unsigned getPreferredHvxVectorAction(MVT VecTy) const;
393 unsigned getCustomHvxOperationAction(SDNode &Op) const;
394
395 bool validateConstPtrAlignment(SDValue Ptr, Align NeedAlign, const SDLoc &dl,
396 SelectionDAG &DAG) const;
397 SDValue replaceMemWithUndef(SDValue Op, SelectionDAG &DAG) const;
398
399 std::pair<SDValue,int> getBaseAndOffset(SDValue Addr) const;
400
401 bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy,
402 SelectionDAG &DAG,
403 MutableArrayRef<ConstantInt*> Consts) const;
404 SDValue buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
405 SelectionDAG &DAG) const;
406 SDValue buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
407 SelectionDAG &DAG) const;
408 SDValue extractVector(SDValue VecV, SDValue IdxV, const SDLoc &dl,
409 MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;
410 SDValue extractVectorPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
411 MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;
412 SDValue insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
413 const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;
414 SDValue insertVectorPred(SDValue VecV, SDValue ValV, SDValue IdxV,
415 const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;
416 SDValue expandPredicate(SDValue Vec32, const SDLoc &dl,
417 SelectionDAG &DAG) const;
418 SDValue contractPredicate(SDValue Vec64, const SDLoc &dl,
419 SelectionDAG &DAG) const;
421 SDValue getVectorShiftByInt(SDValue Op, SelectionDAG &DAG) const;
422 SDValue appendUndef(SDValue Val, MVT ResTy, SelectionDAG &DAG) const;
423 SDValue getCombine(SDValue Hi, SDValue Lo, const SDLoc &dl, MVT ResTy,
424 SelectionDAG &DAG) const;
425
426 bool isUndef(SDValue Op) const {
427 if (Op.isMachineOpcode())
428 return Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF;
429 return Op.getOpcode() == ISD::UNDEF;
430 }
431 SDValue getInstr(unsigned MachineOpc, const SDLoc &dl, MVT Ty,
432 ArrayRef<SDValue> Ops, SelectionDAG &DAG) const {
433 SDNode *N = DAG.getMachineNode(MachineOpc, dl, Ty, Ops);
434 return SDValue(N, 0);
435 }
436 SDValue getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG) const;
437
438 using VectorPair = std::pair<SDValue, SDValue>;
439 using TypePair = std::pair<MVT, MVT>;
440
441 SDValue getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops,
442 const SDLoc &dl, SelectionDAG &DAG) const;
443
444 MVT ty(SDValue Op) const {
445 return Op.getValueType().getSimpleVT();
446 }
447 TypePair ty(const VectorPair &Ops) const {
448 return { Ops.first.getValueType().getSimpleVT(),
449 Ops.second.getValueType().getSimpleVT() };
450 }
451 MVT tyScalar(MVT Ty) const {
452 if (!Ty.isVector())
453 return Ty;
454 return MVT::getIntegerVT(Ty.getSizeInBits());
455 }
456 MVT tyVector(MVT Ty, MVT ElemTy) const {
457 if (Ty.isVector() && Ty.getVectorElementType() == ElemTy)
458 return Ty;
459 unsigned TyWidth = Ty.getSizeInBits();
460 unsigned ElemWidth = ElemTy.getSizeInBits();
461 assert((TyWidth % ElemWidth) == 0);
462 return MVT::getVectorVT(ElemTy, TyWidth/ElemWidth);
463 }
464
465 MVT typeJoin(const TypePair &Tys) const;
466 TypePair typeSplit(MVT Ty) const;
467 MVT typeExtElem(MVT VecTy, unsigned Factor) const;
468 MVT typeTruncElem(MVT VecTy, unsigned Factor) const;
469 TypePair typeExtendToWider(MVT Ty0, MVT Ty1) const;
470 TypePair typeWidenToWider(MVT Ty0, MVT Ty1) const;
471 MVT typeLegalize(MVT Ty, SelectionDAG &DAG) const;
472 MVT typeWidenToHvx(MVT Ty) const;
473
474 SDValue opJoin(const VectorPair &Ops, const SDLoc &dl,
475 SelectionDAG &DAG) const;
476 VectorPair opSplit(SDValue Vec, const SDLoc &dl, SelectionDAG &DAG) const;
477 SDValue opCastElem(SDValue Vec, MVT ElemTy, SelectionDAG &DAG) const;
478
479 SDValue LoHalf(SDValue V, SelectionDAG &DAG) const {
480 MVT Ty = ty(V);
481 const SDLoc &dl(V);
482 if (!Ty.isVector()) {
483 assert(Ty.getSizeInBits() == 64);
484 return DAG.getTargetExtractSubreg(Hexagon::isub_lo, dl, MVT::i32, V);
485 }
486 MVT HalfTy = typeSplit(Ty).first;
487 SDValue Idx = getZero(dl, MVT::i32, DAG);
488 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfTy, V, Idx);
489 }
490 SDValue HiHalf(SDValue V, SelectionDAG &DAG) const {
491 MVT Ty = ty(V);
492 const SDLoc &dl(V);
493 if (!Ty.isVector()) {
494 assert(Ty.getSizeInBits() == 64);
495 return DAG.getTargetExtractSubreg(Hexagon::isub_hi, dl, MVT::i32, V);
496 }
497 MVT HalfTy = typeSplit(Ty).first;
498 SDValue Idx = DAG.getConstant(HalfTy.getVectorNumElements(), dl, MVT::i32);
499 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfTy, V, Idx);
500 }
501
502 bool allowsHvxMemoryAccess(MVT VecTy, MachineMemOperand::Flags Flags,
503 unsigned *Fast) const;
504 bool allowsHvxMisalignedMemoryAccesses(MVT VecTy,
506 unsigned *Fast) const;
507 void AdjustHvxInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const;
508
509 bool isHvxSingleTy(MVT Ty) const;
510 bool isHvxPairTy(MVT Ty) const;
511 bool isHvxBoolTy(MVT Ty) const;
512 SDValue convertToByteIndex(SDValue ElemIdx, MVT ElemTy,
513 SelectionDAG &DAG) const;
514 SDValue getIndexInWord32(SDValue Idx, MVT ElemTy, SelectionDAG &DAG) const;
515 SDValue getByteShuffle(const SDLoc &dl, SDValue Op0, SDValue Op1,
516 ArrayRef<int> Mask, SelectionDAG &DAG) const;
517
518 SDValue buildHvxVectorReg(ArrayRef<SDValue> Values, const SDLoc &dl,
519 MVT VecTy, SelectionDAG &DAG) const;
520 SDValue buildHvxVectorPred(ArrayRef<SDValue> Values, const SDLoc &dl,
521 MVT VecTy, SelectionDAG &DAG) const;
522 SDValue createHvxPrefixPred(SDValue PredV, const SDLoc &dl,
523 unsigned BitBytes, bool ZeroFill,
524 SelectionDAG &DAG) const;
525 SDValue extractHvxElementReg(SDValue VecV, SDValue IdxV, const SDLoc &dl,
526 MVT ResTy, SelectionDAG &DAG) const;
527 SDValue extractHvxElementPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
528 MVT ResTy, SelectionDAG &DAG) const;
529 SDValue insertHvxElementReg(SDValue VecV, SDValue IdxV, SDValue ValV,
530 const SDLoc &dl, SelectionDAG &DAG) const;
531 SDValue insertHvxElementPred(SDValue VecV, SDValue IdxV, SDValue ValV,
532 const SDLoc &dl, SelectionDAG &DAG) const;
533 SDValue extractHvxSubvectorReg(SDValue OrigOp, SDValue VecV, SDValue IdxV,
534 const SDLoc &dl, MVT ResTy, SelectionDAG &DAG)
535 const;
536 SDValue extractHvxSubvectorPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
537 MVT ResTy, SelectionDAG &DAG) const;
538 SDValue insertHvxSubvectorReg(SDValue VecV, SDValue SubV, SDValue IdxV,
539 const SDLoc &dl, SelectionDAG &DAG) const;
540 SDValue insertHvxSubvectorPred(SDValue VecV, SDValue SubV, SDValue IdxV,
541 const SDLoc &dl, SelectionDAG &DAG) const;
542 SDValue extendHvxVectorPred(SDValue VecV, const SDLoc &dl, MVT ResTy,
543 bool ZeroExt, SelectionDAG &DAG) const;
544 SDValue compressHvxPred(SDValue VecQ, const SDLoc &dl, MVT ResTy,
545 SelectionDAG &DAG) const;
546 SDValue resizeToWidth(SDValue VecV, MVT ResTy, bool Signed, const SDLoc &dl,
547 SelectionDAG &DAG) const;
548 SDValue extractSubvector(SDValue Vec, MVT SubTy, unsigned SubIdx,
549 SelectionDAG &DAG) const;
550 VectorPair emitHvxAddWithOverflow(SDValue A, SDValue B, const SDLoc &dl,
551 bool Signed, SelectionDAG &DAG) const;
552 VectorPair emitHvxShiftRightRnd(SDValue Val, unsigned Amt, bool Signed,
553 SelectionDAG &DAG) const;
554 SDValue emitHvxMulHsV60(SDValue A, SDValue B, const SDLoc &dl,
555 SelectionDAG &DAG) const;
556 SDValue emitHvxMulLoHiV60(SDValue A, bool SignedA, SDValue B, bool SignedB,
557 const SDLoc &dl, SelectionDAG &DAG) const;
558 SDValue emitHvxMulLoHiV62(SDValue A, bool SignedA, SDValue B, bool SignedB,
559 const SDLoc &dl, SelectionDAG &DAG) const;
560
561 SDValue LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG) const;
562 SDValue LowerHvxSplatVector(SDValue Op, SelectionDAG &DAG) const;
563 SDValue LowerHvxConcatVectors(SDValue Op, SelectionDAG &DAG) const;
564 SDValue LowerHvxExtractElement(SDValue Op, SelectionDAG &DAG) const;
565 SDValue LowerHvxInsertElement(SDValue Op, SelectionDAG &DAG) const;
566 SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const;
567 SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const;
568 SDValue LowerHvxBitcast(SDValue Op, SelectionDAG &DAG) const;
569 SDValue LowerHvxAnyExt(SDValue Op, SelectionDAG &DAG) const;
570 SDValue LowerHvxSignExt(SDValue Op, SelectionDAG &DAG) const;
571 SDValue LowerHvxZeroExt(SDValue Op, SelectionDAG &DAG) const;
572 SDValue LowerHvxCttz(SDValue Op, SelectionDAG &DAG) const;
573 SDValue LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const;
574 SDValue LowerHvxMulLoHi(SDValue Op, SelectionDAG &DAG) const;
575 SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const;
576 SDValue LowerHvxSelect(SDValue Op, SelectionDAG &DAG) const;
577 SDValue LowerHvxShift(SDValue Op, SelectionDAG &DAG) const;
578 SDValue LowerHvxFunnelShift(SDValue Op, SelectionDAG &DAG) const;
579 SDValue LowerHvxIntrinsic(SDValue Op, SelectionDAG &DAG) const;
580 SDValue LowerHvxMaskedOp(SDValue Op, SelectionDAG &DAG) const;
581 SDValue LowerHvxFpExtend(SDValue Op, SelectionDAG &DAG) const;
582 SDValue LowerHvxFpToInt(SDValue Op, SelectionDAG &DAG) const;
583 SDValue LowerHvxIntToFp(SDValue Op, SelectionDAG &DAG) const;
584 SDValue LowerHvxPred32ToFp(SDValue Op, SelectionDAG &DAG) const;
585 SDValue LowerHvxPred64ToFp(SDValue Op, SelectionDAG &DAG) const;
586 SDValue ExpandHvxFpToInt(SDValue Op, SelectionDAG &DAG) const;
587 SDValue ExpandHvxIntToFp(SDValue Op, SelectionDAG &DAG) const;
588
589 VectorPair SplitVectorOp(SDValue Op, SelectionDAG &DAG) const;
590
591 SDValue SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const;
592 SDValue WidenHvxLoad(SDValue Op, SelectionDAG &DAG) const;
593 SDValue WidenHvxStore(SDValue Op, SelectionDAG &DAG) const;
594 SDValue WidenHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
595 SDValue LegalizeHvxResize(SDValue Op, SelectionDAG &DAG) const;
596 SDValue ExpandHvxResizeIntoSteps(SDValue Op, SelectionDAG &DAG) const;
597 SDValue EqualizeFpIntConversion(SDValue Op, SelectionDAG &DAG) const;
598
599 SDValue CreateTLWrapper(SDValue Op, SelectionDAG &DAG) const;
600 SDValue RemoveTLWrapper(SDValue Op, SelectionDAG &DAG) const;
601
602 std::pair<const TargetRegisterClass*, uint8_t>
603 findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
604 const override;
605
606 bool shouldSplitToHvx(MVT Ty, SelectionDAG &DAG) const;
607 bool shouldWidenToHvx(MVT Ty, SelectionDAG &DAG) const;
608 bool isHvxOperation(SDNode *N, SelectionDAG &DAG) const;
609 SDValue LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const;
610 void LowerHvxOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
611 SelectionDAG &DAG) const;
612 void ReplaceHvxNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
613 SelectionDAG &DAG) const;
614
615 SDValue combineTruncateBeforeLegal(SDValue Op, DAGCombinerInfo &DCI) const;
616 SDValue combineConcatVectorsBeforeLegal(SDValue Op, DAGCombinerInfo & DCI)
617 const;
618 SDValue combineVectorShuffleBeforeLegal(SDValue Op, DAGCombinerInfo & DCI)
619 const;
620
621 SDValue PerformHvxDAGCombine(SDNode * N, DAGCombinerInfo & DCI) const;
622};
623
624} // end namespace llvm
625
626#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
Definition CSEInfo.cpp:27
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
#define I(x, y, z)
Definition MD5.cpp:57
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
static Value * extractVector(IRBuilderTy &IRB, Value *V, unsigned BeginIndex, unsigned EndIndex, const Twine &Name)
Definition SROA.cpp:2621
static Value * insertVector(IRBuilderTy &IRB, Value *Old, Value *V, unsigned BeginIndex, const Twine &Name)
Definition SROA.cpp:2643
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
Class for arbitrary precision integers.
Definition APInt.h:78
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const
SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const
bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override
Return if the target supports combining a chain like:
bool isCtlzFast() const override
Return true if ctlz instruction is fast.
SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override
This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.
bool isTargetCanonicalConstantNode(SDValue Op) const override
Returns true if the given Opc is considered a canonical constant for the target, which should not be ...
ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const
SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const
SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const
SDValue LowerANY_EXTEND(SDValue Op, SelectionDAG &DAG) const
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT, std::optional< unsigned > ByteOffset) const override
Return true if it is profitable to reduce a load to a smaller type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const
AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be expanded by the IR-level AtomicExpand pass into.
SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA, SDValue InGlue, EVT PtrVT, unsigned ReturnReg, unsigned char OperandGlues) const
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &dl, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
Returns true by value, base pointer and offset pointer and addressing mode by reference if this node ...
SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFDIV(SDValue Op, SelectionDAG &DAG) const
SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const
bool isCheapToSpeculateCtlz(Type *) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
isFPImmLegal - Returns true if the target can instruction select the specified FP immediate natively.
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be expanded by the IR-level AtomicExpand pass.
bool isCheapToSpeculateCttz(Type *) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override
Return true if result of the specified node is used by a return node only.
SDValue LowerCallResult(SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals, const SmallVectorImpl< SDValue > &OutVals, SDValue Callee) const
LowerCallResult - Lower the result values of an ISD::CALL into the appropriate copies out of appropri...
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG) const
bool softPromoteHalfType() const override
SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG) const
bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Return true if the target supports a memory access of this type for the given address space and align...
SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const
bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT, unsigned Index) const override
Return true if EXTRACT_SUBVECTOR is cheap for extracting this result type from this source type with ...
SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
bool isShuffleMaskLegal(ArrayRef< int > Mask, EVT VT) const override
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
LegalizeAction getCustomOperationAction(SDNode &Op) const override
How to legalize this custom operation?
SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG) const
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
SDValue LowerUAddSubOCarry(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
LowerCall - Functions arguments are copied from virtual regs to (physical regs)/(stack frame),...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const
SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const
SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
EVT getSetCCResultType(const DataLayout &, LLVMContext &C, EVT VT) const override
Return the ValueType of the result of SETCC operations.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
bool hasBitTest(SDValue X, SDValue Y) const override
Return true if the target has a bit-test instruction: (X & (1 << Y)) ==/!= 0 This knowledge can be us...
HexagonTargetLowering(const TargetMachine &TM, const HexagonSubtarget &ST)
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
bool IsEligibleForTailCallOptimization(SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet, bool isCallerStructRet, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SmallVectorImpl< ISD::InputArg > &Ins, SelectionDAG &DAG) const
IsEligibleForTailCallOptimization - Check whether the call is eligible for tail call optimization.
SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const
SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &, EVT) const override
Return true if an FMA operation is faster than a pair of mul and add instructions.
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const
LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
std::pair< MVT, unsigned > handleMaskRegisterForCallingConv(const HexagonSubtarget &Subtarget, EVT VT) const
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const
SDValue LowerREADSTEADYCOUNTER(SDValue Op, SelectionDAG &DAG) const
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
An instruction for reading from memory.
Machine Value Type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
Representation of each machine instruction.
Flags
Flags values. These may be or'd together.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition ArrayRef.h:298
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
TargetLowering(const TargetLowering &)=delete
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM Value Representation.
Definition Value.h:75
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:228
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
Definition ISDOpcodes.h:607
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
AtomicOrdering
Atomic ordering for LLVM's memory model.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
Definition ValueTypes.h:74
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:168
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:336
This structure contains all information that is necessary for lowering calls.