252 lines · cpp
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-exception6//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.html15// 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 is18// done for the entire file because the problem is actually observed in STL19// template functions.20#pragma runtime_checks("", off)21#pragma optimize("gs", on)22#endif23 24#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"25 26using namespace llvm;27 28LegalityPredicate LegalityPredicates::typeIs(unsigned TypeIdx, LLT Type) {29 return30 [=](const LegalityQuery &Query) { return Query.Types[TypeIdx] == Type; };31}32 33LegalityPredicate34LegalityPredicates::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 42LegalityPredicate 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 52LegalityPredicate LegalityPredicates::typeTupleInSet(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 63LegalityPredicate LegalityPredicates::typePairAndMemDescInSet(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 78LegalityPredicate LegalityPredicates::isScalar(unsigned TypeIdx) {79 return [=](const LegalityQuery &Query) {80 return Query.Types[TypeIdx].isScalar();81 };82}83 84LegalityPredicate LegalityPredicates::isVector(unsigned TypeIdx) {85 return [=](const LegalityQuery &Query) {86 return Query.Types[TypeIdx].isVector();87 };88}89 90LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx) {91 return [=](const LegalityQuery &Query) {92 return Query.Types[TypeIdx].isPointer();93 };94}95 96LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx,97 unsigned AddrSpace) {98 return [=](const LegalityQuery &Query) {99 LLT Ty = Query.Types[TypeIdx];100 return Ty.isPointer() && Ty.getAddressSpace() == AddrSpace;101 };102}103 104LegalityPredicate LegalityPredicates::isPointerVector(unsigned TypeIdx) {105 return [=](const LegalityQuery &Query) {106 return Query.Types[TypeIdx].isPointerVector();107 };108}109 110LegalityPredicate LegalityPredicates::elementTypeIs(unsigned TypeIdx,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 118LegalityPredicate LegalityPredicates::scalarNarrowerThan(unsigned TypeIdx,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 126LegalityPredicate LegalityPredicates::scalarWiderThan(unsigned TypeIdx,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 134LegalityPredicate LegalityPredicates::smallerThan(unsigned TypeIdx0,135 unsigned TypeIdx1) {136 return [=](const LegalityQuery &Query) {137 return Query.Types[TypeIdx0].getSizeInBits() <138 Query.Types[TypeIdx1].getSizeInBits();139 };140}141 142LegalityPredicate LegalityPredicates::largerThan(unsigned TypeIdx0,143 unsigned TypeIdx1) {144 return [=](const LegalityQuery &Query) {145 return Query.Types[TypeIdx0].getSizeInBits() >146 Query.Types[TypeIdx1].getSizeInBits();147 };148}149 150LegalityPredicate LegalityPredicates::scalarOrEltNarrowerThan(unsigned TypeIdx,151 unsigned Size) {152 return [=](const LegalityQuery &Query) {153 const LLT QueryTy = Query.Types[TypeIdx];154 return QueryTy.getScalarSizeInBits() < Size;155 };156}157 158LegalityPredicate159LegalityPredicates::vectorElementCountIsGreaterThan(unsigned TypeIdx,160 unsigned Size) {161 162 return [=](const LegalityQuery &Query) {163 const LLT QueryTy = Query.Types[TypeIdx];164 return QueryTy.isFixedVector() && QueryTy.getNumElements() > Size;165 };166}167 168LegalityPredicate169LegalityPredicates::vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx,170 unsigned Size) {171 172 return [=](const LegalityQuery &Query) {173 const LLT QueryTy = Query.Types[TypeIdx];174 return QueryTy.isFixedVector() && QueryTy.getNumElements() <= Size;175 };176}177 178LegalityPredicate LegalityPredicates::scalarOrEltWiderThan(unsigned TypeIdx,179 unsigned Size) {180 return [=](const LegalityQuery &Query) {181 const LLT QueryTy = Query.Types[TypeIdx];182 return QueryTy.getScalarSizeInBits() > Size;183 };184}185 186LegalityPredicate LegalityPredicates::scalarOrEltSizeNotPow2(unsigned TypeIdx) {187 return [=](const LegalityQuery &Query) {188 const LLT QueryTy = Query.Types[TypeIdx];189 return !isPowerOf2_32(QueryTy.getScalarSizeInBits());190 };191}192 193LegalityPredicate LegalityPredicates::sizeNotMultipleOf(unsigned TypeIdx,194 unsigned Size) {195 return [=](const LegalityQuery &Query) {196 const LLT QueryTy = Query.Types[TypeIdx];197 return QueryTy.isScalar() && QueryTy.getSizeInBits() % Size != 0;198 };199}200 201LegalityPredicate LegalityPredicates::sizeNotPow2(unsigned TypeIdx) {202 return [=](const LegalityQuery &Query) {203 const LLT QueryTy = Query.Types[TypeIdx];204 return QueryTy.isScalar() &&205 !llvm::has_single_bit<uint32_t>(QueryTy.getSizeInBits());206 };207}208 209LegalityPredicate LegalityPredicates::sizeIs(unsigned TypeIdx, unsigned Size) {210 return [=](const LegalityQuery &Query) {211 return Query.Types[TypeIdx].getSizeInBits() == Size;212 };213}214 215LegalityPredicate LegalityPredicates::sameSize(unsigned TypeIdx0,216 unsigned TypeIdx1) {217 return [=](const LegalityQuery &Query) {218 return Query.Types[TypeIdx0].getSizeInBits() ==219 Query.Types[TypeIdx1].getSizeInBits();220 };221}222 223LegalityPredicate LegalityPredicates::memSizeInBytesNotPow2(unsigned MMOIdx) {224 return [=](const LegalityQuery &Query) {225 return !llvm::has_single_bit<uint32_t>(226 Query.MMODescrs[MMOIdx].MemoryTy.getSizeInBytes());227 };228}229 230LegalityPredicate LegalityPredicates::memSizeNotByteSizePow2(unsigned MMOIdx) {231 return [=](const LegalityQuery &Query) {232 const LLT MemTy = Query.MMODescrs[MMOIdx].MemoryTy;233 return !MemTy.isByteSized() ||234 !llvm::has_single_bit<uint32_t>(235 MemTy.getSizeInBytes().getKnownMinValue());236 };237}238 239LegalityPredicate LegalityPredicates::numElementsNotPow2(unsigned TypeIdx) {240 return [=](const LegalityQuery &Query) {241 const LLT QueryTy = Query.Types[TypeIdx];242 return QueryTy.isFixedVector() && !isPowerOf2_32(QueryTy.getNumElements());243 };244}245 246LegalityPredicate LegalityPredicates::atomicOrderingAtLeastOrStrongerThan(247 unsigned MMOIdx, AtomicOrdering Ordering) {248 return [=](const LegalityQuery &Query) {249 return isAtLeastOrStrongerThan(Query.MMODescrs[MMOIdx].Ordering, Ordering);250 };251}252