LLVM  10.0.0svn
LegalizerHelper.h
Go to the documentation of this file.
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.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
21 #define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
22 
28 
29 namespace llvm {
30 // Forward declarations.
31 class LegalizerInfo;
32 class Legalizer;
33 class MachineRegisterInfo;
34 class GISelChangeObserver;
35 
37 public:
39  /// Instruction was already legal and no change was made to the
40  /// MachineFunction.
42 
43  /// Instruction has been legalized and the MachineFunction changed.
45 
46  /// Some kind of error has occurred and we could not legalize this
47  /// instruction.
49  };
50 
55 
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.
64 
65  /// Legalize an instruction by emiting a runtime library call instead.
67 
68  /// Legalize an instruction by reducing the width of the underlying scalar
69  /// type.
70  LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
71 
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);
76 
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);
80 
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.
84  LLT NarrowTy);
85 
86  /// Legalize a vector instruction by increasing the number of vector elements
87  /// involved and ignoring the added elements later.
89  LLT MoreTy);
90 
91  /// Expose MIRBuilder so clients can set their own RecordInsertInstruction
92  /// functions
94 
95  /// Expose LegalizerInfo so the clients can re-use.
96  const LegalizerInfo &getLegalizerInfo() const { return LI; }
97 
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);
105 
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);
110 
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);
116 
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);
126 
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);
131 
133  widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
135  widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
137  widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
139  widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
140 
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,
146 
147  /// Version which handles irregular splits.
148  bool extractParts(Register Reg, LLT RegTy, LLT MainTy,
149  LLT &LeftoverTy,
151  SmallVectorImpl<Register> &LeftoverVRegs);
152 
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.
157  ///
158  /// \p PartRegs must be registers of type \p PartTy.
159  ///
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 = {});
165 
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);
172 
173 public:
175  unsigned TypeIdx, LLT NarrowTy);
176 
177  /// Legalize a simple vector instruction where all operands are the same type
178  /// by splitting into multiple components.
180  LLT NarrowTy);
181 
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.
186  unsigned TypeIdx, LLT NarrowTy);
187 
189  LLT NarrowTy);
190 
192  fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
193 
195  fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
196 
198  unsigned TypeIdx, LLT NarrowTy);
199 
200  LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx,
201  LLT MoreTy);
202 
204  unsigned TypeIdx,
205  LLT NarrowTy);
207  unsigned TypeIdx,
208  LLT NarrowTy);
209 
211  reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
212 
214  LLT HalfTy, LLT ShiftAmtTy);
215 
216  LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
218  LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
219  LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
220 
221  LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
222  LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
223 
224  LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
225 
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);
240 
241 private:
242  MachineRegisterInfo &MRI;
243  const LegalizerInfo &LI;
244  /// To keep track of changes made by the LegalizerHelper.
245  GISelChangeObserver &Observer;
246 };
247 
248 /// Helper function that creates the given libcall.
251  const CallLowering::ArgInfo &Result,
253 
254 /// Create a libcall to memcpy et al.
256  MachineRegisterInfo &MRI,
257  MachineInstr &MI);
258 
259 } // End namespace llvm.
260 
261 #endif
const LegalizerInfo & getLegalizerInfo() const
Expose LegalizerInfo so the clients can re-use.
LegalizeResult fewerElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
LegalizeResult lowerUITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
LegalizeResult fewerElementsVectorMultiEltType(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize a instruction with a vector type where each operand may have a different element type...
LegalizeResult lowerMinMax(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
LegalizeResult fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
unsigned Reg
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty)
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions. ...
LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy)
Legalize an instruction by performing the operation on a wider scalar type (for example a 16-bit addi...
LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx, LLT MoreTy)
Legalize a vector instruction by increasing the number of vector elements involved and ignoring the a...
LegalizerHelper::LegalizeResult createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result, ArrayRef< CallLowering::ArgInfo > Args)
Helper function that creates the given libcall.
LegalizeResult lowerShuffleVector(MachineInstr &MI)
LegalizeResult lowerInsert(MachineInstr &MI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt, LLT HalfTy, LLT ShiftAmtTy)
LegalizeResult lowerDynStackAlloc(MachineInstr &MI)
LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer, MachineIRBuilder &B)
LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Abstract class that contains various methods for clients to notify about changes. ...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LegalizeResult legalizeInstrStep(MachineInstr &MI)
Replace MI by a sequence of legal instructions that can implement the same operation.
LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Helper class to build MachineInstr.
LegalizeResult reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
LegalizeResult lowerExtract(MachineInstr &MI)
LegalizerHelper::LegalizeResult createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, MachineInstr &MI)
Create a libcall to memcpy et al.
LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx, LLT MoreTy)
Some kind of error has occurred and we could not legalize this instruction.
Instruction was already legal and no change was made to the MachineFunction.
LegalizeResult lowerFCopySign(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
LegalizeResult libcall(MachineInstr &MI)
Legalize an instruction by emiting a runtime library call instead.
LegalizeResult lowerSITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
LegalizeResult lowerUnmergeValues(MachineInstr &MI)
LegalizeResult fewerElementsVectorBasic(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize a simple vector instruction where all operands are the same type by splitting into multiple ...
LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Legalize an instruction by splitting it into simpler parts, hopefully understood by the target...
LegalizeResult lowerFMad(MachineInstr &MI)
LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize a vector instruction by splitting into multiple components, each acting on the same scalar t...
LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI)
This file declares the MachineIRBuilder class.
LegalizeResult fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Class for arbitrary precision integers.
Definition: APInt.h:69
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI)
Representation of each machine instruction.
Definition: MachineInstr.h:63
Instruction has been legalized and the MachineFunction changed.
LegalizeResult fewerElementsVectorUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
LegalizeResult fewerElementsVectorBuildVector(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize an instruction by reducing the width of the underlying scalar type.
This file describes how to lower LLVM calls to machine code calls.
LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
IRTranslator LLVM IR MI
LegalizeResult lowerFPTOUI(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
LegalizeResult fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Wrapper class representing virtual and physical registers.
Definition: Register.h:19