1 | //===-- BPFISelLowering.h - BPF 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 BPF uses to lower LLVM code into a |
10 | // selection DAG. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_LIB_TARGET_BPF_BPFISELLOWERING_H |
15 | #define LLVM_LIB_TARGET_BPF_BPFISELLOWERING_H |
16 | |
17 | #include "BPF.h" |
18 | #include "llvm/CodeGen/SelectionDAG.h" |
19 | #include "llvm/CodeGen/TargetLowering.h" |
20 | |
21 | namespace llvm { |
22 | class BPFSubtarget; |
23 | namespace BPFISD { |
24 | enum NodeType : unsigned { |
25 | FIRST_NUMBER = ISD::BUILTIN_OP_END, |
26 | RET_GLUE, |
27 | CALL, |
28 | SELECT_CC, |
29 | BR_CC, |
30 | Wrapper, |
31 | MEMCPY |
32 | }; |
33 | } |
34 | |
35 | class BPFTargetLowering : public TargetLowering { |
36 | public: |
37 | explicit BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI); |
38 | |
39 | // Provide custom lowering hooks for some operations. |
40 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
41 | |
42 | // This method returns the name of a target specific DAG node. |
43 | const char *getTargetNodeName(unsigned Opcode) const override; |
44 | |
45 | // This method decides whether folding a constant offset |
46 | // with the given GlobalAddress is legal. |
47 | bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; |
48 | |
49 | BPFTargetLowering::ConstraintType |
50 | getConstraintType(StringRef Constraint) const override; |
51 | |
52 | std::pair<unsigned, const TargetRegisterClass *> |
53 | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
54 | StringRef Constraint, MVT VT) const override; |
55 | |
56 | MachineBasicBlock * |
57 | EmitInstrWithCustomInserter(MachineInstr &MI, |
58 | MachineBasicBlock *BB) const override; |
59 | |
60 | bool getHasAlu32() const { return HasAlu32; } |
61 | bool getHasJmp32() const { return HasJmp32; } |
62 | bool getHasJmpExt() const { return HasJmpExt; } |
63 | |
64 | EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, |
65 | EVT VT) const override; |
66 | |
67 | MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override; |
68 | |
69 | private: |
70 | // Control Instruction Selection Features |
71 | bool HasAlu32; |
72 | bool HasJmp32; |
73 | bool HasJmpExt; |
74 | bool HasMovsx; |
75 | |
76 | SDValue LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const; |
77 | SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; |
78 | SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; |
79 | SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; |
80 | |
81 | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
82 | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; |
83 | |
84 | template <class NodeTy> |
85 | SDValue getAddr(NodeTy *N, SelectionDAG &DAG, unsigned Flags = 0) const; |
86 | |
87 | // Lower the result values of a call, copying them out of physregs into vregs |
88 | SDValue LowerCallResult(SDValue Chain, SDValue InGlue, |
89 | CallingConv::ID CallConv, bool IsVarArg, |
90 | const SmallVectorImpl<ISD::InputArg> &Ins, |
91 | const SDLoc &DL, SelectionDAG &DAG, |
92 | SmallVectorImpl<SDValue> &InVals) const; |
93 | |
94 | // Maximum number of arguments to a call |
95 | static const size_t MaxArgs; |
96 | |
97 | // Lower a call into CALLSEQ_START - BPFISD:CALL - CALLSEQ_END chain |
98 | SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, |
99 | SmallVectorImpl<SDValue> &InVals) const override; |
100 | |
101 | // Lower incoming arguments, copy physregs into vregs |
102 | SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, |
103 | bool IsVarArg, |
104 | const SmallVectorImpl<ISD::InputArg> &Ins, |
105 | const SDLoc &DL, SelectionDAG &DAG, |
106 | SmallVectorImpl<SDValue> &InVals) const override; |
107 | |
108 | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, |
109 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
110 | const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, |
111 | SelectionDAG &DAG) const override; |
112 | |
113 | void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, |
114 | SelectionDAG &DAG) const override; |
115 | |
116 | EVT getOptimalMemOpType(const MemOp &Op, |
117 | const AttributeList &FuncAttributes) const override { |
118 | return Op.size() >= 8 ? MVT::i64 : MVT::i32; |
119 | } |
120 | |
121 | bool isIntDivCheap(EVT VT, AttributeList Attr) const override { return true; } |
122 | |
123 | bool shouldConvertConstantLoadToIntImm(const APInt &Imm, |
124 | Type *Ty) const override { |
125 | return true; |
126 | } |
127 | |
128 | // Prevent reducing load width during SelectionDag phase. |
129 | // Otherwise, we may transform the following |
130 | // ctx = ctx + reloc_offset |
131 | // ... (*(u32 *)ctx) & 0x8000... |
132 | // to |
133 | // ctx = ctx + reloc_offset |
134 | // ... (*(u8 *)(ctx + 1)) & 0x80 ... |
135 | // which will be rejected by the verifier. |
136 | bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, |
137 | EVT NewVT) const override { |
138 | return false; |
139 | } |
140 | |
141 | bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, |
142 | Type *Ty, unsigned AS, |
143 | Instruction *I = nullptr) const override; |
144 | |
145 | // isTruncateFree - Return true if it's free to truncate a value of |
146 | // type Ty1 to type Ty2. e.g. On BPF at alu32 mode, it's free to truncate |
147 | // a i64 value in register R1 to i32 by referencing its sub-register W1. |
148 | bool isTruncateFree(Type *Ty1, Type *Ty2) const override; |
149 | bool isTruncateFree(EVT VT1, EVT VT2) const override; |
150 | |
151 | // For 32bit ALU result zext to 64bit is free. |
152 | bool isZExtFree(Type *Ty1, Type *Ty2) const override; |
153 | bool isZExtFree(EVT VT1, EVT VT2) const override; |
154 | bool isZExtFree(SDValue Val, EVT VT2) const override; |
155 | |
156 | unsigned EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB, unsigned Reg, |
157 | bool isSigned) const; |
158 | |
159 | MachineBasicBlock * EmitInstrWithCustomInserterMemcpy(MachineInstr &MI, |
160 | MachineBasicBlock *BB) |
161 | const; |
162 | |
163 | }; |
164 | } |
165 | |
166 | #endif |
167 | |