LegalizerInfo.h 52 KB

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