Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
Line
Count
Source
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
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"
28
29
namespace llvm {
30
// Forward declarations.
31
class LegalizerInfo;
32
class Legalizer;
33
class MachineRegisterInfo;
34
class GISelChangeObserver;
35
36
class LegalizerHelper {
37
public:
38
  enum LegalizeResult {
39
    /// Instruction was already legal and no change was made to the
40
    /// MachineFunction.
41
    AlreadyLegal,
42
43
    /// Instruction has been legalized and the MachineFunction changed.
44
    Legalized,
45
46
    /// Some kind of error has occurred and we could not legalize this
47
    /// instruction.
48
    UnableToLegalize,
49
  };
50
51
  LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
52
                  MachineIRBuilder &B);
53
  LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
54
                  GISelChangeObserver &Observer, MachineIRBuilder &B);
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.
63
  LegalizeResult legalizeInstrStep(MachineInstr &MI);
64
65
  /// Legalize an instruction by emiting a runtime library call instead.
66
  LegalizeResult libcall(MachineInstr &MI);
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.
83
  LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
84
                                     LLT NarrowTy);
85
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);
90
91
  /// Expose MIRBuilder so clients can set their own RecordInsertInstruction
92
  /// functions
93
  MachineIRBuilder &MIRBuilder;
94
95
  /// Expose LegalizerInfo so the clients can re-use.
96
239k
  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
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);
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,
145
                    SmallVectorImpl<Register> &VRegs);
146
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);
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:
174
  LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI,
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.
179
  LegalizeResult fewerElementsVectorBasic(MachineInstr &MI, unsigned TypeIdx,
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.
185
  LegalizeResult fewerElementsVectorMultiEltType(MachineInstr &MI,
186
                                                 unsigned TypeIdx, LLT NarrowTy);
187
188
  LegalizeResult fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx,
189
                                          LLT NarrowTy);
190
191
  LegalizeResult
192
  fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
193
194
  LegalizeResult
195
  fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
196
197
  LegalizeResult fewerElementsVectorPhi(MachineInstr &MI,
198
                                        unsigned TypeIdx, LLT NarrowTy);
199
200
  LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx,
201
                                       LLT MoreTy);
202
203
  LegalizeResult
204
  reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
205
206
  LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt,
207
                                             LLT HalfTy, LLT ShiftAmtTy);
208
209
  LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
210
  LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty);
211
  LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
212
  LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
213
214
  LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
215
  LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
216
217
  LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
218
219
  LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI);
220
  LegalizeResult lowerUITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
221
  LegalizeResult lowerSITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
222
  LegalizeResult lowerMinMax(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
223
  LegalizeResult lowerFCopySign(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
224
  LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
225
226
private:
227
  MachineRegisterInfo &MRI;
228
  const LegalizerInfo &LI;
229
  /// To keep track of changes made by the LegalizerHelper.
230
  GISelChangeObserver &Observer;
231
};
232
233
/// Helper function that creates the given libcall.
234
LegalizerHelper::LegalizeResult
235
createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
236
              const CallLowering::ArgInfo &Result,
237
              ArrayRef<CallLowering::ArgInfo> Args);
238
239
/// Create a libcall to memcpy et al.
240
LegalizerHelper::LegalizeResult createMemLibcall(MachineIRBuilder &MIRBuilder,
241
                                                 MachineRegisterInfo &MRI,
242
                                                 MachineInstr &MI);
243
244
} // End namespace llvm.
245
246
#endif