LLVM 20.0.0git
LegalityPredicates.cpp
Go to the documentation of this file.
1//===- lib/CodeGen/GlobalISel/LegalizerPredicates.cpp - Predicates --------===//
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// A library of predicate factories to use for LegalityPredicate.
10//
11//===----------------------------------------------------------------------===//
12
13// Enable optimizations to work around MSVC debug mode bug in 32-bit:
14// https://developercommunity.visualstudio.com/content/problem/1179643/msvc-copies-overaligned-non-trivially-copyable-par.html
15// FIXME: Remove this when the issue is closed.
16#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_IX86)
17// We have to disable runtime checks in order to enable optimizations. This is
18// done for the entire file because the problem is actually observed in STL
19// template functions.
20#pragma runtime_checks("", off)
21#pragma optimize("gs", on)
22#endif
23
25
26using namespace llvm;
27
29 return
30 [=](const LegalityQuery &Query) { return Query.Types[TypeIdx] == Type; };
31}
32
35 std::initializer_list<LLT> TypesInit) {
36 SmallVector<LLT, 4> Types = TypesInit;
37 return [=](const LegalityQuery &Query) {
38 return llvm::is_contained(Types, Query.Types[TypeIdx]);
39 };
40}
41
43 unsigned TypeIdx0, unsigned TypeIdx1,
44 std::initializer_list<std::pair<LLT, LLT>> TypesInit) {
45 SmallVector<std::pair<LLT, LLT>, 4> Types = TypesInit;
46 return [=](const LegalityQuery &Query) {
47 std::pair<LLT, LLT> Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1]};
48 return llvm::is_contained(Types, Match);
49 };
50}
51
53 unsigned TypeIdx0, unsigned TypeIdx1, unsigned TypeIdx2,
54 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit) {
55 SmallVector<std::tuple<LLT, LLT, LLT>, 4> Types = TypesInit;
56 return [=](const LegalityQuery &Query) {
57 std::tuple<LLT, LLT, LLT> Match = {
58 Query.Types[TypeIdx0], Query.Types[TypeIdx1], Query.Types[TypeIdx2]};
59 return llvm::is_contained(Types, Match);
60 };
61}
62
64 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
65 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit) {
66 SmallVector<TypePairAndMemDesc, 4> TypesAndMemDesc = TypesAndMemDescInit;
67 return [=](const LegalityQuery &Query) {
68 TypePairAndMemDesc Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1],
69 Query.MMODescrs[MMOIdx].MemoryTy,
70 Query.MMODescrs[MMOIdx].AlignInBits};
71 return llvm::any_of(TypesAndMemDesc,
72 [=](const TypePairAndMemDesc &Entry) -> bool {
73 return Match.isCompatible(Entry);
74 });
75 };
76}
77
79 return [=](const LegalityQuery &Query) {
80 return Query.Types[TypeIdx].isScalar();
81 };
82}
83
85 return [=](const LegalityQuery &Query) {
86 return Query.Types[TypeIdx].isVector();
87 };
88}
89
91 return [=](const LegalityQuery &Query) {
92 return Query.Types[TypeIdx].isPointer();
93 };
94}
95
97 unsigned AddrSpace) {
98 return [=](const LegalityQuery &Query) {
99 LLT Ty = Query.Types[TypeIdx];
100 return Ty.isPointer() && Ty.getAddressSpace() == AddrSpace;
101 };
102}
103
105 return [=](const LegalityQuery &Query) {
106 return Query.Types[TypeIdx].isPointerVector();
107 };
108}
109
111 LLT EltTy) {
112 return [=](const LegalityQuery &Query) {
113 const LLT QueryTy = Query.Types[TypeIdx];
114 return QueryTy.isVector() && QueryTy.getElementType() == EltTy;
115 };
116}
117
119 unsigned Size) {
120 return [=](const LegalityQuery &Query) {
121 const LLT QueryTy = Query.Types[TypeIdx];
122 return QueryTy.isScalar() && QueryTy.getSizeInBits() < Size;
123 };
124}
125
127 unsigned Size) {
128 return [=](const LegalityQuery &Query) {
129 const LLT QueryTy = Query.Types[TypeIdx];
130 return QueryTy.isScalar() && QueryTy.getSizeInBits() > Size;
131 };
132}
133
135 unsigned TypeIdx1) {
136 return [=](const LegalityQuery &Query) {
137 return Query.Types[TypeIdx0].getSizeInBits() <
138 Query.Types[TypeIdx1].getSizeInBits();
139 };
140}
141
143 unsigned TypeIdx1) {
144 return [=](const LegalityQuery &Query) {
145 return Query.Types[TypeIdx0].getSizeInBits() >
146 Query.Types[TypeIdx1].getSizeInBits();
147 };
148}
149
151 unsigned Size) {
152 return [=](const LegalityQuery &Query) {
153 const LLT QueryTy = Query.Types[TypeIdx];
154 return QueryTy.getScalarSizeInBits() < Size;
155 };
156}
157
159 unsigned Size) {
160 return [=](const LegalityQuery &Query) {
161 const LLT QueryTy = Query.Types[TypeIdx];
162 return QueryTy.getScalarSizeInBits() > Size;
163 };
164}
165
167 return [=](const LegalityQuery &Query) {
168 const LLT QueryTy = Query.Types[TypeIdx];
169 return !isPowerOf2_32(QueryTy.getScalarSizeInBits());
170 };
171}
172
174 unsigned Size) {
175 return [=](const LegalityQuery &Query) {
176 const LLT QueryTy = Query.Types[TypeIdx];
177 return QueryTy.isScalar() && QueryTy.getSizeInBits() % Size != 0;
178 };
179}
180
182 return [=](const LegalityQuery &Query) {
183 const LLT QueryTy = Query.Types[TypeIdx];
184 return QueryTy.isScalar() &&
185 !llvm::has_single_bit<uint32_t>(QueryTy.getSizeInBits());
186 };
187}
188
190 return [=](const LegalityQuery &Query) {
191 return Query.Types[TypeIdx].getSizeInBits() == Size;
192 };
193}
194
196 unsigned TypeIdx1) {
197 return [=](const LegalityQuery &Query) {
198 return Query.Types[TypeIdx0].getSizeInBits() ==
199 Query.Types[TypeIdx1].getSizeInBits();
200 };
201}
202
204 return [=](const LegalityQuery &Query) {
205 return !llvm::has_single_bit<uint32_t>(
206 Query.MMODescrs[MMOIdx].MemoryTy.getSizeInBytes());
207 };
208}
209
211 return [=](const LegalityQuery &Query) {
212 const LLT MemTy = Query.MMODescrs[MMOIdx].MemoryTy;
213 return !MemTy.isByteSized() ||
214 !llvm::has_single_bit<uint32_t>(
216 };
217}
218
220 return [=](const LegalityQuery &Query) {
221 const LLT QueryTy = Query.Types[TypeIdx];
222 return QueryTy.isFixedVector() && !isPowerOf2_32(QueryTy.getNumElements());
223 };
224}
225
227 unsigned MMOIdx, AtomicOrdering Ordering) {
228 return [=](const LegalityQuery &Query) {
229 return isAtLeastOrStrongerThan(Query.MMODescrs[MMOIdx].Ordering, Ordering);
230 };
231}
uint64_t Size
Interface for Targets to specify which operations they can successfully select and how the others sho...
constexpr unsigned getScalarSizeInBits() const
Definition: LowLevelType.h:264
constexpr bool isScalar() const
Definition: LowLevelType.h:146
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelType.h:159
constexpr bool isVector() const
Definition: LowLevelType.h:148
constexpr bool isByteSized() const
Definition: LowLevelType.h:260
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:190
constexpr bool isPointer() const
Definition: LowLevelType.h:149
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelType.h:277
constexpr unsigned getAddressSpace() const
Definition: LowLevelType.h:270
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
Definition: LowLevelType.h:177
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
Definition: LowLevelType.h:200
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:168
LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or a vector with an element type that's wider than the ...
LegalityPredicate isScalar(unsigned TypeIdx)
True iff the specified type index is a scalar.
LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx)
True iff the specified MMO index has a size (rounded to bytes) that is not a power of 2.
LegalityPredicate numElementsNotPow2(unsigned TypeIdx)
True iff the specified type index is a vector whose element count is not a power of 2.
LegalityPredicate isPointerVector(unsigned TypeIdx)
True iff the specified type index is a vector of pointers (with any address space).
LegalityPredicate isPointer(unsigned TypeIdx)
True iff the specified type index is a pointer (with any address space).
LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a smaller total bit size than second type index.
LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering)
True iff the specified MMO index has at an atomic ordering of at Ordering or stronger.
LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar or vector whose element size is not a power of 2.
LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a larger total bit size than second type index.
LegalityPredicate typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, std::initializer_list< std::pair< LLT, LLT > > TypesInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx)
True iff the specified MMO index has a size that is not an even byte size, or that even byte size is ...
LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy)
True if the type index is a vector with element type EltTy.
LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the specified type indices are both the same bit size.
LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or vector with an element type that's narrower than the...
LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size)
True if the total bitwidth of the specified type index is Size bits.
LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
LegalityPredicate sizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar whose size is not a power of.
LegalityPredicate typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2, std::initializer_list< std::tuple< LLT, LLT, LLT > > TypesInit)
True iff the given types for the given tuple of type indexes is one of the specified type tuple.
LegalityPredicate typePairAndMemDescInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, std::initializer_list< TypePairAndMemDesc > TypesAndMemDescInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar whose size is not a multiple of Size.
LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit)
True iff the given type index is the specified type.
LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's wider than the given size.
LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's narrower than the given size.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1746
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:291
bool isAtLeastOrStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1903
std::function< bool(const LegalityQuery &)> LegalityPredicate
The LegalityQuery object bundles together all the information that's needed to decide whether a given...