LLVM  9.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(unsigned Reg, LLT Ty, int NumParts,
146 
147  /// Version which handles irregular splits.
148  bool extractParts(unsigned Reg, LLT RegTy, LLT MainTy,
149  LLT &LeftoverTy,
151  SmallVectorImpl<unsigned> &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(unsigned DstReg, LLT ResultTy,
163  LLT PartTy, ArrayRef<unsigned> PartRegs,
164  LLT LeftoverTy = LLT(), ArrayRef<unsigned> 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<unsigned> &DstRegs,
170  ArrayRef<unsigned> Src1Regs,
171  ArrayRef<unsigned> Src2Regs, LLT NarrowTy);
172 
173  LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI,
174  unsigned TypeIdx, LLT NarrowTy);
175 
176  /// Legalize a simple vector instruction where all operands are the same type
177  /// by splitting into multiple components.
178  LegalizeResult fewerElementsVectorBasic(MachineInstr &MI, unsigned TypeIdx,
179  LLT NarrowTy);
180 
181  /// Legalize a instruction with a vector type where each operand may have a
182  /// different element type. All type indexes must have the same number of
183  /// elements.
184  LegalizeResult fewerElementsVectorMultiEltType(MachineInstr &MI,
185  unsigned TypeIdx, LLT NarrowTy);
186 
187  LegalizeResult fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx,
188  LLT NarrowTy);
189 
191  fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
192 
194  fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
195 
196  LegalizeResult fewerElementsVectorPhi(MachineInstr &MI,
197  unsigned TypeIdx, LLT NarrowTy);
198 
199  LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx,
200  LLT MoreTy);
201 
203  reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
204 
205  LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt,
206  LLT HalfTy, LLT ShiftAmtTy);
207 
208  LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
209  LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty);
210  LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
211  LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
212 
213  LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
214  LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
215 
216  LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
217 
218  LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI);
219  LegalizeResult lowerUITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
220  LegalizeResult lowerSITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
221 
222  MachineRegisterInfo &MRI;
223  const LegalizerInfo &LI;
224  /// To keep track of changes made by the LegalizerHelper.
225  GISelChangeObserver &Observer;
226 };
227 
228 /// Helper function that creates the given libcall.
231  const CallLowering::ArgInfo &Result,
233 
234 } // End namespace llvm.
235 
236 #endif
const LegalizerInfo & getLegalizerInfo() const
Expose LegalizerInfo so the clients can re-use.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
unsigned Reg
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
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 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.
LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer, MachineIRBuilder &B)
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.
Helper class to build MachineInstr.
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 libcall(MachineInstr &MI)
Legalize an instruction by emiting a runtime library call instead.
LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Legalize an instruction by splitting it into simpler parts, hopefully understood by the target...
LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize a vector instruction by splitting into multiple components, each acting on the same scalar t...
This file declares the MachineIRBuilder class.
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.
Representation of each machine instruction.
Definition: MachineInstr.h:63
Instruction has been legalized and the MachineFunction changed.
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.
IRTranslator LLVM IR MI
constexpr char Args[]
Key for Kernel::Metadata::mArgs.