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 // Disable 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 24 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 25 26 using namespace llvm; 27 28 LegalityPredicate LegalityPredicates::typeIs(unsigned TypeIdx, LLT Type) { 29 return 30 [=](const LegalityQuery &Query) { return Query.Types[TypeIdx] == Type; }; 31 } 32 33 LegalityPredicate 34 LegalityPredicates::typeInSet(unsigned TypeIdx, 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 42 LegalityPredicate LegalityPredicates::typePairInSet( 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 52 LegalityPredicate LegalityPredicates::typePairAndMemDescInSet( 53 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, 54 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit) { 55 SmallVector<TypePairAndMemDesc, 4> TypesAndMemDesc = TypesAndMemDescInit; 56 return [=](const LegalityQuery &Query) { 57 TypePairAndMemDesc Match = {Query.Types[TypeIdx0], Query.Types[TypeIdx1], 58 Query.MMODescrs[MMOIdx].SizeInBits, 59 Query.MMODescrs[MMOIdx].AlignInBits}; 60 return std::find_if( 61 TypesAndMemDesc.begin(), TypesAndMemDesc.end(), 62 [=](const TypePairAndMemDesc &Entry) ->bool { 63 return Match.isCompatible(Entry); 64 }) != TypesAndMemDesc.end(); 65 }; 66 } 67 68 LegalityPredicate LegalityPredicates::isScalar(unsigned TypeIdx) { 69 return [=](const LegalityQuery &Query) { 70 return Query.Types[TypeIdx].isScalar(); 71 }; 72 } 73 74 LegalityPredicate LegalityPredicates::isVector(unsigned TypeIdx) { 75 return [=](const LegalityQuery &Query) { 76 return Query.Types[TypeIdx].isVector(); 77 }; 78 } 79 80 LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx) { 81 return [=](const LegalityQuery &Query) { 82 return Query.Types[TypeIdx].isPointer(); 83 }; 84 } 85 86 LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx, 87 unsigned AddrSpace) { 88 return [=](const LegalityQuery &Query) { 89 LLT Ty = Query.Types[TypeIdx]; 90 return Ty.isPointer() && Ty.getAddressSpace() == AddrSpace; 91 }; 92 } 93 94 LegalityPredicate LegalityPredicates::elementTypeIs(unsigned TypeIdx, 95 LLT EltTy) { 96 return [=](const LegalityQuery &Query) { 97 const LLT QueryTy = Query.Types[TypeIdx]; 98 return QueryTy.isVector() && QueryTy.getElementType() == EltTy; 99 }; 100 } 101 102 LegalityPredicate LegalityPredicates::scalarNarrowerThan(unsigned TypeIdx, 103 unsigned Size) { 104 return [=](const LegalityQuery &Query) { 105 const LLT QueryTy = Query.Types[TypeIdx]; 106 return QueryTy.isScalar() && QueryTy.getSizeInBits() < Size; 107 }; 108 } 109 110 LegalityPredicate LegalityPredicates::scalarWiderThan(unsigned TypeIdx, 111 unsigned Size) { 112 return [=](const LegalityQuery &Query) { 113 const LLT QueryTy = Query.Types[TypeIdx]; 114 return QueryTy.isScalar() && QueryTy.getSizeInBits() > Size; 115 }; 116 } 117 118 LegalityPredicate LegalityPredicates::smallerThan(unsigned TypeIdx0, 119 unsigned TypeIdx1) { 120 return [=](const LegalityQuery &Query) { 121 return Query.Types[TypeIdx0].getSizeInBits() < 122 Query.Types[TypeIdx1].getSizeInBits(); 123 }; 124 } 125 126 LegalityPredicate LegalityPredicates::largerThan(unsigned TypeIdx0, 127 unsigned TypeIdx1) { 128 return [=](const LegalityQuery &Query) { 129 return Query.Types[TypeIdx0].getSizeInBits() > 130 Query.Types[TypeIdx1].getSizeInBits(); 131 }; 132 } 133 134 LegalityPredicate LegalityPredicates::scalarOrEltNarrowerThan(unsigned TypeIdx, 135 unsigned Size) { 136 return [=](const LegalityQuery &Query) { 137 const LLT QueryTy = Query.Types[TypeIdx]; 138 return QueryTy.getScalarSizeInBits() < Size; 139 }; 140 } 141 142 LegalityPredicate LegalityPredicates::scalarOrEltWiderThan(unsigned TypeIdx, 143 unsigned Size) { 144 return [=](const LegalityQuery &Query) { 145 const LLT QueryTy = Query.Types[TypeIdx]; 146 return QueryTy.getScalarSizeInBits() > Size; 147 }; 148 } 149 150 LegalityPredicate LegalityPredicates::scalarOrEltSizeNotPow2(unsigned TypeIdx) { 151 return [=](const LegalityQuery &Query) { 152 const LLT QueryTy = Query.Types[TypeIdx]; 153 return !isPowerOf2_32(QueryTy.getScalarSizeInBits()); 154 }; 155 } 156 157 LegalityPredicate LegalityPredicates::sizeNotPow2(unsigned TypeIdx) { 158 return [=](const LegalityQuery &Query) { 159 const LLT QueryTy = Query.Types[TypeIdx]; 160 return QueryTy.isScalar() && !isPowerOf2_32(QueryTy.getSizeInBits()); 161 }; 162 } 163 164 LegalityPredicate LegalityPredicates::sizeIs(unsigned TypeIdx, unsigned Size) { 165 return [=](const LegalityQuery &Query) { 166 return Query.Types[TypeIdx].getSizeInBits() == Size; 167 }; 168 } 169 170 LegalityPredicate LegalityPredicates::sameSize(unsigned TypeIdx0, 171 unsigned TypeIdx1) { 172 return [=](const LegalityQuery &Query) { 173 return Query.Types[TypeIdx0].getSizeInBits() == 174 Query.Types[TypeIdx1].getSizeInBits(); 175 }; 176 } 177 178 LegalityPredicate LegalityPredicates::memSizeInBytesNotPow2(unsigned MMOIdx) { 179 return [=](const LegalityQuery &Query) { 180 return !isPowerOf2_32(Query.MMODescrs[MMOIdx].SizeInBits / 8); 181 }; 182 } 183 184 LegalityPredicate LegalityPredicates::numElementsNotPow2(unsigned TypeIdx) { 185 return [=](const LegalityQuery &Query) { 186 const LLT QueryTy = Query.Types[TypeIdx]; 187 return QueryTy.isVector() && !isPowerOf2_32(QueryTy.getNumElements()); 188 }; 189 } 190 191 LegalityPredicate LegalityPredicates::atomicOrderingAtLeastOrStrongerThan( 192 unsigned MMOIdx, AtomicOrdering Ordering) { 193 return [=](const LegalityQuery &Query) { 194 return isAtLeastOrStrongerThan(Query.MMODescrs[MMOIdx].Ordering, Ordering); 195 }; 196 } 197