1 //===-- VEISelLowering.h - VE 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 VE uses to lower LLVM code into a
10 // selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H
15 #define LLVM_LIB_TARGET_VE_VEISELLOWERING_H
16 
17 #include "VE.h"
18 #include "llvm/CodeGen/TargetLowering.h"
19 
20 namespace llvm {
21 class VESubtarget;
22 
23 namespace VEISD {
24 enum NodeType : unsigned {
25   FIRST_NUMBER = ISD::BUILTIN_OP_END,
26 
27   Hi,
28   Lo, // Hi/Lo operations, typically on a global address.
29 
30   GETFUNPLT,   // load function address through %plt insturction
31   GETTLSADDR,  // load address for TLS access
32   GETSTACKTOP, // retrieve address of stack top (first address of
33                // locals and temporaries)
34 
35   MEMBARRIER, // Compiler barrier only; generate a no-op.
36 
37   VEC_BROADCAST,    // 0: scalar value, 1: VL
38 
39   CALL,            // A call instruction.
40   RET_FLAG,        // Return with a flag operand.
41   GLOBAL_BASE_REG, // Global base reg for PIC.
42 
43   // VVP_* nodes.
44 #define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME,
45 #include "VVPNodes.def"
46 };
47 }
48 
49 class VETargetLowering : public TargetLowering {
50   const VESubtarget *Subtarget;
51 
52   void initRegisterClasses();
53   void initSPUActions();
54   void initVPUActions();
55 
56 public:
57   VETargetLowering(const TargetMachine &TM, const VESubtarget &STI);
58 
59   const char *getTargetNodeName(unsigned Opcode) const override;
getScalarShiftAmountTy(const DataLayout &,EVT)60   MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
61     return MVT::i32;
62   }
63 
64   Register getRegisterByName(const char *RegName, LLT VT,
65                              const MachineFunction &MF) const override;
66 
67   /// getSetCCResultType - Return the ISD::SETCC ValueType
68   EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
69                          EVT VT) const override;
70 
71   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
72                                bool isVarArg,
73                                const SmallVectorImpl<ISD::InputArg> &Ins,
74                                const SDLoc &dl, SelectionDAG &DAG,
75                                SmallVectorImpl<SDValue> &InVals) const override;
76 
77   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
78                     SmallVectorImpl<SDValue> &InVals) const override;
79 
80   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
81                       bool isVarArg,
82                       const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
83                       LLVMContext &Context) const override;
84   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
85                       const SmallVectorImpl<ISD::OutputArg> &Outs,
86                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
87                       SelectionDAG &DAG) const override;
88 
89   /// Helper functions for atomic operations.
shouldInsertFencesForAtomic(const Instruction * I)90   bool shouldInsertFencesForAtomic(const Instruction *I) const override {
91     // VE uses release consistency, so need fence for each atomics.
92     return true;
93   }
94   Instruction *emitLeadingFence(IRBuilder<> &Builder, Instruction *Inst,
95                                 AtomicOrdering Ord) const override;
96   Instruction *emitTrailingFence(IRBuilder<> &Builder, Instruction *Inst,
97                                  AtomicOrdering Ord) const override;
98 
99   /// Custom Lower {
100   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
101   unsigned getJumpTableEncoding() const override;
102   const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
103                                           const MachineBasicBlock *MBB,
104                                           unsigned Uid,
105                                           MCContext &Ctx) const override;
106   SDValue getPICJumpTableRelocBase(SDValue Table,
107                                    SelectionDAG &DAG) const override;
108   // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only
109   // EK_LabelDifference32.
110 
111   SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
112   SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
113   SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
114   SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
115   SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
116   SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
117   SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
118   SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
119   SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
120   SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const;
121   SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
122   SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
123 
124   SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
125   /// } Custom Lower
126 
127   /// VVP Lowering {
128   SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const;
129   /// } VVPLowering
130 
131   /// Custom DAGCombine {
132   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
133 
134   SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const;
135   /// } Custom DAGCombine
136 
137   SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;
138   SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
139                        SelectionDAG &DAG) const;
140   SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const;
141 
142   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
143   bool isFPImmLegal(const APFloat &Imm, EVT VT,
144                     bool ForCodeSize) const override;
145   /// Returns true if the target allows unaligned memory accesses of the
146   /// specified type.
147   bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, unsigned Align,
148                                       MachineMemOperand::Flags Flags,
149                                       bool *Fast) const override;
150 
151   /// Inline Assembly {
152 
153   ConstraintType getConstraintType(StringRef Constraint) const override;
154   std::pair<unsigned, const TargetRegisterClass *>
155   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
156                                StringRef Constraint, MVT VT) const override;
157 
158   /// } Inline Assembly
159 
160   /// Target Optimization {
161 
162   // Return lower limit for number of blocks in a jump table.
163   unsigned getMinimumJumpTableEntries() const override;
164 
165   // SX-Aurora VE's s/udiv is 5-9 times slower than multiply.
isIntDivCheap(EVT,AttributeList)166   bool isIntDivCheap(EVT, AttributeList) const override { return false; }
167   // VE doesn't have rem.
hasStandaloneRem(EVT)168   bool hasStandaloneRem(EVT) const override { return false; }
169   // VE LDZ instruction returns 64 if the input is zero.
isCheapToSpeculateCtlz()170   bool isCheapToSpeculateCtlz() const override { return true; }
171   // VE LDZ instruction is fast.
isCtlzFast()172   bool isCtlzFast() const override { return true; }
173   // VE has NND instruction.
174   bool hasAndNot(SDValue Y) const override;
175 
176   /// } Target Optimization
177 };
178 } // namespace llvm
179 
180 #endif // VE_ISELLOWERING_H
181