[Alignment][NFC] Support compile time constants
[llvm-core.git] / include / llvm / CodeGen / GlobalISel / LegalizerHelper.h
blobf65bf269c88f21380eedfcff0dccb9d717fc3cc0
1 //== llvm/CodeGen/GlobalISel/LegalizerHelper.h ---------------- -*- 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 /// \file A pass to convert the target-illegal operations created by IR -> MIR
10 /// translation into ones the target expects to be able to select. This may
11 /// occur in multiple phases, for example G_ADD <2 x i8> -> G_ADD <2 x i16> ->
12 /// G_ADD <4 x i16>.
13 ///
14 /// The LegalizerHelper class is where most of the work happens, and is
15 /// designed to be callable from other passes that find themselves with an
16 /// illegal instruction.
18 //===----------------------------------------------------------------------===//
20 #ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
21 #define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
23 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
24 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
25 #include "llvm/CodeGen/LowLevelType.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/RuntimeLibcalls.h"
29 namespace llvm {
30 // Forward declarations.
31 class LegalizerInfo;
32 class Legalizer;
33 class MachineRegisterInfo;
34 class GISelChangeObserver;
36 class LegalizerHelper {
37 public:
38 enum LegalizeResult {
39 /// Instruction was already legal and no change was made to the
40 /// MachineFunction.
41 AlreadyLegal,
43 /// Instruction has been legalized and the MachineFunction changed.
44 Legalized,
46 /// Some kind of error has occurred and we could not legalize this
47 /// instruction.
48 UnableToLegalize,
51 LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
52 MachineIRBuilder &B);
53 LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
54 GISelChangeObserver &Observer, MachineIRBuilder &B);
56 /// Replace \p MI by a sequence of legal instructions that can implement the
57 /// same operation. Note that this means \p MI may be deleted, so any iterator
58 /// steps should be performed before calling this function. \p Helper should
59 /// be initialized to the MachineFunction containing \p MI.
60 ///
61 /// Considered as an opaque blob, the legal code will use and define the same
62 /// registers as \p MI.
63 LegalizeResult legalizeInstrStep(MachineInstr &MI);
65 /// Legalize an instruction by emiting a runtime library call instead.
66 LegalizeResult libcall(MachineInstr &MI);
68 /// Legalize an instruction by reducing the width of the underlying scalar
69 /// type.
70 LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
72 /// Legalize an instruction by performing the operation on a wider scalar type
73 /// (for example a 16-bit addition can be safely performed at 32-bits
74 /// precision, ignoring the unused bits).
75 LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
77 /// Legalize an instruction by splitting it into simpler parts, hopefully
78 /// understood by the target.
79 LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
81 /// Legalize a vector instruction by splitting into multiple components, each
82 /// acting on the same scalar type as the original but with fewer elements.
83 LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
84 LLT NarrowTy);
86 /// Legalize a vector instruction by increasing the number of vector elements
87 /// involved and ignoring the added elements later.
88 LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
89 LLT MoreTy);
91 /// Expose MIRBuilder so clients can set their own RecordInsertInstruction
92 /// functions
93 MachineIRBuilder &MIRBuilder;
95 /// Expose LegalizerInfo so the clients can re-use.
96 const LegalizerInfo &getLegalizerInfo() const { return LI; }
98 private:
99 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
100 /// Use by extending the operand's type to \p WideTy using the specified \p
101 /// ExtOpcode for the extension instruction, and replacing the vreg of the
102 /// operand in place.
103 void widenScalarSrc(MachineInstr &MI, LLT WideTy, unsigned OpIdx,
104 unsigned ExtOpcode);
106 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
107 /// Use by truncating the operand's type to \p NarrowTy using G_TRUNC, and
108 /// replacing the vreg of the operand in place.
109 void narrowScalarSrc(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx);
111 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
112 /// Def by extending the operand's type to \p WideTy and truncating it back
113 /// with the \p TruncOpcode, and replacing the vreg of the operand in place.
114 void widenScalarDst(MachineInstr &MI, LLT WideTy, unsigned OpIdx = 0,
115 unsigned TruncOpcode = TargetOpcode::G_TRUNC);
117 // Legalize a single operand \p OpIdx of the machine instruction \p MI as a
118 // Def by truncating the operand's type to \p NarrowTy, replacing in place and
119 // extending back with \p ExtOpcode.
120 void narrowScalarDst(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx,
121 unsigned ExtOpcode);
122 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
123 /// Def by performing it with additional vector elements and extracting the
124 /// result elements, and replacing the vreg of the operand in place.
125 void moreElementsVectorDst(MachineInstr &MI, LLT MoreTy, unsigned OpIdx);
127 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
128 /// Use by producing a vector with undefined high elements, extracting the
129 /// original vector type, and replacing the vreg of the operand in place.
130 void moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy, unsigned OpIdx);
132 LegalizeResult
133 widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
134 LegalizeResult
135 widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
136 LegalizeResult
137 widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
138 LegalizeResult
139 widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
141 /// Helper function to split a wide generic register into bitwise blocks with
142 /// the given Type (which implies the number of blocks needed). The generic
143 /// registers created are appended to Ops, starting at bit 0 of Reg.
144 void extractParts(Register Reg, LLT Ty, int NumParts,
145 SmallVectorImpl<Register> &VRegs);
147 /// Version which handles irregular splits.
148 bool extractParts(Register Reg, LLT RegTy, LLT MainTy,
149 LLT &LeftoverTy,
150 SmallVectorImpl<Register> &VRegs,
151 SmallVectorImpl<Register> &LeftoverVRegs);
153 /// Helper function to build a wide generic register \p DstReg of type \p
154 /// RegTy from smaller parts. This will produce a G_MERGE_VALUES,
155 /// G_BUILD_VECTOR, G_CONCAT_VECTORS, or sequence of G_INSERT as appropriate
156 /// for the types.
158 /// \p PartRegs must be registers of type \p PartTy.
160 /// If \p ResultTy does not evenly break into \p PartTy sized pieces, the
161 /// remainder must be specified with \p LeftoverRegs of type \p LeftoverTy.
162 void insertParts(Register DstReg, LLT ResultTy,
163 LLT PartTy, ArrayRef<Register> PartRegs,
164 LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {});
166 /// Perform generic multiplication of values held in multiple registers.
167 /// Generated instructions use only types NarrowTy and i1.
168 /// Destination can be same or two times size of the source.
169 void multiplyRegisters(SmallVectorImpl<Register> &DstRegs,
170 ArrayRef<Register> Src1Regs,
171 ArrayRef<Register> Src2Regs, LLT NarrowTy);
173 public:
174 LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI,
175 unsigned TypeIdx, LLT NarrowTy);
177 /// Legalize a simple vector instruction where all operands are the same type
178 /// by splitting into multiple components.
179 LegalizeResult fewerElementsVectorBasic(MachineInstr &MI, unsigned TypeIdx,
180 LLT NarrowTy);
182 /// Legalize a instruction with a vector type where each operand may have a
183 /// different element type. All type indexes must have the same number of
184 /// elements.
185 LegalizeResult fewerElementsVectorMultiEltType(MachineInstr &MI,
186 unsigned TypeIdx, LLT NarrowTy);
188 LegalizeResult fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx,
189 LLT NarrowTy);
191 LegalizeResult
192 fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
194 LegalizeResult
195 fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
197 LegalizeResult fewerElementsVectorPhi(MachineInstr &MI,
198 unsigned TypeIdx, LLT NarrowTy);
200 LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx,
201 LLT MoreTy);
203 LegalizeResult fewerElementsVectorUnmergeValues(MachineInstr &MI,
204 unsigned TypeIdx,
205 LLT NarrowTy);
206 LegalizeResult fewerElementsVectorBuildVector(MachineInstr &MI,
207 unsigned TypeIdx,
208 LLT NarrowTy);
210 LegalizeResult
211 reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
213 LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt,
214 LLT HalfTy, LLT ShiftAmtTy);
216 LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
217 LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty);
218 LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
219 LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
221 LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
222 LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
224 LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
226 LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI);
227 LegalizeResult lowerUITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
228 LegalizeResult lowerSITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
229 LegalizeResult lowerFPTOUI(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
230 LegalizeResult lowerMinMax(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
231 LegalizeResult lowerFCopySign(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
232 LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
233 LegalizeResult lowerFMad(MachineInstr &MI);
234 LegalizeResult lowerUnmergeValues(MachineInstr &MI);
235 LegalizeResult lowerShuffleVector(MachineInstr &MI);
236 LegalizeResult lowerDynStackAlloc(MachineInstr &MI);
237 LegalizeResult lowerExtract(MachineInstr &MI);
238 LegalizeResult lowerInsert(MachineInstr &MI);
240 private:
241 MachineRegisterInfo &MRI;
242 const LegalizerInfo &LI;
243 /// To keep track of changes made by the LegalizerHelper.
244 GISelChangeObserver &Observer;
247 /// Helper function that creates the given libcall.
248 LegalizerHelper::LegalizeResult
249 createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
250 const CallLowering::ArgInfo &Result,
251 ArrayRef<CallLowering::ArgInfo> Args);
253 /// Create a libcall to memcpy et al.
254 LegalizerHelper::LegalizeResult createMemLibcall(MachineIRBuilder &MIRBuilder,
255 MachineRegisterInfo &MRI,
256 MachineInstr &MI);
258 } // End namespace llvm.
260 #endif