/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/CodeGen/GlobalISel/InstructionSelector.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 This file declares the API for the instruction selector. |
10 | | /// This class is responsible for selecting machine instructions. |
11 | | /// It's implemented by the target. It's used by the InstructionSelect pass. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #ifndef LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H |
16 | | #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H |
17 | | |
18 | | #include "llvm/ADT/DenseMap.h" |
19 | | #include "llvm/ADT/Optional.h" |
20 | | #include "llvm/ADT/SmallVector.h" |
21 | | #include "llvm/Support/CodeGenCoverage.h" |
22 | | #include "llvm/Support/LowLevelTypeImpl.h" |
23 | | #include <bitset> |
24 | | #include <cstddef> |
25 | | #include <cstdint> |
26 | | #include <functional> |
27 | | #include <initializer_list> |
28 | | #include <vector> |
29 | | |
30 | | namespace llvm { |
31 | | |
32 | | class APInt; |
33 | | class APFloat; |
34 | | class MachineInstr; |
35 | | class MachineInstrBuilder; |
36 | | class MachineFunction; |
37 | | class MachineOperand; |
38 | | class MachineRegisterInfo; |
39 | | class RegisterBankInfo; |
40 | | class TargetInstrInfo; |
41 | | class TargetRegisterClass; |
42 | | class TargetRegisterInfo; |
43 | | |
44 | | /// Container class for CodeGen predicate results. |
45 | | /// This is convenient because std::bitset does not have a constructor |
46 | | /// with an initializer list of set bits. |
47 | | /// |
48 | | /// Each InstructionSelector subclass should define a PredicateBitset class |
49 | | /// with: |
50 | | /// const unsigned MAX_SUBTARGET_PREDICATES = 192; |
51 | | /// using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>; |
52 | | /// and updating the constant to suit the target. Tablegen provides a suitable |
53 | | /// definition for the predicates in use in <Target>GenGlobalISel.inc when |
54 | | /// GET_GLOBALISEL_PREDICATE_BITSET is defined. |
55 | | template <std::size_t MaxPredicates> |
56 | | class PredicateBitsetImpl : public std::bitset<MaxPredicates> { |
57 | | public: |
58 | | // Cannot inherit constructors because it's not supported by VC++.. |
59 | 7.35M | PredicateBitsetImpl() = default; llvm::PredicateBitsetImpl<19ul>::PredicateBitsetImpl() Line | Count | Source | 59 | 6.89M | PredicateBitsetImpl() = default; |
llvm::PredicateBitsetImpl<33ul>::PredicateBitsetImpl() Line | Count | Source | 59 | 103k | PredicateBitsetImpl() = default; |
llvm::PredicateBitsetImpl<64ul>::PredicateBitsetImpl() Line | Count | Source | 59 | 112k | PredicateBitsetImpl() = default; |
llvm::PredicateBitsetImpl<42ul>::PredicateBitsetImpl() Line | Count | Source | 59 | 119k | PredicateBitsetImpl() = default; |
llvm::PredicateBitsetImpl<112ul>::PredicateBitsetImpl() Line | Count | Source | 59 | 128k | PredicateBitsetImpl() = default; |
|
60 | | |
61 | | PredicateBitsetImpl(const std::bitset<MaxPredicates> &B) |
62 | 6.77M | : std::bitset<MaxPredicates>(B) {} llvm::PredicateBitsetImpl<19ul>::PredicateBitsetImpl(std::__1::bitset<19ul> const&) Line | Count | Source | 62 | 6.77M | : std::bitset<MaxPredicates>(B) {} |
llvm::PredicateBitsetImpl<33ul>::PredicateBitsetImpl(std::__1::bitset<33ul> const&) Line | Count | Source | 62 | 56 | : std::bitset<MaxPredicates>(B) {} |
llvm::PredicateBitsetImpl<64ul>::PredicateBitsetImpl(std::__1::bitset<64ul> const&) Line | Count | Source | 62 | 783 | : std::bitset<MaxPredicates>(B) {} |
llvm::PredicateBitsetImpl<42ul>::PredicateBitsetImpl(std::__1::bitset<42ul> const&) Line | Count | Source | 62 | 423 | : std::bitset<MaxPredicates>(B) {} |
llvm::PredicateBitsetImpl<112ul>::PredicateBitsetImpl(std::__1::bitset<112ul> const&) Line | Count | Source | 62 | 2.16k | : std::bitset<MaxPredicates>(B) {} |
|
63 | | |
64 | 21.6M | PredicateBitsetImpl(std::initializer_list<unsigned> Init) { |
65 | 21.6M | for (auto I : Init) |
66 | 48.4M | std::bitset<MaxPredicates>::set(I); |
67 | 21.6M | } llvm::PredicateBitsetImpl<19ul>::PredicateBitsetImpl(std::initializer_list<unsigned int>) Line | Count | Source | 64 | 1.46M | PredicateBitsetImpl(std::initializer_list<unsigned> Init) { | 65 | 1.46M | for (auto I : Init) | 66 | 1.75M | std::bitset<MaxPredicates>::set(I); | 67 | 1.46M | } |
llvm::PredicateBitsetImpl<33ul>::PredicateBitsetImpl(std::initializer_list<unsigned int>) Line | Count | Source | 64 | 778k | PredicateBitsetImpl(std::initializer_list<unsigned> Init) { | 65 | 778k | for (auto I : Init) | 66 | 1.36M | std::bitset<MaxPredicates>::set(I); | 67 | 778k | } |
llvm::PredicateBitsetImpl<64ul>::PredicateBitsetImpl(std::initializer_list<unsigned int>) Line | Count | Source | 64 | 5.45M | PredicateBitsetImpl(std::initializer_list<unsigned> Init) { | 65 | 5.45M | for (auto I : Init) | 66 | 10.9M | std::bitset<MaxPredicates>::set(I); | 67 | 5.45M | } |
llvm::PredicateBitsetImpl<42ul>::PredicateBitsetImpl(std::initializer_list<unsigned int>) Line | Count | Source | 64 | 7.00M | PredicateBitsetImpl(std::initializer_list<unsigned> Init) { | 65 | 7.00M | for (auto I : Init) | 66 | 24.0M | std::bitset<MaxPredicates>::set(I); | 67 | 7.00M | } |
llvm::PredicateBitsetImpl<112ul>::PredicateBitsetImpl(std::initializer_list<unsigned int>) Line | Count | Source | 64 | 6.93M | PredicateBitsetImpl(std::initializer_list<unsigned> Init) { | 65 | 6.93M | for (auto I : Init) | 66 | 10.3M | std::bitset<MaxPredicates>::set(I); | 67 | 6.93M | } |
|
68 | | }; |
69 | | |
70 | | enum { |
71 | | /// Begin a try-block to attempt a match and jump to OnFail if it is |
72 | | /// unsuccessful. |
73 | | /// - OnFail - The MatchTable entry at which to resume if the match fails. |
74 | | /// |
75 | | /// FIXME: This ought to take an argument indicating the number of try-blocks |
76 | | /// to exit on failure. It's usually one but the last match attempt of |
77 | | /// a block will need more. The (implemented) alternative is to tack a |
78 | | /// GIM_Reject on the end of each try-block which is simpler but |
79 | | /// requires an extra opcode and iteration in the interpreter on each |
80 | | /// failed match. |
81 | | GIM_Try, |
82 | | |
83 | | /// Switch over the opcode on the specified instruction |
84 | | /// - InsnID - Instruction ID |
85 | | /// - LowerBound - numerically minimum opcode supported |
86 | | /// - UpperBound - numerically maximum + 1 opcode supported |
87 | | /// - Default - failure jump target |
88 | | /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets |
89 | | GIM_SwitchOpcode, |
90 | | |
91 | | /// Switch over the LLT on the specified instruction operand |
92 | | /// - InsnID - Instruction ID |
93 | | /// - OpIdx - Operand index |
94 | | /// - LowerBound - numerically minimum Type ID supported |
95 | | /// - UpperBound - numerically maximum + 1 Type ID supported |
96 | | /// - Default - failure jump target |
97 | | /// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets |
98 | | GIM_SwitchType, |
99 | | |
100 | | /// Record the specified instruction |
101 | | /// - NewInsnID - Instruction ID to define |
102 | | /// - InsnID - Instruction ID |
103 | | /// - OpIdx - Operand index |
104 | | GIM_RecordInsn, |
105 | | |
106 | | /// Check the feature bits |
107 | | /// - Expected features |
108 | | GIM_CheckFeatures, |
109 | | |
110 | | /// Check the opcode on the specified instruction |
111 | | /// - InsnID - Instruction ID |
112 | | /// - Expected opcode |
113 | | GIM_CheckOpcode, |
114 | | /// Check the instruction has the right number of operands |
115 | | /// - InsnID - Instruction ID |
116 | | /// - Expected number of operands |
117 | | GIM_CheckNumOperands, |
118 | | /// Check an immediate predicate on the specified instruction |
119 | | /// - InsnID - Instruction ID |
120 | | /// - The predicate to test |
121 | | GIM_CheckI64ImmPredicate, |
122 | | /// Check an immediate predicate on the specified instruction via an APInt. |
123 | | /// - InsnID - Instruction ID |
124 | | /// - The predicate to test |
125 | | GIM_CheckAPIntImmPredicate, |
126 | | /// Check a floating point immediate predicate on the specified instruction. |
127 | | /// - InsnID - Instruction ID |
128 | | /// - The predicate to test |
129 | | GIM_CheckAPFloatImmPredicate, |
130 | | /// Check a memory operation has the specified atomic ordering. |
131 | | /// - InsnID - Instruction ID |
132 | | /// - Ordering - The AtomicOrdering value |
133 | | GIM_CheckAtomicOrdering, |
134 | | GIM_CheckAtomicOrderingOrStrongerThan, |
135 | | GIM_CheckAtomicOrderingWeakerThan, |
136 | | /// Check the size of the memory access for the given machine memory operand. |
137 | | /// - InsnID - Instruction ID |
138 | | /// - MMOIdx - MMO index |
139 | | /// - Size - The size in bytes of the memory access |
140 | | GIM_CheckMemorySizeEqualTo, |
141 | | /// Check the size of the memory access for the given machine memory operand |
142 | | /// against the size of an operand. |
143 | | /// - InsnID - Instruction ID |
144 | | /// - MMOIdx - MMO index |
145 | | /// - OpIdx - The operand index to compare the MMO against |
146 | | GIM_CheckMemorySizeEqualToLLT, |
147 | | GIM_CheckMemorySizeLessThanLLT, |
148 | | GIM_CheckMemorySizeGreaterThanLLT, |
149 | | /// Check a generic C++ instruction predicate |
150 | | /// - InsnID - Instruction ID |
151 | | /// - PredicateID - The ID of the predicate function to call |
152 | | GIM_CheckCxxInsnPredicate, |
153 | | |
154 | | /// Check the type for the specified operand |
155 | | /// - InsnID - Instruction ID |
156 | | /// - OpIdx - Operand index |
157 | | /// - Expected type |
158 | | GIM_CheckType, |
159 | | /// Check the type of a pointer to any address space. |
160 | | /// - InsnID - Instruction ID |
161 | | /// - OpIdx - Operand index |
162 | | /// - SizeInBits - The size of the pointer value in bits. |
163 | | GIM_CheckPointerToAny, |
164 | | /// Check the register bank for the specified operand |
165 | | /// - InsnID - Instruction ID |
166 | | /// - OpIdx - Operand index |
167 | | /// - Expected register bank (specified as a register class) |
168 | | GIM_CheckRegBankForClass, |
169 | | |
170 | | /// Check the operand matches a complex predicate |
171 | | /// - InsnID - Instruction ID |
172 | | /// - OpIdx - Operand index |
173 | | /// - RendererID - The renderer to hold the result |
174 | | /// - Complex predicate ID |
175 | | GIM_CheckComplexPattern, |
176 | | |
177 | | /// Check the operand is a specific integer |
178 | | /// - InsnID - Instruction ID |
179 | | /// - OpIdx - Operand index |
180 | | /// - Expected integer |
181 | | GIM_CheckConstantInt, |
182 | | /// Check the operand is a specific literal integer (i.e. MO.isImm() or |
183 | | /// MO.isCImm() is true). |
184 | | /// - InsnID - Instruction ID |
185 | | /// - OpIdx - Operand index |
186 | | /// - Expected integer |
187 | | GIM_CheckLiteralInt, |
188 | | /// Check the operand is a specific intrinsic ID |
189 | | /// - InsnID - Instruction ID |
190 | | /// - OpIdx - Operand index |
191 | | /// - Expected Intrinsic ID |
192 | | GIM_CheckIntrinsicID, |
193 | | |
194 | | /// Check the specified operand is an MBB |
195 | | /// - InsnID - Instruction ID |
196 | | /// - OpIdx - Operand index |
197 | | GIM_CheckIsMBB, |
198 | | |
199 | | /// Check if the specified operand is safe to fold into the current |
200 | | /// instruction. |
201 | | /// - InsnID - Instruction ID |
202 | | GIM_CheckIsSafeToFold, |
203 | | |
204 | | /// Check the specified operands are identical. |
205 | | /// - InsnID - Instruction ID |
206 | | /// - OpIdx - Operand index |
207 | | /// - OtherInsnID - Other instruction ID |
208 | | /// - OtherOpIdx - Other operand index |
209 | | GIM_CheckIsSameOperand, |
210 | | |
211 | | /// Fail the current try-block, or completely fail to match if there is no |
212 | | /// current try-block. |
213 | | GIM_Reject, |
214 | | |
215 | | //=== Renderers === |
216 | | |
217 | | /// Mutate an instruction |
218 | | /// - NewInsnID - Instruction ID to define |
219 | | /// - OldInsnID - Instruction ID to mutate |
220 | | /// - NewOpcode - The new opcode to use |
221 | | GIR_MutateOpcode, |
222 | | |
223 | | /// Build a new instruction |
224 | | /// - InsnID - Instruction ID to define |
225 | | /// - Opcode - The new opcode to use |
226 | | GIR_BuildMI, |
227 | | |
228 | | /// Copy an operand to the specified instruction |
229 | | /// - NewInsnID - Instruction ID to modify |
230 | | /// - OldInsnID - Instruction ID to copy from |
231 | | /// - OpIdx - The operand to copy |
232 | | GIR_Copy, |
233 | | |
234 | | /// Copy an operand to the specified instruction or add a zero register if the |
235 | | /// operand is a zero immediate. |
236 | | /// - NewInsnID - Instruction ID to modify |
237 | | /// - OldInsnID - Instruction ID to copy from |
238 | | /// - OpIdx - The operand to copy |
239 | | /// - ZeroReg - The zero register to use |
240 | | GIR_CopyOrAddZeroReg, |
241 | | /// Copy an operand to the specified instruction |
242 | | /// - NewInsnID - Instruction ID to modify |
243 | | /// - OldInsnID - Instruction ID to copy from |
244 | | /// - OpIdx - The operand to copy |
245 | | /// - SubRegIdx - The subregister to copy |
246 | | GIR_CopySubReg, |
247 | | |
248 | | /// Add an implicit register def to the specified instruction |
249 | | /// - InsnID - Instruction ID to modify |
250 | | /// - RegNum - The register to add |
251 | | GIR_AddImplicitDef, |
252 | | /// Add an implicit register use to the specified instruction |
253 | | /// - InsnID - Instruction ID to modify |
254 | | /// - RegNum - The register to add |
255 | | GIR_AddImplicitUse, |
256 | | /// Add an register to the specified instruction |
257 | | /// - InsnID - Instruction ID to modify |
258 | | /// - RegNum - The register to add |
259 | | GIR_AddRegister, |
260 | | |
261 | | /// Add a temporary register to the specified instruction |
262 | | /// - InsnID - Instruction ID to modify |
263 | | /// - TempRegID - The temporary register ID to add |
264 | | /// - TempRegFlags - The register flags to set |
265 | | GIR_AddTempRegister, |
266 | | |
267 | | /// Add an immediate to the specified instruction |
268 | | /// - InsnID - Instruction ID to modify |
269 | | /// - Imm - The immediate to add |
270 | | GIR_AddImm, |
271 | | /// Render complex operands to the specified instruction |
272 | | /// - InsnID - Instruction ID to modify |
273 | | /// - RendererID - The renderer to call |
274 | | GIR_ComplexRenderer, |
275 | | |
276 | | /// Render sub-operands of complex operands to the specified instruction |
277 | | /// - InsnID - Instruction ID to modify |
278 | | /// - RendererID - The renderer to call |
279 | | /// - RenderOpID - The suboperand to render. |
280 | | GIR_ComplexSubOperandRenderer, |
281 | | /// Render operands to the specified instruction using a custom function |
282 | | /// - InsnID - Instruction ID to modify |
283 | | /// - OldInsnID - Instruction ID to get the matched operand from |
284 | | /// - RendererFnID - Custom renderer function to call |
285 | | GIR_CustomRenderer, |
286 | | |
287 | | /// Render a G_CONSTANT operator as a sign-extended immediate. |
288 | | /// - NewInsnID - Instruction ID to modify |
289 | | /// - OldInsnID - Instruction ID to copy from |
290 | | /// The operand index is implicitly 1. |
291 | | GIR_CopyConstantAsSImm, |
292 | | |
293 | | /// Render a G_FCONSTANT operator as a sign-extended immediate. |
294 | | /// - NewInsnID - Instruction ID to modify |
295 | | /// - OldInsnID - Instruction ID to copy from |
296 | | /// The operand index is implicitly 1. |
297 | | GIR_CopyFConstantAsFPImm, |
298 | | |
299 | | /// Constrain an instruction operand to a register class. |
300 | | /// - InsnID - Instruction ID to modify |
301 | | /// - OpIdx - Operand index |
302 | | /// - RCEnum - Register class enumeration value |
303 | | GIR_ConstrainOperandRC, |
304 | | |
305 | | /// Constrain an instructions operands according to the instruction |
306 | | /// description. |
307 | | /// - InsnID - Instruction ID to modify |
308 | | GIR_ConstrainSelectedInstOperands, |
309 | | |
310 | | /// Merge all memory operands into instruction. |
311 | | /// - InsnID - Instruction ID to modify |
312 | | /// - MergeInsnID... - One or more Instruction ID to merge into the result. |
313 | | /// - GIU_MergeMemOperands_EndOfList - Terminates the list of instructions to |
314 | | /// merge. |
315 | | GIR_MergeMemOperands, |
316 | | |
317 | | /// Erase from parent. |
318 | | /// - InsnID - Instruction ID to erase |
319 | | GIR_EraseFromParent, |
320 | | |
321 | | /// Create a new temporary register that's not constrained. |
322 | | /// - TempRegID - The temporary register ID to initialize. |
323 | | /// - Expected type |
324 | | GIR_MakeTempReg, |
325 | | |
326 | | /// A successful emission |
327 | | GIR_Done, |
328 | | |
329 | | /// Increment the rule coverage counter. |
330 | | /// - RuleID - The ID of the rule that was covered. |
331 | | GIR_Coverage, |
332 | | |
333 | | /// Keeping track of the number of the GI opcodes. Must be the last entry. |
334 | | GIU_NumOpcodes, |
335 | | }; |
336 | | |
337 | | enum { |
338 | | /// Indicates the end of the variable-length MergeInsnID list in a |
339 | | /// GIR_MergeMemOperands opcode. |
340 | | GIU_MergeMemOperands_EndOfList = -1, |
341 | | }; |
342 | | |
343 | | /// Provides the logic to select generic machine instructions. |
344 | | class InstructionSelector { |
345 | | public: |
346 | 31.3k | virtual ~InstructionSelector() = default; |
347 | | |
348 | | /// Select the (possibly generic) instruction \p I to only use target-specific |
349 | | /// opcodes. It is OK to insert multiple instructions, but they cannot be |
350 | | /// generic pre-isel instructions. |
351 | | /// |
352 | | /// \returns whether selection succeeded. |
353 | | /// \pre I.getParent() && I.getParent()->getParent() |
354 | | /// \post |
355 | | /// if returns true: |
356 | | /// for I in all mutated/inserted instructions: |
357 | | /// !isPreISelGenericOpcode(I.getOpcode()) |
358 | | virtual bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const = 0; |
359 | | |
360 | | protected: |
361 | | using ComplexRendererFns = |
362 | | Optional<SmallVector<std::function<void(MachineInstrBuilder &)>, 4>>; |
363 | | using RecordedMIVector = SmallVector<MachineInstr *, 4>; |
364 | | using NewMIVector = SmallVector<MachineInstrBuilder, 4>; |
365 | | |
366 | | struct MatcherState { |
367 | | std::vector<ComplexRendererFns::value_type> Renderers; |
368 | | RecordedMIVector MIs; |
369 | | DenseMap<unsigned, unsigned> TempRegisters; |
370 | | |
371 | | MatcherState(unsigned MaxRenderers); |
372 | | }; |
373 | | |
374 | | public: |
375 | | template <class PredicateBitset, class ComplexMatcherMemFn, |
376 | | class CustomRendererFn> |
377 | | struct ISelInfoTy { |
378 | | ISelInfoTy(const LLT *TypeObjects, size_t NumTypeObjects, |
379 | | const PredicateBitset *FeatureBitsets, |
380 | | const ComplexMatcherMemFn *ComplexPredicates, |
381 | | const CustomRendererFn *CustomRenderers) |
382 | | : TypeObjects(TypeObjects), |
383 | | FeatureBitsets(FeatureBitsets), |
384 | | ComplexPredicates(ComplexPredicates), |
385 | 44.0k | CustomRenderers(CustomRenderers) { |
386 | 44.0k | |
387 | 702k | for (size_t I = 0; I < NumTypeObjects; ++I658k ) |
388 | 658k | TypeIDMap[TypeObjects[I]] = I; |
389 | 44.0k | } AArch64InstructionSelector.cpp:llvm::InstructionSelector::ISelInfoTy<llvm::PredicateBitsetImpl<19ul>, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::AArch64InstructionSelector::*)(llvm::MachineOperand&) const, void ((anonymous namespace)::AArch64InstructionSelector::*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const>::ISelInfoTy(llvm::LLT const*, unsigned long, llvm::PredicateBitsetImpl<19ul> const*, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::AArch64InstructionSelector::* const*)(llvm::MachineOperand&) const, void ((anonymous namespace)::AArch64InstructionSelector::* const*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const) Line | Count | Source | 385 | 8.85k | CustomRenderers(CustomRenderers) { | 386 | 8.85k | | 387 | 106k | for (size_t I = 0; I < NumTypeObjects; ++I97.4k ) | 388 | 97.4k | TypeIDMap[TypeObjects[I]] = I; | 389 | 8.85k | } |
llvm::InstructionSelector::ISelInfoTy<llvm::PredicateBitsetImpl<33ul>, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > (llvm::AMDGPUInstructionSelector::*)(llvm::MachineOperand&) const, void (llvm::AMDGPUInstructionSelector::*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const>::ISelInfoTy(llvm::LLT const*, unsigned long, llvm::PredicateBitsetImpl<33ul> const*, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > (llvm::AMDGPUInstructionSelector::* const*)(llvm::MachineOperand&) const, void (llvm::AMDGPUInstructionSelector::* const*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const) Line | Count | Source | 385 | 2.90k | CustomRenderers(CustomRenderers) { | 386 | 2.90k | | 387 | 34.8k | for (size_t I = 0; I < NumTypeObjects; ++I31.9k ) | 388 | 31.9k | TypeIDMap[TypeObjects[I]] = I; | 389 | 2.90k | } |
ARMInstructionSelector.cpp:llvm::InstructionSelector::ISelInfoTy<llvm::PredicateBitsetImpl<64ul>, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::ARMInstructionSelector::*)(llvm::MachineOperand&) const, void ((anonymous namespace)::ARMInstructionSelector::*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const>::ISelInfoTy(llvm::LLT const*, unsigned long, llvm::PredicateBitsetImpl<64ul> const*, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::ARMInstructionSelector::* const*)(llvm::MachineOperand&) const, void ((anonymous namespace)::ARMInstructionSelector::* const*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const) Line | Count | Source | 385 | 7.00k | CustomRenderers(CustomRenderers) { | 386 | 7.00k | | 387 | 77.0k | for (size_t I = 0; I < NumTypeObjects; ++I70.0k ) | 388 | 70.0k | TypeIDMap[TypeObjects[I]] = I; | 389 | 7.00k | } |
MipsInstructionSelector.cpp:llvm::InstructionSelector::ISelInfoTy<llvm::PredicateBitsetImpl<42ul>, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::MipsInstructionSelector::*)(llvm::MachineOperand&) const, void ((anonymous namespace)::MipsInstructionSelector::*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const>::ISelInfoTy(llvm::LLT const*, unsigned long, llvm::PredicateBitsetImpl<42ul> const*, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::MipsInstructionSelector::* const*)(llvm::MachineOperand&) const, void ((anonymous namespace)::MipsInstructionSelector::* const*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const) Line | Count | Source | 385 | 10.7k | CustomRenderers(CustomRenderers) { | 386 | 10.7k | | 387 | 107k | for (size_t I = 0; I < NumTypeObjects; ++I96.5k ) | 388 | 96.5k | TypeIDMap[TypeObjects[I]] = I; | 389 | 10.7k | } |
X86InstructionSelector.cpp:llvm::InstructionSelector::ISelInfoTy<llvm::PredicateBitsetImpl<112ul>, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::X86InstructionSelector::*)(llvm::MachineOperand&) const, void ((anonymous namespace)::X86InstructionSelector::*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const>::ISelInfoTy(llvm::LLT const*, unsigned long, llvm::PredicateBitsetImpl<112ul> const*, llvm::Optional<llvm::SmallVector<std::__1::function<void (llvm::MachineInstrBuilder&)>, 4u> > ((anonymous namespace)::X86InstructionSelector::* const*)(llvm::MachineOperand&) const, void ((anonymous namespace)::X86InstructionSelector::* const*)(llvm::MachineInstrBuilder&, llvm::MachineInstr const&) const) Line | Count | Source | 385 | 14.5k | CustomRenderers(CustomRenderers) { | 386 | 14.5k | | 387 | 377k | for (size_t I = 0; I < NumTypeObjects; ++I362k ) | 388 | 362k | TypeIDMap[TypeObjects[I]] = I; | 389 | 14.5k | } |
|
390 | | const LLT *TypeObjects; |
391 | | const PredicateBitset *FeatureBitsets; |
392 | | const ComplexMatcherMemFn *ComplexPredicates; |
393 | | const CustomRendererFn *CustomRenderers; |
394 | | |
395 | | SmallDenseMap<LLT, unsigned, 64> TypeIDMap; |
396 | | }; |
397 | | |
398 | | protected: |
399 | | InstructionSelector(); |
400 | | |
401 | | /// Execute a given matcher table and return true if the match was successful |
402 | | /// and false otherwise. |
403 | | template <class TgtInstructionSelector, class PredicateBitset, |
404 | | class ComplexMatcherMemFn, class CustomRendererFn> |
405 | | bool executeMatchTable( |
406 | | TgtInstructionSelector &ISel, NewMIVector &OutMIs, MatcherState &State, |
407 | | const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, CustomRendererFn> |
408 | | &ISelInfo, |
409 | | const int64_t *MatchTable, const TargetInstrInfo &TII, |
410 | | MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, |
411 | | const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, |
412 | | CodeGenCoverage &CoverageInfo) const; |
413 | | |
414 | 0 | virtual const int64_t *getMatchTable() const { |
415 | 0 | llvm_unreachable("Should have been overridden by tablegen if used"); |
416 | 0 | } |
417 | | |
418 | 0 | virtual bool testImmPredicate_I64(unsigned, int64_t) const { |
419 | 0 | llvm_unreachable( |
420 | 0 | "Subclasses must override this with a tablegen-erated function"); |
421 | 0 | } |
422 | 0 | virtual bool testImmPredicate_APInt(unsigned, const APInt &) const { |
423 | 0 | llvm_unreachable( |
424 | 0 | "Subclasses must override this with a tablegen-erated function"); |
425 | 0 | } |
426 | 0 | virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const { |
427 | 0 | llvm_unreachable( |
428 | 0 | "Subclasses must override this with a tablegen-erated function"); |
429 | 0 | } |
430 | 0 | virtual bool testMIPredicate_MI(unsigned, const MachineInstr &) const { |
431 | 0 | llvm_unreachable( |
432 | 0 | "Subclasses must override this with a tablegen-erated function"); |
433 | 0 | } |
434 | | |
435 | | /// Constrain a register operand of an instruction \p I to a specified |
436 | | /// register class. This could involve inserting COPYs before (for uses) or |
437 | | /// after (for defs) and may replace the operand of \p I. |
438 | | /// \returns whether operand regclass constraining succeeded. |
439 | | bool constrainOperandRegToRegClass(MachineInstr &I, unsigned OpIdx, |
440 | | const TargetRegisterClass &RC, |
441 | | const TargetInstrInfo &TII, |
442 | | const TargetRegisterInfo &TRI, |
443 | | const RegisterBankInfo &RBI) const; |
444 | | |
445 | | bool isOperandImmEqual(const MachineOperand &MO, int64_t Value, |
446 | | const MachineRegisterInfo &MRI) const; |
447 | | |
448 | | /// Return true if the specified operand is a G_GEP with a G_CONSTANT on the |
449 | | /// right-hand side. GlobalISel's separation of pointer and integer types |
450 | | /// means that we don't need to worry about G_OR with equivalent semantics. |
451 | | bool isBaseWithConstantOffset(const MachineOperand &Root, |
452 | | const MachineRegisterInfo &MRI) const; |
453 | | |
454 | | /// Return true if MI can obviously be folded into IntoMI. |
455 | | /// MI and IntoMI do not need to be in the same basic blocks, but MI must |
456 | | /// preceed IntoMI. |
457 | | bool isObviouslySafeToFold(MachineInstr &MI, MachineInstr &IntoMI) const; |
458 | | }; |
459 | | |
460 | | } // end namespace llvm |
461 | | |
462 | | #endif // LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H |