LegalizerInfo.h 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  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/SmallBitVector.h"
  21. #include "llvm/ADT/SmallVector.h"
  22. #include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h"
  23. #include "llvm/CodeGen/MachineMemOperand.h"
  24. #include "llvm/CodeGen/TargetOpcodes.h"
  25. #include "llvm/MC/MCInstrDesc.h"
  26. #include "llvm/Support/AtomicOrdering.h"
  27. #include "llvm/Support/CommandLine.h"
  28. #include "llvm/Support/LowLevelTypeImpl.h"
  29. #include <cassert>
  30. #include <cstdint>
  31. #include <tuple>
  32. #include <utility>
  33. namespace llvm {
  34. extern cl::opt<bool> DisableGISelLegalityCheck;
  35. class MachineFunction;
  36. class raw_ostream;
  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 (rounded to bytes) that is not a
  286. /// power of 2.
  287. LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx);
  288. /// True iff the specified MMO index has a size that is not an even byte size,
  289. /// or that even byte size is not a power of 2.
  290. LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx);
  291. /// True iff the specified type index is a vector whose element count is not a
  292. /// power of 2.
  293. LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
  294. /// True iff the specified MMO index has at an atomic ordering of at Ordering or
  295. /// stronger.
  296. LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx,
  297. AtomicOrdering Ordering);
  298. } // end namespace LegalityPredicates
  299. namespace LegalizeMutations {
  300. /// Select this specific type for the given type index.
  301. LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
  302. /// Keep the same type as the given type index.
  303. LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
  304. /// Keep the same scalar or element type as the given type index.
  305. LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
  306. /// Keep the same scalar or element type as the given type.
  307. LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
  308. /// Keep the same scalar or element type as \p TypeIdx, but take the number of
  309. /// elements from \p FromTypeIdx.
  310. LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx);
  311. /// Keep the same scalar or element type as \p TypeIdx, but take the number of
  312. /// elements from \p Ty.
  313. LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
  314. /// Change the scalar size or element size to have the same scalar size as type
  315. /// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
  316. /// only changes the size.
  317. LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx);
  318. /// Widen the scalar type or vector element type for the given type index to the
  319. /// next power of 2.
  320. LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
  321. /// Widen the scalar type or vector element type for the given type index to
  322. /// next multiple of \p Size.
  323. LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx,
  324. unsigned Size);
  325. /// Add more elements to the type for the given type index to the next power of
  326. /// 2.
  327. LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
  328. /// Break up the vector type for the given type index into the element type.
  329. LegalizeMutation scalarize(unsigned TypeIdx);
  330. } // end namespace LegalizeMutations
  331. /// A single rule in a legalizer info ruleset.
  332. /// The specified action is chosen when the predicate is true. Where appropriate
  333. /// for the action (e.g. for WidenScalar) the new type is selected using the
  334. /// given mutator.
  335. class LegalizeRule {
  336. LegalityPredicate Predicate;
  337. LegalizeAction Action;
  338. LegalizeMutation Mutation;
  339. public:
  340. LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action,
  341. LegalizeMutation Mutation = nullptr)
  342. : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
  343. /// Test whether the LegalityQuery matches.
  344. bool match(const LegalityQuery &Query) const {
  345. return Predicate(Query);
  346. }
  347. LegalizeAction getAction() const { return Action; }
  348. /// Determine the change to make.
  349. std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
  350. if (Mutation)
  351. return Mutation(Query);
  352. return std::make_pair(0, LLT{});
  353. }
  354. };
  355. class LegalizeRuleSet {
  356. /// When non-zero, the opcode we are an alias of
  357. unsigned AliasOf = 0;
  358. /// If true, there is another opcode that aliases this one
  359. bool IsAliasedByAnother = false;
  360. SmallVector<LegalizeRule, 2> Rules;
  361. #ifndef NDEBUG
  362. /// If bit I is set, this rule set contains a rule that may handle (predicate
  363. /// or perform an action upon (or both)) the type index I. The uncertainty
  364. /// comes from free-form rules executing user-provided lambda functions. We
  365. /// conservatively assume such rules do the right thing and cover all type
  366. /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
  367. /// to be to distinguish such cases from the cases where all type indices are
  368. /// individually handled.
  369. SmallBitVector TypeIdxsCovered{MCOI::OPERAND_LAST_GENERIC -
  370. MCOI::OPERAND_FIRST_GENERIC + 2};
  371. SmallBitVector ImmIdxsCovered{MCOI::OPERAND_LAST_GENERIC_IMM -
  372. MCOI::OPERAND_FIRST_GENERIC_IMM + 2};
  373. #endif
  374. unsigned typeIdx(unsigned TypeIdx) {
  375. assert(TypeIdx <=
  376. (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) &&
  377. "Type Index is out of bounds");
  378. #ifndef NDEBUG
  379. TypeIdxsCovered.set(TypeIdx);
  380. #endif
  381. return TypeIdx;
  382. }
  383. void markAllIdxsAsCovered() {
  384. #ifndef NDEBUG
  385. TypeIdxsCovered.set();
  386. ImmIdxsCovered.set();
  387. #endif
  388. }
  389. void add(const LegalizeRule &Rule) {
  390. assert(AliasOf == 0 &&
  391. "RuleSet is aliased, change the representative opcode instead");
  392. Rules.push_back(Rule);
  393. }
  394. static bool always(const LegalityQuery &) { return true; }
  395. /// Use the given action when the predicate is true.
  396. /// Action should not be an action that requires mutation.
  397. LegalizeRuleSet &actionIf(LegalizeAction Action,
  398. LegalityPredicate Predicate) {
  399. add({Predicate, Action});
  400. return *this;
  401. }
  402. /// Use the given action when the predicate is true.
  403. /// Action should be an action that requires mutation.
  404. LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
  405. LegalizeMutation Mutation) {
  406. add({Predicate, Action, Mutation});
  407. return *this;
  408. }
  409. /// Use the given action when type index 0 is any type in the given list.
  410. /// Action should not be an action that requires mutation.
  411. LegalizeRuleSet &actionFor(LegalizeAction Action,
  412. std::initializer_list<LLT> Types) {
  413. using namespace LegalityPredicates;
  414. return actionIf(Action, typeInSet(typeIdx(0), Types));
  415. }
  416. /// Use the given action when type index 0 is any type in the given list.
  417. /// Action should be an action that requires mutation.
  418. LegalizeRuleSet &actionFor(LegalizeAction Action,
  419. std::initializer_list<LLT> Types,
  420. LegalizeMutation Mutation) {
  421. using namespace LegalityPredicates;
  422. return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
  423. }
  424. /// Use the given action when type indexes 0 and 1 is any type pair in the
  425. /// given list.
  426. /// Action should not be an action that requires mutation.
  427. LegalizeRuleSet &actionFor(LegalizeAction Action,
  428. std::initializer_list<std::pair<LLT, LLT>> Types) {
  429. using namespace LegalityPredicates;
  430. return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
  431. }
  432. /// Use the given action when type indexes 0 and 1 is any type pair in the
  433. /// given list.
  434. /// Action should be an action that requires mutation.
  435. LegalizeRuleSet &actionFor(LegalizeAction Action,
  436. std::initializer_list<std::pair<LLT, LLT>> Types,
  437. LegalizeMutation Mutation) {
  438. using namespace LegalityPredicates;
  439. return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
  440. Mutation);
  441. }
  442. /// Use the given action when type index 0 is any type in the given list and
  443. /// imm index 0 is anything. Action should not be an action that requires
  444. /// mutation.
  445. LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
  446. std::initializer_list<LLT> Types) {
  447. using namespace LegalityPredicates;
  448. immIdx(0); // Inform verifier imm idx 0 is handled.
  449. return actionIf(Action, typeInSet(typeIdx(0), Types));
  450. }
  451. LegalizeRuleSet &actionForTypeWithAnyImm(
  452. LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
  453. using namespace LegalityPredicates;
  454. immIdx(0); // Inform verifier imm idx 0 is handled.
  455. return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
  456. }
  457. /// Use the given action when type indexes 0 and 1 are both in the given list.
  458. /// That is, the type pair is in the cartesian product of the list.
  459. /// Action should not be an action that requires mutation.
  460. LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
  461. std::initializer_list<LLT> Types) {
  462. using namespace LegalityPredicates;
  463. return actionIf(Action, all(typeInSet(typeIdx(0), Types),
  464. typeInSet(typeIdx(1), Types)));
  465. }
  466. /// Use the given action when type indexes 0 and 1 are both in their
  467. /// respective lists.
  468. /// That is, the type pair is in the cartesian product of the lists
  469. /// Action should not be an action that requires mutation.
  470. LegalizeRuleSet &
  471. actionForCartesianProduct(LegalizeAction Action,
  472. std::initializer_list<LLT> Types0,
  473. std::initializer_list<LLT> Types1) {
  474. using namespace LegalityPredicates;
  475. return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
  476. typeInSet(typeIdx(1), Types1)));
  477. }
  478. /// Use the given action when type indexes 0, 1, and 2 are all in their
  479. /// respective lists.
  480. /// That is, the type triple is in the cartesian product of the lists
  481. /// Action should not be an action that requires mutation.
  482. LegalizeRuleSet &actionForCartesianProduct(
  483. LegalizeAction Action, std::initializer_list<LLT> Types0,
  484. std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
  485. using namespace LegalityPredicates;
  486. return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
  487. all(typeInSet(typeIdx(1), Types1),
  488. typeInSet(typeIdx(2), Types2))));
  489. }
  490. public:
  491. LegalizeRuleSet() = default;
  492. bool isAliasedByAnother() { return IsAliasedByAnother; }
  493. void setIsAliasedByAnother() { IsAliasedByAnother = true; }
  494. void aliasTo(unsigned Opcode) {
  495. assert((AliasOf == 0 || AliasOf == Opcode) &&
  496. "Opcode is already aliased to another opcode");
  497. assert(Rules.empty() && "Aliasing will discard rules");
  498. AliasOf = Opcode;
  499. }
  500. unsigned getAlias() const { return AliasOf; }
  501. unsigned immIdx(unsigned ImmIdx) {
  502. assert(ImmIdx <= (MCOI::OPERAND_LAST_GENERIC_IMM -
  503. MCOI::OPERAND_FIRST_GENERIC_IMM) &&
  504. "Imm Index is out of bounds");
  505. #ifndef NDEBUG
  506. ImmIdxsCovered.set(ImmIdx);
  507. #endif
  508. return ImmIdx;
  509. }
  510. /// The instruction is legal if predicate is true.
  511. LegalizeRuleSet &legalIf(LegalityPredicate Predicate) {
  512. // We have no choice but conservatively assume that the free-form
  513. // user-provided Predicate properly handles all type indices:
  514. markAllIdxsAsCovered();
  515. return actionIf(LegalizeAction::Legal, Predicate);
  516. }
  517. /// The instruction is legal when type index 0 is any type in the given list.
  518. LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
  519. return actionFor(LegalizeAction::Legal, Types);
  520. }
  521. /// The instruction is legal when type indexes 0 and 1 is any type pair in the
  522. /// given list.
  523. LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
  524. return actionFor(LegalizeAction::Legal, Types);
  525. }
  526. /// The instruction is legal when type index 0 is any type in the given list
  527. /// and imm index 0 is anything.
  528. LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
  529. markAllIdxsAsCovered();
  530. return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
  531. }
  532. LegalizeRuleSet &legalForTypeWithAnyImm(
  533. std::initializer_list<std::pair<LLT, LLT>> Types) {
  534. markAllIdxsAsCovered();
  535. return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
  536. }
  537. /// The instruction is legal when type indexes 0 and 1 along with the memory
  538. /// size and minimum alignment is any type and size tuple in the given list.
  539. LegalizeRuleSet &legalForTypesWithMemDesc(
  540. std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
  541. TypesAndMemDesc) {
  542. return actionIf(LegalizeAction::Legal,
  543. LegalityPredicates::typePairAndMemDescInSet(
  544. typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
  545. }
  546. /// The instruction is legal when type indexes 0 and 1 are both in the given
  547. /// list. That is, the type pair is in the cartesian product of the list.
  548. LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
  549. return actionForCartesianProduct(LegalizeAction::Legal, Types);
  550. }
  551. /// The instruction is legal when type indexes 0 and 1 are both their
  552. /// respective lists.
  553. LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
  554. std::initializer_list<LLT> Types1) {
  555. return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
  556. }
  557. /// The instruction is legal when type indexes 0, 1, and 2 are both their
  558. /// respective lists.
  559. LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
  560. std::initializer_list<LLT> Types1,
  561. std::initializer_list<LLT> Types2) {
  562. return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
  563. Types2);
  564. }
  565. LegalizeRuleSet &alwaysLegal() {
  566. using namespace LegalizeMutations;
  567. markAllIdxsAsCovered();
  568. return actionIf(LegalizeAction::Legal, always);
  569. }
  570. /// The specified type index is coerced if predicate is true.
  571. LegalizeRuleSet &bitcastIf(LegalityPredicate Predicate,
  572. LegalizeMutation Mutation) {
  573. // We have no choice but conservatively assume that lowering with a
  574. // free-form user provided Predicate properly handles all type indices:
  575. markAllIdxsAsCovered();
  576. return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
  577. }
  578. /// The instruction is lowered.
  579. LegalizeRuleSet &lower() {
  580. using namespace LegalizeMutations;
  581. // We have no choice but conservatively assume that predicate-less lowering
  582. // properly handles all type indices by design:
  583. markAllIdxsAsCovered();
  584. return actionIf(LegalizeAction::Lower, always);
  585. }
  586. /// The instruction is lowered if predicate is true. Keep type index 0 as the
  587. /// same type.
  588. LegalizeRuleSet &lowerIf(LegalityPredicate Predicate) {
  589. using namespace LegalizeMutations;
  590. // We have no choice but conservatively assume that lowering with a
  591. // free-form user provided Predicate properly handles all type indices:
  592. markAllIdxsAsCovered();
  593. return actionIf(LegalizeAction::Lower, Predicate);
  594. }
  595. /// The instruction is lowered if predicate is true.
  596. LegalizeRuleSet &lowerIf(LegalityPredicate Predicate,
  597. LegalizeMutation Mutation) {
  598. // We have no choice but conservatively assume that lowering with a
  599. // free-form user provided Predicate properly handles all type indices:
  600. markAllIdxsAsCovered();
  601. return actionIf(LegalizeAction::Lower, Predicate, Mutation);
  602. }
  603. /// The instruction is lowered when type index 0 is any type in the given
  604. /// list. Keep type index 0 as the same type.
  605. LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
  606. return actionFor(LegalizeAction::Lower, Types);
  607. }
  608. /// The instruction is lowered when type index 0 is any type in the given
  609. /// list.
  610. LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
  611. LegalizeMutation Mutation) {
  612. return actionFor(LegalizeAction::Lower, Types, Mutation);
  613. }
  614. /// The instruction is lowered when type indexes 0 and 1 is any type pair in
  615. /// the given list. Keep type index 0 as the same type.
  616. LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
  617. return actionFor(LegalizeAction::Lower, Types);
  618. }
  619. /// The instruction is lowered when type indexes 0 and 1 is any type pair in
  620. /// the given list.
  621. LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
  622. LegalizeMutation Mutation) {
  623. return actionFor(LegalizeAction::Lower, Types, Mutation);
  624. }
  625. /// The instruction is lowered when type indexes 0 and 1 are both in their
  626. /// respective lists.
  627. LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
  628. std::initializer_list<LLT> Types1) {
  629. using namespace LegalityPredicates;
  630. return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
  631. }
  632. /// The instruction is lowered when when type indexes 0, 1, and 2 are all in
  633. /// their respective lists.
  634. LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
  635. std::initializer_list<LLT> Types1,
  636. std::initializer_list<LLT> Types2) {
  637. using namespace LegalityPredicates;
  638. return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
  639. Types2);
  640. }
  641. /// The instruction is emitted as a library call.
  642. LegalizeRuleSet &libcall() {
  643. using namespace LegalizeMutations;
  644. // We have no choice but conservatively assume that predicate-less lowering
  645. // properly handles all type indices by design:
  646. markAllIdxsAsCovered();
  647. return actionIf(LegalizeAction::Libcall, always);
  648. }
  649. /// Like legalIf, but for the Libcall action.
  650. LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) {
  651. // We have no choice but conservatively assume that a libcall with a
  652. // free-form user provided Predicate properly handles all type indices:
  653. markAllIdxsAsCovered();
  654. return actionIf(LegalizeAction::Libcall, Predicate);
  655. }
  656. LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
  657. return actionFor(LegalizeAction::Libcall, Types);
  658. }
  659. LegalizeRuleSet &
  660. libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
  661. return actionFor(LegalizeAction::Libcall, Types);
  662. }
  663. LegalizeRuleSet &
  664. libcallForCartesianProduct(std::initializer_list<LLT> Types) {
  665. return actionForCartesianProduct(LegalizeAction::Libcall, Types);
  666. }
  667. LegalizeRuleSet &
  668. libcallForCartesianProduct(std::initializer_list<LLT> Types0,
  669. std::initializer_list<LLT> Types1) {
  670. return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
  671. }
  672. /// Widen the scalar to the one selected by the mutation if the predicate is
  673. /// true.
  674. LegalizeRuleSet &widenScalarIf(LegalityPredicate Predicate,
  675. LegalizeMutation Mutation) {
  676. // We have no choice but conservatively assume that an action with a
  677. // free-form user provided Predicate properly handles all type indices:
  678. markAllIdxsAsCovered();
  679. return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
  680. }
  681. /// Narrow the scalar to the one selected by the mutation if the predicate is
  682. /// true.
  683. LegalizeRuleSet &narrowScalarIf(LegalityPredicate Predicate,
  684. LegalizeMutation Mutation) {
  685. // We have no choice but conservatively assume that an action with a
  686. // free-form user provided Predicate properly handles all type indices:
  687. markAllIdxsAsCovered();
  688. return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
  689. }
  690. /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
  691. /// type pair in the given list.
  692. LegalizeRuleSet &
  693. narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
  694. LegalizeMutation Mutation) {
  695. return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
  696. }
  697. /// Add more elements to reach the type selected by the mutation if the
  698. /// predicate is true.
  699. LegalizeRuleSet &moreElementsIf(LegalityPredicate Predicate,
  700. LegalizeMutation Mutation) {
  701. // We have no choice but conservatively assume that an action with a
  702. // free-form user provided Predicate properly handles all type indices:
  703. markAllIdxsAsCovered();
  704. return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
  705. }
  706. /// Remove elements to reach the type selected by the mutation if the
  707. /// predicate is true.
  708. LegalizeRuleSet &fewerElementsIf(LegalityPredicate Predicate,
  709. LegalizeMutation Mutation) {
  710. // We have no choice but conservatively assume that an action with a
  711. // free-form user provided Predicate properly handles all type indices:
  712. markAllIdxsAsCovered();
  713. return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
  714. }
  715. /// The instruction is unsupported.
  716. LegalizeRuleSet &unsupported() {
  717. markAllIdxsAsCovered();
  718. return actionIf(LegalizeAction::Unsupported, always);
  719. }
  720. LegalizeRuleSet &unsupportedIf(LegalityPredicate Predicate) {
  721. return actionIf(LegalizeAction::Unsupported, Predicate);
  722. }
  723. LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
  724. return actionFor(LegalizeAction::Unsupported, Types);
  725. }
  726. LegalizeRuleSet &unsupportedIfMemSizeNotPow2() {
  727. return actionIf(LegalizeAction::Unsupported,
  728. LegalityPredicates::memSizeInBytesNotPow2(0));
  729. }
  730. /// Lower a memory operation if the memory size, rounded to bytes, is not a
  731. /// power of 2. For example, this will not trigger for s1 or s7, but will for
  732. /// s24.
  733. LegalizeRuleSet &lowerIfMemSizeNotPow2() {
  734. return actionIf(LegalizeAction::Lower,
  735. LegalityPredicates::memSizeInBytesNotPow2(0));
  736. }
  737. /// Lower a memory operation if the memory access size is not a round power of
  738. /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
  739. /// what you want (e.g. this will lower s1, s7 and s24).
  740. LegalizeRuleSet &lowerIfMemSizeNotByteSizePow2() {
  741. return actionIf(LegalizeAction::Lower,
  742. LegalityPredicates::memSizeNotByteSizePow2(0));
  743. }
  744. LegalizeRuleSet &customIf(LegalityPredicate Predicate) {
  745. // We have no choice but conservatively assume that a custom action with a
  746. // free-form user provided Predicate properly handles all type indices:
  747. markAllIdxsAsCovered();
  748. return actionIf(LegalizeAction::Custom, Predicate);
  749. }
  750. LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
  751. return actionFor(LegalizeAction::Custom, Types);
  752. }
  753. /// The instruction is custom when type indexes 0 and 1 is any type pair in the
  754. /// given list.
  755. LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
  756. return actionFor(LegalizeAction::Custom, Types);
  757. }
  758. LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
  759. return actionForCartesianProduct(LegalizeAction::Custom, Types);
  760. }
  761. /// The instruction is custom when type indexes 0 and 1 are both in their
  762. /// respective lists.
  763. LegalizeRuleSet &
  764. customForCartesianProduct(std::initializer_list<LLT> Types0,
  765. std::initializer_list<LLT> Types1) {
  766. return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
  767. }
  768. /// The instruction is custom when when type indexes 0, 1, and 2 are all in
  769. /// their respective lists.
  770. LegalizeRuleSet &
  771. customForCartesianProduct(std::initializer_list<LLT> Types0,
  772. std::initializer_list<LLT> Types1,
  773. std::initializer_list<LLT> Types2) {
  774. return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
  775. Types2);
  776. }
  777. /// Unconditionally custom lower.
  778. LegalizeRuleSet &custom() {
  779. return customIf(always);
  780. }
  781. /// Widen the scalar to the next power of two that is at least MinSize.
  782. /// No effect if the type is not a scalar or is a power of two.
  783. LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx,
  784. unsigned MinSize = 0) {
  785. using namespace LegalityPredicates;
  786. return actionIf(
  787. LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
  788. LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
  789. }
  790. /// Widen the scalar to the next multiple of Size. No effect if the
  791. /// type is not a scalar or is a multiple of Size.
  792. LegalizeRuleSet &widenScalarToNextMultipleOf(unsigned TypeIdx,
  793. unsigned Size) {
  794. using namespace LegalityPredicates;
  795. return actionIf(
  796. LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
  797. LegalizeMutations::widenScalarOrEltToNextMultipleOf(TypeIdx, Size));
  798. }
  799. /// Widen the scalar or vector element type to the next power of two that is
  800. /// at least MinSize. No effect if the scalar size is a power of two.
  801. LegalizeRuleSet &widenScalarOrEltToNextPow2(unsigned TypeIdx,
  802. unsigned MinSize = 0) {
  803. using namespace LegalityPredicates;
  804. return actionIf(
  805. LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
  806. LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
  807. }
  808. LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
  809. using namespace LegalityPredicates;
  810. return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
  811. Mutation);
  812. }
  813. LegalizeRuleSet &scalarize(unsigned TypeIdx) {
  814. using namespace LegalityPredicates;
  815. return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
  816. LegalizeMutations::scalarize(TypeIdx));
  817. }
  818. LegalizeRuleSet &scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx) {
  819. using namespace LegalityPredicates;
  820. return actionIf(LegalizeAction::FewerElements,
  821. all(Predicate, isVector(typeIdx(TypeIdx))),
  822. LegalizeMutations::scalarize(TypeIdx));
  823. }
  824. /// Ensure the scalar or element is at least as wide as Ty.
  825. LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
  826. using namespace LegalityPredicates;
  827. using namespace LegalizeMutations;
  828. return actionIf(LegalizeAction::WidenScalar,
  829. scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
  830. changeElementTo(typeIdx(TypeIdx), Ty));
  831. }
  832. /// Ensure the scalar or element is at least as wide as Ty.
  833. LegalizeRuleSet &minScalarOrEltIf(LegalityPredicate Predicate,
  834. unsigned TypeIdx, const LLT Ty) {
  835. using namespace LegalityPredicates;
  836. using namespace LegalizeMutations;
  837. return actionIf(LegalizeAction::WidenScalar,
  838. all(Predicate, scalarOrEltNarrowerThan(
  839. TypeIdx, Ty.getScalarSizeInBits())),
  840. changeElementTo(typeIdx(TypeIdx), Ty));
  841. }
  842. /// Ensure the scalar is at least as wide as Ty.
  843. LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
  844. using namespace LegalityPredicates;
  845. using namespace LegalizeMutations;
  846. return actionIf(LegalizeAction::WidenScalar,
  847. scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
  848. changeTo(typeIdx(TypeIdx), Ty));
  849. }
  850. /// Ensure the scalar is at least as wide as Ty if condition is met.
  851. LegalizeRuleSet &minScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
  852. const LLT Ty) {
  853. using namespace LegalityPredicates;
  854. using namespace LegalizeMutations;
  855. return actionIf(
  856. LegalizeAction::WidenScalar,
  857. [=](const LegalityQuery &Query) {
  858. const LLT QueryTy = Query.Types[TypeIdx];
  859. return QueryTy.isScalar() &&
  860. QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
  861. Predicate(Query);
  862. },
  863. changeTo(typeIdx(TypeIdx), Ty));
  864. }
  865. /// Ensure the scalar is at most as wide as Ty.
  866. LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
  867. using namespace LegalityPredicates;
  868. using namespace LegalizeMutations;
  869. return actionIf(LegalizeAction::NarrowScalar,
  870. scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
  871. changeElementTo(typeIdx(TypeIdx), Ty));
  872. }
  873. /// Ensure the scalar is at most as wide as Ty.
  874. LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
  875. using namespace LegalityPredicates;
  876. using namespace LegalizeMutations;
  877. return actionIf(LegalizeAction::NarrowScalar,
  878. scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
  879. changeTo(typeIdx(TypeIdx), Ty));
  880. }
  881. /// Conditionally limit the maximum size of the scalar.
  882. /// For example, when the maximum size of one type depends on the size of
  883. /// another such as extracting N bits from an M bit container.
  884. LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
  885. const LLT Ty) {
  886. using namespace LegalityPredicates;
  887. using namespace LegalizeMutations;
  888. return actionIf(
  889. LegalizeAction::NarrowScalar,
  890. [=](const LegalityQuery &Query) {
  891. const LLT QueryTy = Query.Types[TypeIdx];
  892. return QueryTy.isScalar() &&
  893. QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
  894. Predicate(Query);
  895. },
  896. changeElementTo(typeIdx(TypeIdx), Ty));
  897. }
  898. /// Limit the range of scalar sizes to MinTy and MaxTy.
  899. LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
  900. const LLT MaxTy) {
  901. assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
  902. return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
  903. }
  904. /// Limit the range of scalar sizes to MinTy and MaxTy.
  905. LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
  906. const LLT MaxTy) {
  907. return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
  908. }
  909. /// Widen the scalar to match the size of another.
  910. LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
  911. typeIdx(TypeIdx);
  912. return widenScalarIf(
  913. [=](const LegalityQuery &Query) {
  914. return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
  915. Query.Types[TypeIdx].getSizeInBits();
  916. },
  917. LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
  918. }
  919. /// Narrow the scalar to match the size of another.
  920. LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
  921. typeIdx(TypeIdx);
  922. return narrowScalarIf(
  923. [=](const LegalityQuery &Query) {
  924. return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
  925. Query.Types[TypeIdx].getSizeInBits();
  926. },
  927. LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
  928. }
  929. /// Change the type \p TypeIdx to have the same scalar size as type \p
  930. /// SameSizeIdx.
  931. LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
  932. return minScalarSameAs(TypeIdx, SameSizeIdx)
  933. .maxScalarSameAs(TypeIdx, SameSizeIdx);
  934. }
  935. /// Conditionally widen the scalar or elt to match the size of another.
  936. LegalizeRuleSet &minScalarEltSameAsIf(LegalityPredicate Predicate,
  937. unsigned TypeIdx, unsigned LargeTypeIdx) {
  938. typeIdx(TypeIdx);
  939. return widenScalarIf(
  940. [=](const LegalityQuery &Query) {
  941. return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
  942. Query.Types[TypeIdx].getScalarSizeInBits() &&
  943. Predicate(Query);
  944. },
  945. [=](const LegalityQuery &Query) {
  946. LLT T = Query.Types[LargeTypeIdx];
  947. if (T.isVector() && T.getElementType().isPointer())
  948. T = T.changeElementType(LLT::scalar(T.getScalarSizeInBits()));
  949. return std::make_pair(TypeIdx, T);
  950. });
  951. }
  952. /// Conditionally narrow the scalar or elt to match the size of another.
  953. LegalizeRuleSet &maxScalarEltSameAsIf(LegalityPredicate Predicate,
  954. unsigned TypeIdx,
  955. unsigned SmallTypeIdx) {
  956. typeIdx(TypeIdx);
  957. return narrowScalarIf(
  958. [=](const LegalityQuery &Query) {
  959. return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
  960. Query.Types[TypeIdx].getScalarSizeInBits() &&
  961. Predicate(Query);
  962. },
  963. [=](const LegalityQuery &Query) {
  964. LLT T = Query.Types[SmallTypeIdx];
  965. return std::make_pair(TypeIdx, T);
  966. });
  967. }
  968. /// Add more elements to the vector to reach the next power of two.
  969. /// No effect if the type is not a vector or the element count is a power of
  970. /// two.
  971. LegalizeRuleSet &moreElementsToNextPow2(unsigned TypeIdx) {
  972. using namespace LegalityPredicates;
  973. return actionIf(LegalizeAction::MoreElements,
  974. numElementsNotPow2(typeIdx(TypeIdx)),
  975. LegalizeMutations::moreElementsToNextPow2(TypeIdx));
  976. }
  977. /// Limit the number of elements in EltTy vectors to at least MinElements.
  978. LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
  979. unsigned MinElements) {
  980. // Mark the type index as covered:
  981. typeIdx(TypeIdx);
  982. return actionIf(
  983. LegalizeAction::MoreElements,
  984. [=](const LegalityQuery &Query) {
  985. LLT VecTy = Query.Types[TypeIdx];
  986. return VecTy.isVector() && VecTy.getElementType() == EltTy &&
  987. VecTy.getNumElements() < MinElements;
  988. },
  989. [=](const LegalityQuery &Query) {
  990. LLT VecTy = Query.Types[TypeIdx];
  991. return std::make_pair(
  992. TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
  993. });
  994. }
  995. /// Set number of elements to nearest larger multiple of NumElts.
  996. LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
  997. unsigned NumElts) {
  998. typeIdx(TypeIdx);
  999. return actionIf(
  1000. LegalizeAction::MoreElements,
  1001. [=](const LegalityQuery &Query) {
  1002. LLT VecTy = Query.Types[TypeIdx];
  1003. return VecTy.isVector() && VecTy.getElementType() == EltTy &&
  1004. (VecTy.getNumElements() % NumElts != 0);
  1005. },
  1006. [=](const LegalityQuery &Query) {
  1007. LLT VecTy = Query.Types[TypeIdx];
  1008. unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
  1009. return std::make_pair(
  1010. TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
  1011. });
  1012. }
  1013. /// Limit the number of elements in EltTy vectors to at most MaxElements.
  1014. LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
  1015. unsigned MaxElements) {
  1016. // Mark the type index as covered:
  1017. typeIdx(TypeIdx);
  1018. return actionIf(
  1019. LegalizeAction::FewerElements,
  1020. [=](const LegalityQuery &Query) {
  1021. LLT VecTy = Query.Types[TypeIdx];
  1022. return VecTy.isVector() && VecTy.getElementType() == EltTy &&
  1023. VecTy.getNumElements() > MaxElements;
  1024. },
  1025. [=](const LegalityQuery &Query) {
  1026. LLT VecTy = Query.Types[TypeIdx];
  1027. LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
  1028. VecTy.getElementType());
  1029. return std::make_pair(TypeIdx, NewTy);
  1030. });
  1031. }
  1032. /// Limit the number of elements for the given vectors to at least MinTy's
  1033. /// number of elements and at most MaxTy's number of elements.
  1034. ///
  1035. /// No effect if the type is not a vector or does not have the same element
  1036. /// type as the constraints.
  1037. /// The element type of MinTy and MaxTy must match.
  1038. LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
  1039. const LLT MaxTy) {
  1040. assert(MinTy.getElementType() == MaxTy.getElementType() &&
  1041. "Expected element types to agree");
  1042. const LLT EltTy = MinTy.getElementType();
  1043. return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
  1044. .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
  1045. }
  1046. /// Express \p EltTy vectors strictly using vectors with \p NumElts elements
  1047. /// (or scalars when \p NumElts equals 1).
  1048. /// First pad with undef elements to nearest larger multiple of \p NumElts.
  1049. /// Then perform split with all sub-instructions having the same type.
  1050. /// Using clampMaxNumElements (non-strict) can result in leftover instruction
  1051. /// with different type (fewer elements then \p NumElts or scalar).
  1052. /// No effect if the type is not a vector.
  1053. LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
  1054. unsigned NumElts) {
  1055. return alignNumElementsTo(TypeIdx, EltTy, NumElts)
  1056. .clampMaxNumElements(TypeIdx, EltTy, NumElts);
  1057. }
  1058. /// Fallback on the previous implementation. This should only be used while
  1059. /// porting a rule.
  1060. LegalizeRuleSet &fallback() {
  1061. add({always, LegalizeAction::UseLegacyRules});
  1062. return *this;
  1063. }
  1064. /// Check if there is no type index which is obviously not handled by the
  1065. /// LegalizeRuleSet in any way at all.
  1066. /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
  1067. bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
  1068. /// Check if there is no imm index which is obviously not handled by the
  1069. /// LegalizeRuleSet in any way at all.
  1070. /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
  1071. bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
  1072. /// Apply the ruleset to the given LegalityQuery.
  1073. LegalizeActionStep apply(const LegalityQuery &Query) const;
  1074. };
  1075. class LegalizerInfo {
  1076. public:
  1077. virtual ~LegalizerInfo() = default;
  1078. const LegacyLegalizerInfo &getLegacyLegalizerInfo() const {
  1079. return LegacyInfo;
  1080. }
  1081. LegacyLegalizerInfo &getLegacyLegalizerInfo() { return LegacyInfo; }
  1082. unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
  1083. unsigned getActionDefinitionsIdx(unsigned Opcode) const;
  1084. /// Perform simple self-diagnostic and assert if there is anything obviously
  1085. /// wrong with the actions set up.
  1086. void verify(const MCInstrInfo &MII) const;
  1087. /// Get the action definitions for the given opcode. Use this to run a
  1088. /// LegalityQuery through the definitions.
  1089. const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
  1090. /// Get the action definition builder for the given opcode. Use this to define
  1091. /// the action definitions.
  1092. ///
  1093. /// It is an error to request an opcode that has already been requested by the
  1094. /// multiple-opcode variant.
  1095. LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
  1096. /// Get the action definition builder for the given set of opcodes. Use this
  1097. /// to define the action definitions for multiple opcodes at once. The first
  1098. /// opcode given will be considered the representative opcode and will hold
  1099. /// the definitions whereas the other opcodes will be configured to refer to
  1100. /// the representative opcode. This lowers memory requirements and very
  1101. /// slightly improves performance.
  1102. ///
  1103. /// It would be very easy to introduce unexpected side-effects as a result of
  1104. /// this aliasing if it were permitted to request different but intersecting
  1105. /// sets of opcodes but that is difficult to keep track of. It is therefore an
  1106. /// error to request the same opcode twice using this API, to request an
  1107. /// opcode that already has definitions, or to use the single-opcode API on an
  1108. /// opcode that has already been requested by this API.
  1109. LegalizeRuleSet &
  1110. getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
  1111. void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
  1112. /// Determine what action should be taken to legalize the described
  1113. /// instruction. Requires computeTables to have been called.
  1114. ///
  1115. /// \returns a description of the next legalization step to perform.
  1116. LegalizeActionStep getAction(const LegalityQuery &Query) const;
  1117. /// Determine what action should be taken to legalize the given generic
  1118. /// instruction.
  1119. ///
  1120. /// \returns a description of the next legalization step to perform.
  1121. LegalizeActionStep getAction(const MachineInstr &MI,
  1122. const MachineRegisterInfo &MRI) const;
  1123. bool isLegal(const LegalityQuery &Query) const {
  1124. return getAction(Query).Action == LegalizeAction::Legal;
  1125. }
  1126. bool isLegalOrCustom(const LegalityQuery &Query) const {
  1127. auto Action = getAction(Query).Action;
  1128. return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
  1129. }
  1130. bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
  1131. bool isLegalOrCustom(const MachineInstr &MI,
  1132. const MachineRegisterInfo &MRI) const;
  1133. /// Called for instructions with the Custom LegalizationAction.
  1134. virtual bool legalizeCustom(LegalizerHelper &Helper,
  1135. MachineInstr &MI) const {
  1136. llvm_unreachable("must implement this if custom action is used");
  1137. }
  1138. /// \returns true if MI is either legal or has been legalized and false if not
  1139. /// legal.
  1140. /// Return true if MI is either legal or has been legalized and false
  1141. /// if not legal.
  1142. virtual bool legalizeIntrinsic(LegalizerHelper &Helper,
  1143. MachineInstr &MI) const {
  1144. return true;
  1145. }
  1146. /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
  1147. /// widening a constant of type SmallTy which targets can override.
  1148. /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
  1149. /// will be the default.
  1150. virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
  1151. private:
  1152. static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
  1153. static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
  1154. LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
  1155. LegacyLegalizerInfo LegacyInfo;
  1156. };
  1157. #ifndef NDEBUG
  1158. /// Checks that MIR is fully legal, returns an illegal instruction if it's not,
  1159. /// nullptr otherwise
  1160. const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
  1161. #endif
  1162. } // end namespace llvm.
  1163. #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
  1164. #ifdef __GNUC__
  1165. #pragma GCC diagnostic pop
  1166. #endif