1 //===- llvm/CodeGen/GlobalISel/LegalizerInfo.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 /// \file 9 /// Interface for Targets to specify which operations they can successfully 10 /// select and how the others should be expanded most efficiently. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H 15 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H 16 17 #include "llvm/ADT/SmallBitVector.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h" 20 #include "llvm/CodeGen/MachineMemOperand.h" 21 #include "llvm/CodeGen/TargetOpcodes.h" 22 #include "llvm/CodeGenTypes/LowLevelType.h" 23 #include "llvm/MC/MCInstrDesc.h" 24 #include "llvm/Support/AtomicOrdering.h" 25 #include "llvm/Support/CommandLine.h" 26 #include <cassert> 27 #include <cstdint> 28 #include <tuple> 29 #include <utility> 30 31 namespace llvm { 32 33 extern cl::opt<bool> DisableGISelLegalityCheck; 34 35 class MachineFunction; 36 class raw_ostream; 37 class LegalizerHelper; 38 class LostDebugLocObserver; 39 class MachineInstr; 40 class MachineRegisterInfo; 41 class MCInstrInfo; 42 43 namespace LegalizeActions { 44 enum LegalizeAction : std::uint8_t { 45 /// The operation is expected to be selectable directly by the target, and 46 /// no transformation is necessary. 47 Legal, 48 49 /// The operation should be synthesized from multiple instructions acting on 50 /// a narrower scalar base-type. For example a 64-bit add might be 51 /// implemented in terms of 32-bit add-with-carry. 52 NarrowScalar, 53 54 /// The operation should be implemented in terms of a wider scalar 55 /// base-type. For example a <2 x s8> add could be implemented as a <2 56 /// x s32> add (ignoring the high bits). 57 WidenScalar, 58 59 /// The (vector) operation should be implemented by splitting it into 60 /// sub-vectors where the operation is legal. For example a <8 x s64> add 61 /// might be implemented as 4 separate <2 x s64> adds. There can be a leftover 62 /// if there are not enough elements for last sub-vector e.g. <7 x s64> add 63 /// will be implemented as 3 separate <2 x s64> adds and one s64 add. Leftover 64 /// types can be avoided by doing MoreElements first. 65 FewerElements, 66 67 /// The (vector) operation should be implemented by widening the input 68 /// vector and ignoring the lanes added by doing so. For example <2 x i8> is 69 /// rarely legal, but you might perform an <8 x i8> and then only look at 70 /// the first two results. 71 MoreElements, 72 73 /// Perform the operation on a different, but equivalently sized type. 74 Bitcast, 75 76 /// The operation itself must be expressed in terms of simpler actions on 77 /// this target. E.g. a SREM replaced by an SDIV and subtraction. 78 Lower, 79 80 /// The operation should be implemented as a call to some kind of runtime 81 /// support library. For example this usually happens on machines that don't 82 /// support floating-point operations natively. 83 Libcall, 84 85 /// The target wants to do something special with this combination of 86 /// operand and type. A callback will be issued when it is needed. 87 Custom, 88 89 /// This operation is completely unsupported on the target. A programming 90 /// error has occurred. 91 Unsupported, 92 93 /// Sentinel value for when no action was found in the specified table. 94 NotFound, 95 96 /// Fall back onto the old rules. 97 /// TODO: Remove this once we've migrated 98 UseLegacyRules, 99 }; 100 } // end namespace LegalizeActions 101 raw_ostream &operator<<(raw_ostream &OS, LegalizeActions::LegalizeAction Action); 102 103 using LegalizeActions::LegalizeAction; 104 105 /// The LegalityQuery object bundles together all the information that's needed 106 /// to decide whether a given operation is legal or not. 107 /// For efficiency, it doesn't make a copy of Types so care must be taken not 108 /// to free it before using the query. 109 struct LegalityQuery { 110 unsigned Opcode; 111 ArrayRef<LLT> Types; 112 113 struct MemDesc { 114 LLT MemoryTy; 115 uint64_t AlignInBits; 116 AtomicOrdering Ordering; 117 118 MemDesc() = default; 119 MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering) 120 : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering) {} 121 MemDesc(const MachineMemOperand &MMO) 122 : MemoryTy(MMO.getMemoryType()), 123 AlignInBits(MMO.getAlign().value() * 8), 124 Ordering(MMO.getSuccessOrdering()) {} 125 }; 126 127 /// Operations which require memory can use this to place requirements on the 128 /// memory type for each MMO. 129 ArrayRef<MemDesc> MMODescrs; 130 131 constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types, 132 const ArrayRef<MemDesc> MMODescrs) 133 : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {} 134 constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types) 135 : LegalityQuery(Opcode, Types, {}) {} 136 137 raw_ostream &print(raw_ostream &OS) const; 138 }; 139 140 /// The result of a query. It either indicates a final answer of Legal or 141 /// Unsupported or describes an action that must be taken to make an operation 142 /// more legal. 143 struct LegalizeActionStep { 144 /// The action to take or the final answer. 145 LegalizeAction Action; 146 /// If describing an action, the type index to change. Otherwise zero. 147 unsigned TypeIdx; 148 /// If describing an action, the new type for TypeIdx. Otherwise LLT{}. 149 LLT NewType; 150 151 LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx, 152 const LLT NewType) 153 : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {} 154 155 LegalizeActionStep(LegacyLegalizeActionStep Step) 156 : TypeIdx(Step.TypeIdx), NewType(Step.NewType) { 157 switch (Step.Action) { 158 case LegacyLegalizeActions::Legal: 159 Action = LegalizeActions::Legal; 160 break; 161 case LegacyLegalizeActions::NarrowScalar: 162 Action = LegalizeActions::NarrowScalar; 163 break; 164 case LegacyLegalizeActions::WidenScalar: 165 Action = LegalizeActions::WidenScalar; 166 break; 167 case LegacyLegalizeActions::FewerElements: 168 Action = LegalizeActions::FewerElements; 169 break; 170 case LegacyLegalizeActions::MoreElements: 171 Action = LegalizeActions::MoreElements; 172 break; 173 case LegacyLegalizeActions::Bitcast: 174 Action = LegalizeActions::Bitcast; 175 break; 176 case LegacyLegalizeActions::Lower: 177 Action = LegalizeActions::Lower; 178 break; 179 case LegacyLegalizeActions::Libcall: 180 Action = LegalizeActions::Libcall; 181 break; 182 case LegacyLegalizeActions::Custom: 183 Action = LegalizeActions::Custom; 184 break; 185 case LegacyLegalizeActions::Unsupported: 186 Action = LegalizeActions::Unsupported; 187 break; 188 case LegacyLegalizeActions::NotFound: 189 Action = LegalizeActions::NotFound; 190 break; 191 } 192 } 193 194 bool operator==(const LegalizeActionStep &RHS) const { 195 return std::tie(Action, TypeIdx, NewType) == 196 std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType); 197 } 198 }; 199 200 using LegalityPredicate = std::function<bool (const LegalityQuery &)>; 201 using LegalizeMutation = 202 std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>; 203 204 namespace LegalityPredicates { 205 struct TypePairAndMemDesc { 206 LLT Type0; 207 LLT Type1; 208 LLT MemTy; 209 uint64_t Align; 210 211 bool operator==(const TypePairAndMemDesc &Other) const { 212 return Type0 == Other.Type0 && Type1 == Other.Type1 && 213 Align == Other.Align && MemTy == Other.MemTy; 214 } 215 216 /// \returns true if this memory access is legal with for the access described 217 /// by \p Other (The alignment is sufficient for the size and result type). 218 bool isCompatible(const TypePairAndMemDesc &Other) const { 219 return Type0 == Other.Type0 && Type1 == Other.Type1 && 220 Align >= Other.Align && 221 // FIXME: This perhaps should be stricter, but the current legality 222 // rules are written only considering the size. 223 MemTy.getSizeInBits() == Other.MemTy.getSizeInBits(); 224 } 225 }; 226 227 /// True iff P is false. 228 template <typename Predicate> Predicate predNot(Predicate P) { 229 return [=](const LegalityQuery &Query) { return !P(Query); }; 230 } 231 232 /// True iff P0 and P1 are true. 233 template<typename Predicate> 234 Predicate all(Predicate P0, Predicate P1) { 235 return [=](const LegalityQuery &Query) { 236 return P0(Query) && P1(Query); 237 }; 238 } 239 /// True iff all given predicates are true. 240 template<typename Predicate, typename... Args> 241 Predicate all(Predicate P0, Predicate P1, Args... args) { 242 return all(all(P0, P1), args...); 243 } 244 245 /// True iff P0 or P1 are true. 246 template<typename Predicate> 247 Predicate any(Predicate P0, Predicate P1) { 248 return [=](const LegalityQuery &Query) { 249 return P0(Query) || P1(Query); 250 }; 251 } 252 /// True iff any given predicates are true. 253 template<typename Predicate, typename... Args> 254 Predicate any(Predicate P0, Predicate P1, Args... args) { 255 return any(any(P0, P1), args...); 256 } 257 258 /// True iff the given type index is the specified type. 259 LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit); 260 /// True iff the given type index is one of the specified types. 261 LegalityPredicate typeInSet(unsigned TypeIdx, 262 std::initializer_list<LLT> TypesInit); 263 264 /// True iff the given type index is not the specified type. 265 inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) { 266 return [=](const LegalityQuery &Query) { 267 return Query.Types[TypeIdx] != Type; 268 }; 269 } 270 271 /// True iff the given types for the given pair of type indexes is one of the 272 /// specified type pairs. 273 LegalityPredicate 274 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, 275 std::initializer_list<std::pair<LLT, LLT>> TypesInit); 276 /// True iff the given types for the given tuple of type indexes is one of the 277 /// specified type tuple. 278 LegalityPredicate 279 typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2, 280 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit); 281 /// True iff the given types for the given pair of type indexes is one of the 282 /// specified type pairs. 283 LegalityPredicate typePairAndMemDescInSet( 284 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, 285 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit); 286 /// True iff the specified type index is a scalar. 287 LegalityPredicate isScalar(unsigned TypeIdx); 288 /// True iff the specified type index is a vector. 289 LegalityPredicate isVector(unsigned TypeIdx); 290 /// True iff the specified type index is a pointer (with any address space). 291 LegalityPredicate isPointer(unsigned TypeIdx); 292 /// True iff the specified type index is a pointer with the specified address 293 /// space. 294 LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace); 295 /// True iff the specified type index is a vector of pointers (with any address 296 /// space). 297 LegalityPredicate isPointerVector(unsigned TypeIdx); 298 299 /// True if the type index is a vector with element type \p EltTy 300 LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy); 301 302 /// True iff the specified type index is a scalar that's narrower than the given 303 /// size. 304 LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size); 305 306 /// True iff the specified type index is a scalar that's wider than the given 307 /// size. 308 LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size); 309 310 /// True iff the specified type index is a scalar or vector with an element type 311 /// that's narrower than the given size. 312 LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size); 313 314 /// True iff the specified type index is a scalar or a vector with an element 315 /// type that's wider than the given size. 316 LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size); 317 318 /// True iff the specified type index is a scalar whose size is not a multiple 319 /// of Size. 320 LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size); 321 322 /// True iff the specified type index is a scalar whose size is not a power of 323 /// 2. 324 LegalityPredicate sizeNotPow2(unsigned TypeIdx); 325 326 /// True iff the specified type index is a scalar or vector whose element size 327 /// is not a power of 2. 328 LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx); 329 330 /// True if the total bitwidth of the specified type index is \p Size bits. 331 LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size); 332 333 /// True iff the specified type indices are both the same bit size. 334 LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1); 335 336 /// True iff the first type index has a larger total bit size than second type 337 /// index. 338 LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1); 339 340 /// True iff the first type index has a smaller total bit size than second type 341 /// index. 342 LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1); 343 344 /// True iff the specified MMO index has a size (rounded to bytes) that is not a 345 /// power of 2. 346 LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx); 347 348 /// True iff the specified MMO index has a size that is not an even byte size, 349 /// or that even byte size is not a power of 2. 350 LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx); 351 352 /// True iff the specified type index is a vector whose element count is not a 353 /// power of 2. 354 LegalityPredicate numElementsNotPow2(unsigned TypeIdx); 355 /// True iff the specified MMO index has at an atomic ordering of at Ordering or 356 /// stronger. 357 LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, 358 AtomicOrdering Ordering); 359 } // end namespace LegalityPredicates 360 361 namespace LegalizeMutations { 362 /// Select this specific type for the given type index. 363 LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty); 364 365 /// Keep the same type as the given type index. 366 LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx); 367 368 /// Keep the same scalar or element type as the given type index. 369 LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx); 370 371 /// Keep the same scalar or element type as the given type. 372 LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty); 373 374 /// Keep the same scalar or element type as \p TypeIdx, but take the number of 375 /// elements from \p FromTypeIdx. 376 LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx); 377 378 /// Keep the same scalar or element type as \p TypeIdx, but take the number of 379 /// elements from \p Ty. 380 LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty); 381 382 /// Change the scalar size or element size to have the same scalar size as type 383 /// index \p FromIndex. Unlike changeElementTo, this discards pointer types and 384 /// only changes the size. 385 LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx); 386 387 /// Widen the scalar type or vector element type for the given type index to the 388 /// next power of 2. 389 LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0); 390 391 /// Widen the scalar type or vector element type for the given type index to 392 /// next multiple of \p Size. 393 LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx, 394 unsigned Size); 395 396 /// Add more elements to the type for the given type index to the next power of 397 /// 2. 398 LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0); 399 /// Break up the vector type for the given type index into the element type. 400 LegalizeMutation scalarize(unsigned TypeIdx); 401 } // end namespace LegalizeMutations 402 403 /// A single rule in a legalizer info ruleset. 404 /// The specified action is chosen when the predicate is true. Where appropriate 405 /// for the action (e.g. for WidenScalar) the new type is selected using the 406 /// given mutator. 407 class LegalizeRule { 408 LegalityPredicate Predicate; 409 LegalizeAction Action; 410 LegalizeMutation Mutation; 411 412 public: 413 LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action, 414 LegalizeMutation Mutation = nullptr) 415 : Predicate(Predicate), Action(Action), Mutation(Mutation) {} 416 417 /// Test whether the LegalityQuery matches. 418 bool match(const LegalityQuery &Query) const { 419 return Predicate(Query); 420 } 421 422 LegalizeAction getAction() const { return Action; } 423 424 /// Determine the change to make. 425 std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const { 426 if (Mutation) 427 return Mutation(Query); 428 return std::make_pair(0, LLT{}); 429 } 430 }; 431 432 class LegalizeRuleSet { 433 /// When non-zero, the opcode we are an alias of 434 unsigned AliasOf = 0; 435 /// If true, there is another opcode that aliases this one 436 bool IsAliasedByAnother = false; 437 SmallVector<LegalizeRule, 2> Rules; 438 439 #ifndef NDEBUG 440 /// If bit I is set, this rule set contains a rule that may handle (predicate 441 /// or perform an action upon (or both)) the type index I. The uncertainty 442 /// comes from free-form rules executing user-provided lambda functions. We 443 /// conservatively assume such rules do the right thing and cover all type 444 /// indices. The bitset is intentionally 1 bit wider than it absolutely needs 445 /// to be to distinguish such cases from the cases where all type indices are 446 /// individually handled. 447 SmallBitVector TypeIdxsCovered{MCOI::OPERAND_LAST_GENERIC - 448 MCOI::OPERAND_FIRST_GENERIC + 2}; 449 SmallBitVector ImmIdxsCovered{MCOI::OPERAND_LAST_GENERIC_IMM - 450 MCOI::OPERAND_FIRST_GENERIC_IMM + 2}; 451 #endif 452 453 unsigned typeIdx(unsigned TypeIdx) { 454 assert(TypeIdx <= 455 (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) && 456 "Type Index is out of bounds"); 457 #ifndef NDEBUG 458 TypeIdxsCovered.set(TypeIdx); 459 #endif 460 return TypeIdx; 461 } 462 463 void markAllIdxsAsCovered() { 464 #ifndef NDEBUG 465 TypeIdxsCovered.set(); 466 ImmIdxsCovered.set(); 467 #endif 468 } 469 470 void add(const LegalizeRule &Rule) { 471 assert(AliasOf == 0 && 472 "RuleSet is aliased, change the representative opcode instead"); 473 Rules.push_back(Rule); 474 } 475 476 static bool always(const LegalityQuery &) { return true; } 477 478 /// Use the given action when the predicate is true. 479 /// Action should not be an action that requires mutation. 480 LegalizeRuleSet &actionIf(LegalizeAction Action, 481 LegalityPredicate Predicate) { 482 add({Predicate, Action}); 483 return *this; 484 } 485 /// Use the given action when the predicate is true. 486 /// Action should be an action that requires mutation. 487 LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate, 488 LegalizeMutation Mutation) { 489 add({Predicate, Action, Mutation}); 490 return *this; 491 } 492 /// Use the given action when type index 0 is any type in the given list. 493 /// Action should not be an action that requires mutation. 494 LegalizeRuleSet &actionFor(LegalizeAction Action, 495 std::initializer_list<LLT> Types) { 496 using namespace LegalityPredicates; 497 return actionIf(Action, typeInSet(typeIdx(0), Types)); 498 } 499 /// Use the given action when type index 0 is any type in the given list. 500 /// Action should be an action that requires mutation. 501 LegalizeRuleSet &actionFor(LegalizeAction Action, 502 std::initializer_list<LLT> Types, 503 LegalizeMutation Mutation) { 504 using namespace LegalityPredicates; 505 return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation); 506 } 507 /// Use the given action when type indexes 0 and 1 is any type pair in the 508 /// given list. 509 /// Action should not be an action that requires mutation. 510 LegalizeRuleSet &actionFor(LegalizeAction Action, 511 std::initializer_list<std::pair<LLT, LLT>> Types) { 512 using namespace LegalityPredicates; 513 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types)); 514 } 515 516 LegalizeRuleSet & 517 actionFor(LegalizeAction Action, 518 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) { 519 using namespace LegalityPredicates; 520 return actionIf(Action, 521 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types)); 522 } 523 524 /// Use the given action when type indexes 0 and 1 is any type pair in the 525 /// given list. 526 /// Action should be an action that requires mutation. 527 LegalizeRuleSet &actionFor(LegalizeAction Action, 528 std::initializer_list<std::pair<LLT, LLT>> Types, 529 LegalizeMutation Mutation) { 530 using namespace LegalityPredicates; 531 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types), 532 Mutation); 533 } 534 /// Use the given action when type index 0 is any type in the given list and 535 /// imm index 0 is anything. Action should not be an action that requires 536 /// mutation. 537 LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action, 538 std::initializer_list<LLT> Types) { 539 using namespace LegalityPredicates; 540 immIdx(0); // Inform verifier imm idx 0 is handled. 541 return actionIf(Action, typeInSet(typeIdx(0), Types)); 542 } 543 544 LegalizeRuleSet &actionForTypeWithAnyImm( 545 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) { 546 using namespace LegalityPredicates; 547 immIdx(0); // Inform verifier imm idx 0 is handled. 548 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types)); 549 } 550 551 /// Use the given action when type indexes 0 and 1 are both in the given list. 552 /// That is, the type pair is in the cartesian product of the list. 553 /// Action should not be an action that requires mutation. 554 LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action, 555 std::initializer_list<LLT> Types) { 556 using namespace LegalityPredicates; 557 return actionIf(Action, all(typeInSet(typeIdx(0), Types), 558 typeInSet(typeIdx(1), Types))); 559 } 560 /// Use the given action when type indexes 0 and 1 are both in their 561 /// respective lists. 562 /// That is, the type pair is in the cartesian product of the lists 563 /// Action should not be an action that requires mutation. 564 LegalizeRuleSet & 565 actionForCartesianProduct(LegalizeAction Action, 566 std::initializer_list<LLT> Types0, 567 std::initializer_list<LLT> Types1) { 568 using namespace LegalityPredicates; 569 return actionIf(Action, all(typeInSet(typeIdx(0), Types0), 570 typeInSet(typeIdx(1), Types1))); 571 } 572 /// Use the given action when type indexes 0, 1, and 2 are all in their 573 /// respective lists. 574 /// That is, the type triple is in the cartesian product of the lists 575 /// Action should not be an action that requires mutation. 576 LegalizeRuleSet &actionForCartesianProduct( 577 LegalizeAction Action, std::initializer_list<LLT> Types0, 578 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) { 579 using namespace LegalityPredicates; 580 return actionIf(Action, all(typeInSet(typeIdx(0), Types0), 581 all(typeInSet(typeIdx(1), Types1), 582 typeInSet(typeIdx(2), Types2)))); 583 } 584 585 public: 586 LegalizeRuleSet() = default; 587 588 bool isAliasedByAnother() { return IsAliasedByAnother; } 589 void setIsAliasedByAnother() { IsAliasedByAnother = true; } 590 void aliasTo(unsigned Opcode) { 591 assert((AliasOf == 0 || AliasOf == Opcode) && 592 "Opcode is already aliased to another opcode"); 593 assert(Rules.empty() && "Aliasing will discard rules"); 594 AliasOf = Opcode; 595 } 596 unsigned getAlias() const { return AliasOf; } 597 598 unsigned immIdx(unsigned ImmIdx) { 599 assert(ImmIdx <= (MCOI::OPERAND_LAST_GENERIC_IMM - 600 MCOI::OPERAND_FIRST_GENERIC_IMM) && 601 "Imm Index is out of bounds"); 602 #ifndef NDEBUG 603 ImmIdxsCovered.set(ImmIdx); 604 #endif 605 return ImmIdx; 606 } 607 608 /// The instruction is legal if predicate is true. 609 LegalizeRuleSet &legalIf(LegalityPredicate Predicate) { 610 // We have no choice but conservatively assume that the free-form 611 // user-provided Predicate properly handles all type indices: 612 markAllIdxsAsCovered(); 613 return actionIf(LegalizeAction::Legal, Predicate); 614 } 615 /// The instruction is legal when type index 0 is any type in the given list. 616 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) { 617 return actionFor(LegalizeAction::Legal, Types); 618 } 619 LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) { 620 if (!Pred) 621 return *this; 622 return actionFor(LegalizeAction::Legal, Types); 623 } 624 /// The instruction is legal when type indexes 0 and 1 is any type pair in the 625 /// given list. 626 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) { 627 return actionFor(LegalizeAction::Legal, Types); 628 } 629 LegalizeRuleSet &legalFor(bool Pred, 630 std::initializer_list<std::pair<LLT, LLT>> Types) { 631 if (!Pred) 632 return *this; 633 return actionFor(LegalizeAction::Legal, Types); 634 } 635 LegalizeRuleSet & 636 legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) { 637 if (!Pred) 638 return *this; 639 return actionFor(LegalizeAction::Legal, Types); 640 } 641 /// The instruction is legal when type index 0 is any type in the given list 642 /// and imm index 0 is anything. 643 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) { 644 markAllIdxsAsCovered(); 645 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types); 646 } 647 648 LegalizeRuleSet &legalForTypeWithAnyImm( 649 std::initializer_list<std::pair<LLT, LLT>> Types) { 650 markAllIdxsAsCovered(); 651 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types); 652 } 653 654 /// The instruction is legal when type indexes 0 and 1 along with the memory 655 /// size and minimum alignment is any type and size tuple in the given list. 656 LegalizeRuleSet &legalForTypesWithMemDesc( 657 std::initializer_list<LegalityPredicates::TypePairAndMemDesc> 658 TypesAndMemDesc) { 659 return actionIf(LegalizeAction::Legal, 660 LegalityPredicates::typePairAndMemDescInSet( 661 typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc)); 662 } 663 /// The instruction is legal when type indexes 0 and 1 are both in the given 664 /// list. That is, the type pair is in the cartesian product of the list. 665 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) { 666 return actionForCartesianProduct(LegalizeAction::Legal, Types); 667 } 668 /// The instruction is legal when type indexes 0 and 1 are both their 669 /// respective lists. 670 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0, 671 std::initializer_list<LLT> Types1) { 672 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1); 673 } 674 /// The instruction is legal when type indexes 0, 1, and 2 are both their 675 /// respective lists. 676 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0, 677 std::initializer_list<LLT> Types1, 678 std::initializer_list<LLT> Types2) { 679 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1, 680 Types2); 681 } 682 683 LegalizeRuleSet &alwaysLegal() { 684 using namespace LegalizeMutations; 685 markAllIdxsAsCovered(); 686 return actionIf(LegalizeAction::Legal, always); 687 } 688 689 /// The specified type index is coerced if predicate is true. 690 LegalizeRuleSet &bitcastIf(LegalityPredicate Predicate, 691 LegalizeMutation Mutation) { 692 // We have no choice but conservatively assume that lowering with a 693 // free-form user provided Predicate properly handles all type indices: 694 markAllIdxsAsCovered(); 695 return actionIf(LegalizeAction::Bitcast, Predicate, Mutation); 696 } 697 698 /// The instruction is lowered. 699 LegalizeRuleSet &lower() { 700 using namespace LegalizeMutations; 701 // We have no choice but conservatively assume that predicate-less lowering 702 // properly handles all type indices by design: 703 markAllIdxsAsCovered(); 704 return actionIf(LegalizeAction::Lower, always); 705 } 706 /// The instruction is lowered if predicate is true. Keep type index 0 as the 707 /// same type. 708 LegalizeRuleSet &lowerIf(LegalityPredicate Predicate) { 709 using namespace LegalizeMutations; 710 // We have no choice but conservatively assume that lowering with a 711 // free-form user provided Predicate properly handles all type indices: 712 markAllIdxsAsCovered(); 713 return actionIf(LegalizeAction::Lower, Predicate); 714 } 715 /// The instruction is lowered if predicate is true. 716 LegalizeRuleSet &lowerIf(LegalityPredicate Predicate, 717 LegalizeMutation Mutation) { 718 // We have no choice but conservatively assume that lowering with a 719 // free-form user provided Predicate properly handles all type indices: 720 markAllIdxsAsCovered(); 721 return actionIf(LegalizeAction::Lower, Predicate, Mutation); 722 } 723 /// The instruction is lowered when type index 0 is any type in the given 724 /// list. Keep type index 0 as the same type. 725 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) { 726 return actionFor(LegalizeAction::Lower, Types); 727 } 728 /// The instruction is lowered when type index 0 is any type in the given 729 /// list. 730 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types, 731 LegalizeMutation Mutation) { 732 return actionFor(LegalizeAction::Lower, Types, Mutation); 733 } 734 /// The instruction is lowered when type indexes 0 and 1 is any type pair in 735 /// the given list. Keep type index 0 as the same type. 736 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) { 737 return actionFor(LegalizeAction::Lower, Types); 738 } 739 /// The instruction is lowered when type indexes 0 and 1 is any type pair in 740 /// the given list. 741 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types, 742 LegalizeMutation Mutation) { 743 return actionFor(LegalizeAction::Lower, Types, Mutation); 744 } 745 /// The instruction is lowered when type indexes 0 and 1 are both in their 746 /// respective lists. 747 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0, 748 std::initializer_list<LLT> Types1) { 749 using namespace LegalityPredicates; 750 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1); 751 } 752 /// The instruction is lowered when type indexes 0, 1, and 2 are all in 753 /// their respective lists. 754 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0, 755 std::initializer_list<LLT> Types1, 756 std::initializer_list<LLT> Types2) { 757 using namespace LegalityPredicates; 758 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1, 759 Types2); 760 } 761 762 /// The instruction is emitted as a library call. 763 LegalizeRuleSet &libcall() { 764 using namespace LegalizeMutations; 765 // We have no choice but conservatively assume that predicate-less lowering 766 // properly handles all type indices by design: 767 markAllIdxsAsCovered(); 768 return actionIf(LegalizeAction::Libcall, always); 769 } 770 771 /// Like legalIf, but for the Libcall action. 772 LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) { 773 // We have no choice but conservatively assume that a libcall with a 774 // free-form user provided Predicate properly handles all type indices: 775 markAllIdxsAsCovered(); 776 return actionIf(LegalizeAction::Libcall, Predicate); 777 } 778 LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) { 779 return actionFor(LegalizeAction::Libcall, Types); 780 } 781 LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) { 782 if (!Pred) 783 return *this; 784 return actionFor(LegalizeAction::Libcall, Types); 785 } 786 LegalizeRuleSet & 787 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) { 788 return actionFor(LegalizeAction::Libcall, Types); 789 } 790 LegalizeRuleSet & 791 libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) { 792 if (!Pred) 793 return *this; 794 return actionFor(LegalizeAction::Libcall, Types); 795 } 796 LegalizeRuleSet & 797 libcallForCartesianProduct(std::initializer_list<LLT> Types) { 798 return actionForCartesianProduct(LegalizeAction::Libcall, Types); 799 } 800 LegalizeRuleSet & 801 libcallForCartesianProduct(std::initializer_list<LLT> Types0, 802 std::initializer_list<LLT> Types1) { 803 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1); 804 } 805 806 /// Widen the scalar to the one selected by the mutation if the predicate is 807 /// true. 808 LegalizeRuleSet &widenScalarIf(LegalityPredicate Predicate, 809 LegalizeMutation Mutation) { 810 // We have no choice but conservatively assume that an action with a 811 // free-form user provided Predicate properly handles all type indices: 812 markAllIdxsAsCovered(); 813 return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation); 814 } 815 /// Narrow the scalar to the one selected by the mutation if the predicate is 816 /// true. 817 LegalizeRuleSet &narrowScalarIf(LegalityPredicate Predicate, 818 LegalizeMutation Mutation) { 819 // We have no choice but conservatively assume that an action with a 820 // free-form user provided Predicate properly handles all type indices: 821 markAllIdxsAsCovered(); 822 return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation); 823 } 824 /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any 825 /// type pair in the given list. 826 LegalizeRuleSet & 827 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types, 828 LegalizeMutation Mutation) { 829 return actionFor(LegalizeAction::NarrowScalar, Types, Mutation); 830 } 831 832 /// Add more elements to reach the type selected by the mutation if the 833 /// predicate is true. 834 LegalizeRuleSet &moreElementsIf(LegalityPredicate Predicate, 835 LegalizeMutation Mutation) { 836 // We have no choice but conservatively assume that an action with a 837 // free-form user provided Predicate properly handles all type indices: 838 markAllIdxsAsCovered(); 839 return actionIf(LegalizeAction::MoreElements, Predicate, Mutation); 840 } 841 /// Remove elements to reach the type selected by the mutation if the 842 /// predicate is true. 843 LegalizeRuleSet &fewerElementsIf(LegalityPredicate Predicate, 844 LegalizeMutation Mutation) { 845 // We have no choice but conservatively assume that an action with a 846 // free-form user provided Predicate properly handles all type indices: 847 markAllIdxsAsCovered(); 848 return actionIf(LegalizeAction::FewerElements, Predicate, Mutation); 849 } 850 851 /// The instruction is unsupported. 852 LegalizeRuleSet &unsupported() { 853 markAllIdxsAsCovered(); 854 return actionIf(LegalizeAction::Unsupported, always); 855 } 856 LegalizeRuleSet &unsupportedIf(LegalityPredicate Predicate) { 857 return actionIf(LegalizeAction::Unsupported, Predicate); 858 } 859 860 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) { 861 return actionFor(LegalizeAction::Unsupported, Types); 862 } 863 864 LegalizeRuleSet &unsupportedIfMemSizeNotPow2() { 865 return actionIf(LegalizeAction::Unsupported, 866 LegalityPredicates::memSizeInBytesNotPow2(0)); 867 } 868 869 /// Lower a memory operation if the memory size, rounded to bytes, is not a 870 /// power of 2. For example, this will not trigger for s1 or s7, but will for 871 /// s24. 872 LegalizeRuleSet &lowerIfMemSizeNotPow2() { 873 return actionIf(LegalizeAction::Lower, 874 LegalityPredicates::memSizeInBytesNotPow2(0)); 875 } 876 877 /// Lower a memory operation if the memory access size is not a round power of 878 /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely 879 /// what you want (e.g. this will lower s1, s7 and s24). 880 LegalizeRuleSet &lowerIfMemSizeNotByteSizePow2() { 881 return actionIf(LegalizeAction::Lower, 882 LegalityPredicates::memSizeNotByteSizePow2(0)); 883 } 884 885 LegalizeRuleSet &customIf(LegalityPredicate Predicate) { 886 // We have no choice but conservatively assume that a custom action with a 887 // free-form user provided Predicate properly handles all type indices: 888 markAllIdxsAsCovered(); 889 return actionIf(LegalizeAction::Custom, Predicate); 890 } 891 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) { 892 return actionFor(LegalizeAction::Custom, Types); 893 } 894 LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) { 895 if (!Pred) 896 return *this; 897 return actionFor(LegalizeAction::Custom, Types); 898 } 899 900 /// The instruction is custom when type indexes 0 and 1 is any type pair in 901 /// the given list. 902 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) { 903 return actionFor(LegalizeAction::Custom, Types); 904 } 905 LegalizeRuleSet &customFor(bool Pred, 906 std::initializer_list<std::pair<LLT, LLT>> Types) { 907 if (!Pred) 908 return *this; 909 return actionFor(LegalizeAction::Custom, Types); 910 } 911 912 LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) { 913 return actionForCartesianProduct(LegalizeAction::Custom, Types); 914 } 915 /// The instruction is custom when type indexes 0 and 1 are both in their 916 /// respective lists. 917 LegalizeRuleSet & 918 customForCartesianProduct(std::initializer_list<LLT> Types0, 919 std::initializer_list<LLT> Types1) { 920 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1); 921 } 922 /// The instruction is custom when type indexes 0, 1, and 2 are all in 923 /// their respective lists. 924 LegalizeRuleSet & 925 customForCartesianProduct(std::initializer_list<LLT> Types0, 926 std::initializer_list<LLT> Types1, 927 std::initializer_list<LLT> Types2) { 928 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1, 929 Types2); 930 } 931 932 /// Unconditionally custom lower. 933 LegalizeRuleSet &custom() { 934 return customIf(always); 935 } 936 937 /// Widen the scalar to the next power of two that is at least MinSize. 938 /// No effect if the type is a power of two, except if the type is smaller 939 /// than MinSize, or if the type is a vector type. 940 LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx, 941 unsigned MinSize = 0) { 942 using namespace LegalityPredicates; 943 return actionIf( 944 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)), 945 LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize)); 946 } 947 948 /// Widen the scalar to the next multiple of Size. No effect if the 949 /// type is not a scalar or is a multiple of Size. 950 LegalizeRuleSet &widenScalarToNextMultipleOf(unsigned TypeIdx, 951 unsigned Size) { 952 using namespace LegalityPredicates; 953 return actionIf( 954 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size), 955 LegalizeMutations::widenScalarOrEltToNextMultipleOf(TypeIdx, Size)); 956 } 957 958 /// Widen the scalar or vector element type to the next power of two that is 959 /// at least MinSize. No effect if the scalar size is a power of two. 960 LegalizeRuleSet &widenScalarOrEltToNextPow2(unsigned TypeIdx, 961 unsigned MinSize = 0) { 962 using namespace LegalityPredicates; 963 return actionIf( 964 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)), 965 LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize)); 966 } 967 968 /// Widen the scalar or vector element type to the next power of two that is 969 /// at least MinSize. No effect if the scalar size is a power of two. 970 LegalizeRuleSet &widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx, 971 unsigned MinSize = 0) { 972 using namespace LegalityPredicates; 973 return actionIf( 974 LegalizeAction::WidenScalar, 975 any(scalarOrEltNarrowerThan(TypeIdx, MinSize), 976 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))), 977 LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize)); 978 } 979 980 LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) { 981 using namespace LegalityPredicates; 982 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)), 983 Mutation); 984 } 985 986 LegalizeRuleSet &scalarize(unsigned TypeIdx) { 987 using namespace LegalityPredicates; 988 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)), 989 LegalizeMutations::scalarize(TypeIdx)); 990 } 991 992 LegalizeRuleSet &scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx) { 993 using namespace LegalityPredicates; 994 return actionIf(LegalizeAction::FewerElements, 995 all(Predicate, isVector(typeIdx(TypeIdx))), 996 LegalizeMutations::scalarize(TypeIdx)); 997 } 998 999 /// Ensure the scalar or element is at least as wide as Ty. 1000 LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) { 1001 using namespace LegalityPredicates; 1002 using namespace LegalizeMutations; 1003 return actionIf(LegalizeAction::WidenScalar, 1004 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()), 1005 changeElementTo(typeIdx(TypeIdx), Ty)); 1006 } 1007 1008 /// Ensure the scalar or element is at least as wide as Ty. 1009 LegalizeRuleSet &minScalarOrEltIf(LegalityPredicate Predicate, 1010 unsigned TypeIdx, const LLT Ty) { 1011 using namespace LegalityPredicates; 1012 using namespace LegalizeMutations; 1013 return actionIf(LegalizeAction::WidenScalar, 1014 all(Predicate, scalarOrEltNarrowerThan( 1015 TypeIdx, Ty.getScalarSizeInBits())), 1016 changeElementTo(typeIdx(TypeIdx), Ty)); 1017 } 1018 1019 /// Ensure the vector size is at least as wide as VectorSize by promoting the 1020 /// element. 1021 LegalizeRuleSet &widenVectorEltsToVectorMinSize(unsigned TypeIdx, 1022 unsigned VectorSize) { 1023 using namespace LegalityPredicates; 1024 using namespace LegalizeMutations; 1025 return actionIf( 1026 LegalizeAction::WidenScalar, 1027 [=](const LegalityQuery &Query) { 1028 const LLT VecTy = Query.Types[TypeIdx]; 1029 return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize; 1030 }, 1031 [=](const LegalityQuery &Query) { 1032 const LLT VecTy = Query.Types[TypeIdx]; 1033 unsigned NumElts = VecTy.getNumElements(); 1034 unsigned MinSize = VectorSize / NumElts; 1035 LLT NewTy = LLT::fixed_vector(NumElts, LLT::scalar(MinSize)); 1036 return std::make_pair(TypeIdx, NewTy); 1037 }); 1038 } 1039 1040 /// Ensure the scalar is at least as wide as Ty. 1041 LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) { 1042 using namespace LegalityPredicates; 1043 using namespace LegalizeMutations; 1044 return actionIf(LegalizeAction::WidenScalar, 1045 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()), 1046 changeTo(typeIdx(TypeIdx), Ty)); 1047 } 1048 LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) { 1049 if (!Pred) 1050 return *this; 1051 return minScalar(TypeIdx, Ty); 1052 } 1053 1054 /// Ensure the scalar is at least as wide as Ty if condition is met. 1055 LegalizeRuleSet &minScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, 1056 const LLT Ty) { 1057 using namespace LegalityPredicates; 1058 using namespace LegalizeMutations; 1059 return actionIf( 1060 LegalizeAction::WidenScalar, 1061 [=](const LegalityQuery &Query) { 1062 const LLT QueryTy = Query.Types[TypeIdx]; 1063 return QueryTy.isScalar() && 1064 QueryTy.getSizeInBits() < Ty.getSizeInBits() && 1065 Predicate(Query); 1066 }, 1067 changeTo(typeIdx(TypeIdx), Ty)); 1068 } 1069 1070 /// Ensure the scalar is at most as wide as Ty. 1071 LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) { 1072 using namespace LegalityPredicates; 1073 using namespace LegalizeMutations; 1074 return actionIf(LegalizeAction::NarrowScalar, 1075 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()), 1076 changeElementTo(typeIdx(TypeIdx), Ty)); 1077 } 1078 1079 /// Ensure the scalar is at most as wide as Ty. 1080 LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) { 1081 using namespace LegalityPredicates; 1082 using namespace LegalizeMutations; 1083 return actionIf(LegalizeAction::NarrowScalar, 1084 scalarWiderThan(TypeIdx, Ty.getSizeInBits()), 1085 changeTo(typeIdx(TypeIdx), Ty)); 1086 } 1087 1088 /// Conditionally limit the maximum size of the scalar. 1089 /// For example, when the maximum size of one type depends on the size of 1090 /// another such as extracting N bits from an M bit container. 1091 LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, 1092 const LLT Ty) { 1093 using namespace LegalityPredicates; 1094 using namespace LegalizeMutations; 1095 return actionIf( 1096 LegalizeAction::NarrowScalar, 1097 [=](const LegalityQuery &Query) { 1098 const LLT QueryTy = Query.Types[TypeIdx]; 1099 return QueryTy.isScalar() && 1100 QueryTy.getSizeInBits() > Ty.getSizeInBits() && 1101 Predicate(Query); 1102 }, 1103 changeElementTo(typeIdx(TypeIdx), Ty)); 1104 } 1105 1106 /// Limit the range of scalar sizes to MinTy and MaxTy. 1107 LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy, 1108 const LLT MaxTy) { 1109 assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types"); 1110 return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy); 1111 } 1112 1113 LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy, 1114 const LLT MaxTy) { 1115 if (!Pred) 1116 return *this; 1117 return clampScalar(TypeIdx, MinTy, MaxTy); 1118 } 1119 1120 /// Limit the range of scalar sizes to MinTy and MaxTy. 1121 LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy, 1122 const LLT MaxTy) { 1123 return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy); 1124 } 1125 1126 /// Widen the scalar to match the size of another. 1127 LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) { 1128 typeIdx(TypeIdx); 1129 return actionIf( 1130 LegalizeAction::WidenScalar, 1131 [=](const LegalityQuery &Query) { 1132 return Query.Types[LargeTypeIdx].getScalarSizeInBits() > 1133 Query.Types[TypeIdx].getSizeInBits(); 1134 }, 1135 LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx)); 1136 } 1137 1138 /// Narrow the scalar to match the size of another. 1139 LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) { 1140 typeIdx(TypeIdx); 1141 return actionIf( 1142 LegalizeAction::NarrowScalar, 1143 [=](const LegalityQuery &Query) { 1144 return Query.Types[NarrowTypeIdx].getScalarSizeInBits() < 1145 Query.Types[TypeIdx].getSizeInBits(); 1146 }, 1147 LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx)); 1148 } 1149 1150 /// Change the type \p TypeIdx to have the same scalar size as type \p 1151 /// SameSizeIdx. 1152 LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) { 1153 return minScalarSameAs(TypeIdx, SameSizeIdx) 1154 .maxScalarSameAs(TypeIdx, SameSizeIdx); 1155 } 1156 1157 /// Conditionally widen the scalar or elt to match the size of another. 1158 LegalizeRuleSet &minScalarEltSameAsIf(LegalityPredicate Predicate, 1159 unsigned TypeIdx, unsigned LargeTypeIdx) { 1160 typeIdx(TypeIdx); 1161 return widenScalarIf( 1162 [=](const LegalityQuery &Query) { 1163 return Query.Types[LargeTypeIdx].getScalarSizeInBits() > 1164 Query.Types[TypeIdx].getScalarSizeInBits() && 1165 Predicate(Query); 1166 }, 1167 [=](const LegalityQuery &Query) { 1168 LLT T = Query.Types[LargeTypeIdx]; 1169 if (T.isPointerVector()) 1170 T = T.changeElementType(LLT::scalar(T.getScalarSizeInBits())); 1171 return std::make_pair(TypeIdx, T); 1172 }); 1173 } 1174 1175 /// Conditionally narrow the scalar or elt to match the size of another. 1176 LegalizeRuleSet &maxScalarEltSameAsIf(LegalityPredicate Predicate, 1177 unsigned TypeIdx, 1178 unsigned SmallTypeIdx) { 1179 typeIdx(TypeIdx); 1180 return narrowScalarIf( 1181 [=](const LegalityQuery &Query) { 1182 return Query.Types[SmallTypeIdx].getScalarSizeInBits() < 1183 Query.Types[TypeIdx].getScalarSizeInBits() && 1184 Predicate(Query); 1185 }, 1186 [=](const LegalityQuery &Query) { 1187 LLT T = Query.Types[SmallTypeIdx]; 1188 return std::make_pair(TypeIdx, T); 1189 }); 1190 } 1191 1192 /// Add more elements to the vector to reach the next power of two. 1193 /// No effect if the type is not a vector or the element count is a power of 1194 /// two. 1195 LegalizeRuleSet &moreElementsToNextPow2(unsigned TypeIdx) { 1196 using namespace LegalityPredicates; 1197 return actionIf(LegalizeAction::MoreElements, 1198 numElementsNotPow2(typeIdx(TypeIdx)), 1199 LegalizeMutations::moreElementsToNextPow2(TypeIdx)); 1200 } 1201 1202 /// Limit the number of elements in EltTy vectors to at least MinElements. 1203 LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy, 1204 unsigned MinElements) { 1205 // Mark the type index as covered: 1206 typeIdx(TypeIdx); 1207 return actionIf( 1208 LegalizeAction::MoreElements, 1209 [=](const LegalityQuery &Query) { 1210 LLT VecTy = Query.Types[TypeIdx]; 1211 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy && 1212 VecTy.getNumElements() < MinElements; 1213 }, 1214 [=](const LegalityQuery &Query) { 1215 LLT VecTy = Query.Types[TypeIdx]; 1216 return std::make_pair( 1217 TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType())); 1218 }); 1219 } 1220 1221 /// Set number of elements to nearest larger multiple of NumElts. 1222 LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy, 1223 unsigned NumElts) { 1224 typeIdx(TypeIdx); 1225 return actionIf( 1226 LegalizeAction::MoreElements, 1227 [=](const LegalityQuery &Query) { 1228 LLT VecTy = Query.Types[TypeIdx]; 1229 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy && 1230 (VecTy.getNumElements() % NumElts != 0); 1231 }, 1232 [=](const LegalityQuery &Query) { 1233 LLT VecTy = Query.Types[TypeIdx]; 1234 unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts); 1235 return std::make_pair( 1236 TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType())); 1237 }); 1238 } 1239 1240 /// Limit the number of elements in EltTy vectors to at most MaxElements. 1241 LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy, 1242 unsigned MaxElements) { 1243 // Mark the type index as covered: 1244 typeIdx(TypeIdx); 1245 return actionIf( 1246 LegalizeAction::FewerElements, 1247 [=](const LegalityQuery &Query) { 1248 LLT VecTy = Query.Types[TypeIdx]; 1249 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy && 1250 VecTy.getNumElements() > MaxElements; 1251 }, 1252 [=](const LegalityQuery &Query) { 1253 LLT VecTy = Query.Types[TypeIdx]; 1254 LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements), 1255 VecTy.getElementType()); 1256 return std::make_pair(TypeIdx, NewTy); 1257 }); 1258 } 1259 /// Limit the number of elements for the given vectors to at least MinTy's 1260 /// number of elements and at most MaxTy's number of elements. 1261 /// 1262 /// No effect if the type is not a vector or does not have the same element 1263 /// type as the constraints. 1264 /// The element type of MinTy and MaxTy must match. 1265 LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy, 1266 const LLT MaxTy) { 1267 assert(MinTy.getElementType() == MaxTy.getElementType() && 1268 "Expected element types to agree"); 1269 1270 assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) && 1271 "Unexpected scalable vectors"); 1272 1273 const LLT EltTy = MinTy.getElementType(); 1274 return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements()) 1275 .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements()); 1276 } 1277 1278 /// Express \p EltTy vectors strictly using vectors with \p NumElts elements 1279 /// (or scalars when \p NumElts equals 1). 1280 /// First pad with undef elements to nearest larger multiple of \p NumElts. 1281 /// Then perform split with all sub-instructions having the same type. 1282 /// Using clampMaxNumElements (non-strict) can result in leftover instruction 1283 /// with different type (fewer elements then \p NumElts or scalar). 1284 /// No effect if the type is not a vector. 1285 LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy, 1286 unsigned NumElts) { 1287 return alignNumElementsTo(TypeIdx, EltTy, NumElts) 1288 .clampMaxNumElements(TypeIdx, EltTy, NumElts); 1289 } 1290 1291 /// Fallback on the previous implementation. This should only be used while 1292 /// porting a rule. 1293 LegalizeRuleSet &fallback() { 1294 add({always, LegalizeAction::UseLegacyRules}); 1295 return *this; 1296 } 1297 1298 /// Check if there is no type index which is obviously not handled by the 1299 /// LegalizeRuleSet in any way at all. 1300 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set. 1301 bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const; 1302 /// Check if there is no imm index which is obviously not handled by the 1303 /// LegalizeRuleSet in any way at all. 1304 /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set. 1305 bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const; 1306 1307 /// Apply the ruleset to the given LegalityQuery. 1308 LegalizeActionStep apply(const LegalityQuery &Query) const; 1309 }; 1310 1311 class LegalizerInfo { 1312 public: 1313 virtual ~LegalizerInfo() = default; 1314 1315 const LegacyLegalizerInfo &getLegacyLegalizerInfo() const { 1316 return LegacyInfo; 1317 } 1318 LegacyLegalizerInfo &getLegacyLegalizerInfo() { return LegacyInfo; } 1319 1320 unsigned getOpcodeIdxForOpcode(unsigned Opcode) const; 1321 unsigned getActionDefinitionsIdx(unsigned Opcode) const; 1322 1323 /// Perform simple self-diagnostic and assert if there is anything obviously 1324 /// wrong with the actions set up. 1325 void verify(const MCInstrInfo &MII) const; 1326 1327 /// Get the action definitions for the given opcode. Use this to run a 1328 /// LegalityQuery through the definitions. 1329 const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const; 1330 1331 /// Get the action definition builder for the given opcode. Use this to define 1332 /// the action definitions. 1333 /// 1334 /// It is an error to request an opcode that has already been requested by the 1335 /// multiple-opcode variant. 1336 LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode); 1337 1338 /// Get the action definition builder for the given set of opcodes. Use this 1339 /// to define the action definitions for multiple opcodes at once. The first 1340 /// opcode given will be considered the representative opcode and will hold 1341 /// the definitions whereas the other opcodes will be configured to refer to 1342 /// the representative opcode. This lowers memory requirements and very 1343 /// slightly improves performance. 1344 /// 1345 /// It would be very easy to introduce unexpected side-effects as a result of 1346 /// this aliasing if it were permitted to request different but intersecting 1347 /// sets of opcodes but that is difficult to keep track of. It is therefore an 1348 /// error to request the same opcode twice using this API, to request an 1349 /// opcode that already has definitions, or to use the single-opcode API on an 1350 /// opcode that has already been requested by this API. 1351 LegalizeRuleSet & 1352 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes); 1353 void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom); 1354 1355 /// Determine what action should be taken to legalize the described 1356 /// instruction. Requires computeTables to have been called. 1357 /// 1358 /// \returns a description of the next legalization step to perform. 1359 LegalizeActionStep getAction(const LegalityQuery &Query) const; 1360 1361 /// Determine what action should be taken to legalize the given generic 1362 /// instruction. 1363 /// 1364 /// \returns a description of the next legalization step to perform. 1365 LegalizeActionStep getAction(const MachineInstr &MI, 1366 const MachineRegisterInfo &MRI) const; 1367 1368 bool isLegal(const LegalityQuery &Query) const { 1369 return getAction(Query).Action == LegalizeAction::Legal; 1370 } 1371 1372 bool isLegalOrCustom(const LegalityQuery &Query) const { 1373 auto Action = getAction(Query).Action; 1374 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom; 1375 } 1376 1377 bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const; 1378 bool isLegalOrCustom(const MachineInstr &MI, 1379 const MachineRegisterInfo &MRI) const; 1380 1381 /// Called for instructions with the Custom LegalizationAction. 1382 virtual bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, 1383 LostDebugLocObserver &LocObserver) const { 1384 llvm_unreachable("must implement this if custom action is used"); 1385 } 1386 1387 /// \returns true if MI is either legal or has been legalized and false if not 1388 /// legal. 1389 /// Return true if MI is either legal or has been legalized and false 1390 /// if not legal. 1391 virtual bool legalizeIntrinsic(LegalizerHelper &Helper, 1392 MachineInstr &MI) const { 1393 return true; 1394 } 1395 1396 /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while 1397 /// widening a constant of type SmallTy which targets can override. 1398 /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which 1399 /// will be the default. 1400 virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const; 1401 1402 private: 1403 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START; 1404 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END; 1405 1406 LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1]; 1407 LegacyLegalizerInfo LegacyInfo; 1408 }; 1409 1410 #ifndef NDEBUG 1411 /// Checks that MIR is fully legal, returns an illegal instruction if it's not, 1412 /// nullptr otherwise 1413 const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF); 1414 #endif 1415 1416 } // end namespace llvm. 1417 1418 #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H 1419