LegacyLegalizerInfo.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.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. /// This implementation has been deprecated for a long time but it still in use
  17. /// in a few places.
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
  20. #define LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
  21. #include "llvm/ADT/DenseMap.h"
  22. #include "llvm/CodeGen/TargetOpcodes.h"
  23. #include "llvm/Support/LowLevelTypeImpl.h"
  24. #include <unordered_map>
  25. namespace llvm {
  26. struct LegalityQuery;
  27. namespace LegacyLegalizeActions {
  28. enum LegacyLegalizeAction : std::uint8_t {
  29. /// The operation is expected to be selectable directly by the target, and
  30. /// no transformation is necessary.
  31. Legal,
  32. /// The operation should be synthesized from multiple instructions acting on
  33. /// a narrower scalar base-type. For example a 64-bit add might be
  34. /// implemented in terms of 32-bit add-with-carry.
  35. NarrowScalar,
  36. /// The operation should be implemented in terms of a wider scalar
  37. /// base-type. For example a <2 x s8> add could be implemented as a <2
  38. /// x s32> add (ignoring the high bits).
  39. WidenScalar,
  40. /// The (vector) operation should be implemented by splitting it into
  41. /// sub-vectors where the operation is legal. For example a <8 x s64> add
  42. /// might be implemented as 4 separate <2 x s64> adds.
  43. FewerElements,
  44. /// The (vector) operation should be implemented by widening the input
  45. /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
  46. /// rarely legal, but you might perform an <8 x i8> and then only look at
  47. /// the first two results.
  48. MoreElements,
  49. /// Perform the operation on a different, but equivalently sized type.
  50. Bitcast,
  51. /// The operation itself must be expressed in terms of simpler actions on
  52. /// this target. E.g. a SREM replaced by an SDIV and subtraction.
  53. Lower,
  54. /// The operation should be implemented as a call to some kind of runtime
  55. /// support library. For example this usually happens on machines that don't
  56. /// support floating-point operations natively.
  57. Libcall,
  58. /// The target wants to do something special with this combination of
  59. /// operand and type. A callback will be issued when it is needed.
  60. Custom,
  61. /// This operation is completely unsupported on the target. A programming
  62. /// error has occurred.
  63. Unsupported,
  64. /// Sentinel value for when no action was found in the specified table.
  65. NotFound,
  66. };
  67. } // end namespace LegacyLegalizeActions
  68. raw_ostream &operator<<(raw_ostream &OS,
  69. LegacyLegalizeActions::LegacyLegalizeAction Action);
  70. /// Legalization is decided based on an instruction's opcode, which type slot
  71. /// we're considering, and what the existing type is. These aspects are gathered
  72. /// together for convenience in the InstrAspect class.
  73. struct InstrAspect {
  74. unsigned Opcode;
  75. unsigned Idx = 0;
  76. LLT Type;
  77. InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {}
  78. InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
  79. : Opcode(Opcode), Idx(Idx), Type(Type) {}
  80. bool operator==(const InstrAspect &RHS) const {
  81. return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
  82. }
  83. };
  84. /// The result of a query. It either indicates a final answer of Legal or
  85. /// Unsupported or describes an action that must be taken to make an operation
  86. /// more legal.
  87. struct LegacyLegalizeActionStep {
  88. /// The action to take or the final answer.
  89. LegacyLegalizeActions::LegacyLegalizeAction Action;
  90. /// If describing an action, the type index to change. Otherwise zero.
  91. unsigned TypeIdx;
  92. /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
  93. LLT NewType;
  94. LegacyLegalizeActionStep(LegacyLegalizeActions::LegacyLegalizeAction Action,
  95. unsigned TypeIdx, const LLT NewType)
  96. : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
  97. bool operator==(const LegacyLegalizeActionStep &RHS) const {
  98. return std::tie(Action, TypeIdx, NewType) ==
  99. std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
  100. }
  101. };
  102. class LegacyLegalizerInfo {
  103. public:
  104. using SizeAndAction =
  105. std::pair<uint16_t, LegacyLegalizeActions::LegacyLegalizeAction>;
  106. using SizeAndActionsVec = std::vector<SizeAndAction>;
  107. using SizeChangeStrategy =
  108. std::function<SizeAndActionsVec(const SizeAndActionsVec &v)>;
  109. LegacyLegalizerInfo();
  110. static bool needsLegalizingToDifferentSize(
  111. const LegacyLegalizeActions::LegacyLegalizeAction Action) {
  112. using namespace LegacyLegalizeActions;
  113. switch (Action) {
  114. case NarrowScalar:
  115. case WidenScalar:
  116. case FewerElements:
  117. case MoreElements:
  118. case Unsupported:
  119. return true;
  120. default:
  121. return false;
  122. }
  123. }
  124. /// Compute any ancillary tables needed to quickly decide how an operation
  125. /// should be handled. This must be called after all "set*Action"methods but
  126. /// before any query is made or incorrect results may be returned.
  127. void computeTables();
  128. /// More friendly way to set an action for common types that have an LLT
  129. /// representation.
  130. /// The LegacyLegalizeAction must be one for which
  131. /// NeedsLegalizingToDifferentSize returns false.
  132. void setAction(const InstrAspect &Aspect,
  133. LegacyLegalizeActions::LegacyLegalizeAction Action) {
  134. assert(!needsLegalizingToDifferentSize(Action));
  135. TablesInitialized = false;
  136. const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;
  137. if (SpecifiedActions[OpcodeIdx].size() <= Aspect.Idx)
  138. SpecifiedActions[OpcodeIdx].resize(Aspect.Idx + 1);
  139. SpecifiedActions[OpcodeIdx][Aspect.Idx][Aspect.Type] = Action;
  140. }
  141. /// The setAction calls record the non-size-changing legalization actions
  142. /// to take on specificly-sized types. The SizeChangeStrategy defines what
  143. /// to do when the size of the type needs to be changed to reach a legally
  144. /// sized type (i.e., one that was defined through a setAction call).
  145. /// e.g.
  146. /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);
  147. /// setLegalizeScalarToDifferentSizeStrategy(
  148. /// G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
  149. /// will end up defining getAction({G_ADD, 0, T}) to return the following
  150. /// actions for different scalar types T:
  151. /// LLT::scalar(1)..LLT::scalar(31): {WidenScalar, 0, LLT::scalar(32)}
  152. /// LLT::scalar(32): {Legal, 0, LLT::scalar(32)}
  153. /// LLT::scalar(33)..: {NarrowScalar, 0, LLT::scalar(32)}
  154. ///
  155. /// If no SizeChangeAction gets defined, through this function,
  156. /// the default is unsupportedForDifferentSizes.
  157. void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode,
  158. const unsigned TypeIdx,
  159. SizeChangeStrategy S) {
  160. const unsigned OpcodeIdx = Opcode - FirstOp;
  161. if (ScalarSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
  162. ScalarSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
  163. ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
  164. }
  165. /// See also setLegalizeScalarToDifferentSizeStrategy.
  166. /// This function allows to set the SizeChangeStrategy for vector elements.
  167. void setLegalizeVectorElementToDifferentSizeStrategy(const unsigned Opcode,
  168. const unsigned TypeIdx,
  169. SizeChangeStrategy S) {
  170. const unsigned OpcodeIdx = Opcode - FirstOp;
  171. if (VectorElementSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
  172. VectorElementSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
  173. VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
  174. }
  175. /// A SizeChangeStrategy for the common case where legalization for a
  176. /// particular operation consists of only supporting a specific set of type
  177. /// sizes. E.g.
  178. /// setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);
  179. /// setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);
  180. /// setLegalizeScalarToDifferentSizeStrategy(
  181. /// G_DIV, 0, unsupportedForDifferentSizes);
  182. /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,
  183. /// and Unsupported for all other scalar types T.
  184. static SizeAndActionsVec
  185. unsupportedForDifferentSizes(const SizeAndActionsVec &v) {
  186. using namespace LegacyLegalizeActions;
  187. return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
  188. Unsupported);
  189. }
  190. /// A SizeChangeStrategy for the common case where legalization for a
  191. /// particular operation consists of widening the type to a large legal type,
  192. /// unless there is no such type and then instead it should be narrowed to the
  193. /// largest legal type.
  194. static SizeAndActionsVec
  195. widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v) {
  196. using namespace LegacyLegalizeActions;
  197. assert(v.size() > 0 &&
  198. "At least one size that can be legalized towards is needed"
  199. " for this SizeChangeStrategy");
  200. return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
  201. NarrowScalar);
  202. }
  203. static SizeAndActionsVec
  204. widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v) {
  205. using namespace LegacyLegalizeActions;
  206. return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
  207. Unsupported);
  208. }
  209. static SizeAndActionsVec
  210. narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v) {
  211. using namespace LegacyLegalizeActions;
  212. return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
  213. Unsupported);
  214. }
  215. static SizeAndActionsVec
  216. narrowToSmallerAndWidenToSmallest(const SizeAndActionsVec &v) {
  217. using namespace LegacyLegalizeActions;
  218. assert(v.size() > 0 &&
  219. "At least one size that can be legalized towards is needed"
  220. " for this SizeChangeStrategy");
  221. return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
  222. WidenScalar);
  223. }
  224. /// A SizeChangeStrategy for the common case where legalization for a
  225. /// particular vector operation consists of having more elements in the
  226. /// vector, to a type that is legal. Unless there is no such type and then
  227. /// instead it should be legalized towards the widest vector that's still
  228. /// legal. E.g.
  229. /// setAction({G_ADD, LLT::vector(8, 8)}, Legal);
  230. /// setAction({G_ADD, LLT::vector(16, 8)}, Legal);
  231. /// setAction({G_ADD, LLT::vector(2, 32)}, Legal);
  232. /// setAction({G_ADD, LLT::vector(4, 32)}, Legal);
  233. /// setLegalizeVectorElementToDifferentSizeStrategy(
  234. /// G_ADD, 0, moreToWiderTypesAndLessToWidest);
  235. /// will result in the following getAction results:
  236. /// * getAction({G_ADD, LLT::vector(8,8)}) returns
  237. /// (Legal, vector(8,8)).
  238. /// * getAction({G_ADD, LLT::vector(9,8)}) returns
  239. /// (MoreElements, vector(16,8)).
  240. /// * getAction({G_ADD, LLT::vector(8,32)}) returns
  241. /// (FewerElements, vector(4,32)).
  242. static SizeAndActionsVec
  243. moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v) {
  244. using namespace LegacyLegalizeActions;
  245. return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
  246. FewerElements);
  247. }
  248. /// Helper function to implement many typical SizeChangeStrategy functions.
  249. static SizeAndActionsVec increaseToLargerTypesAndDecreaseToLargest(
  250. const SizeAndActionsVec &v,
  251. LegacyLegalizeActions::LegacyLegalizeAction IncreaseAction,
  252. LegacyLegalizeActions::LegacyLegalizeAction DecreaseAction);
  253. /// Helper function to implement many typical SizeChangeStrategy functions.
  254. static SizeAndActionsVec decreaseToSmallerTypesAndIncreaseToSmallest(
  255. const SizeAndActionsVec &v,
  256. LegacyLegalizeActions::LegacyLegalizeAction DecreaseAction,
  257. LegacyLegalizeActions::LegacyLegalizeAction IncreaseAction);
  258. LegacyLegalizeActionStep getAction(const LegalityQuery &Query) const;
  259. unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
  260. private:
  261. /// Determine what action should be taken to legalize the given generic
  262. /// instruction opcode, type-index and type. Requires computeTables to have
  263. /// been called.
  264. ///
  265. /// \returns a pair consisting of the kind of legalization that should be
  266. /// performed and the destination type.
  267. std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
  268. getAspectAction(const InstrAspect &Aspect) const;
  269. /// The SizeAndActionsVec is a representation mapping between all natural
  270. /// numbers and an Action. The natural number represents the bit size of
  271. /// the InstrAspect. For example, for a target with native support for 32-bit
  272. /// and 64-bit additions, you'd express that as:
  273. /// setScalarAction(G_ADD, 0,
  274. /// {{1, WidenScalar}, // bit sizes [ 1, 31[
  275. /// {32, Legal}, // bit sizes [32, 33[
  276. /// {33, WidenScalar}, // bit sizes [33, 64[
  277. /// {64, Legal}, // bit sizes [64, 65[
  278. /// {65, NarrowScalar} // bit sizes [65, +inf[
  279. /// });
  280. /// It may be that only 64-bit pointers are supported on your target:
  281. /// setPointerAction(G_PTR_ADD, 0, LLT:pointer(1),
  282. /// {{1, Unsupported}, // bit sizes [ 1, 63[
  283. /// {64, Legal}, // bit sizes [64, 65[
  284. /// {65, Unsupported}, // bit sizes [65, +inf[
  285. /// });
  286. void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,
  287. const SizeAndActionsVec &SizeAndActions) {
  288. const unsigned OpcodeIdx = Opcode - FirstOp;
  289. SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];
  290. setActions(TypeIndex, Actions, SizeAndActions);
  291. }
  292. void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,
  293. const unsigned AddressSpace,
  294. const SizeAndActionsVec &SizeAndActions) {
  295. const unsigned OpcodeIdx = Opcode - FirstOp;
  296. if (AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace) ==
  297. AddrSpace2PointerActions[OpcodeIdx].end())
  298. AddrSpace2PointerActions[OpcodeIdx][AddressSpace] = {{}};
  299. SmallVector<SizeAndActionsVec, 1> &Actions =
  300. AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace)->second;
  301. setActions(TypeIndex, Actions, SizeAndActions);
  302. }
  303. /// If an operation on a given vector type (say <M x iN>) isn't explicitly
  304. /// specified, we proceed in 2 stages. First we legalize the underlying scalar
  305. /// (so that there's at least one legal vector with that scalar), then we
  306. /// adjust the number of elements in the vector so that it is legal. The
  307. /// desired action in the first step is controlled by this function.
  308. void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,
  309. const SizeAndActionsVec &SizeAndActions) {
  310. unsigned OpcodeIdx = Opcode - FirstOp;
  311. SmallVector<SizeAndActionsVec, 1> &Actions =
  312. ScalarInVectorActions[OpcodeIdx];
  313. setActions(TypeIndex, Actions, SizeAndActions);
  314. }
  315. /// See also setScalarInVectorAction.
  316. /// This function let's you specify the number of elements in a vector that
  317. /// are legal for a legal element size.
  318. void setVectorNumElementAction(const unsigned Opcode,
  319. const unsigned TypeIndex,
  320. const unsigned ElementSize,
  321. const SizeAndActionsVec &SizeAndActions) {
  322. const unsigned OpcodeIdx = Opcode - FirstOp;
  323. if (NumElements2Actions[OpcodeIdx].find(ElementSize) ==
  324. NumElements2Actions[OpcodeIdx].end())
  325. NumElements2Actions[OpcodeIdx][ElementSize] = {{}};
  326. SmallVector<SizeAndActionsVec, 1> &Actions =
  327. NumElements2Actions[OpcodeIdx].find(ElementSize)->second;
  328. setActions(TypeIndex, Actions, SizeAndActions);
  329. }
  330. /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
  331. /// i.e. it's OK if it doesn't start from size 1.
  332. static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
  333. using namespace LegacyLegalizeActions;
  334. #ifndef NDEBUG
  335. // The sizes should be in increasing order
  336. int prev_size = -1;
  337. for(auto SizeAndAction: v) {
  338. assert(SizeAndAction.first > prev_size);
  339. prev_size = SizeAndAction.first;
  340. }
  341. // - for every Widen action, there should be a larger bitsize that
  342. // can be legalized towards (e.g. Legal, Lower, Libcall or Custom
  343. // action).
  344. // - for every Narrow action, there should be a smaller bitsize that
  345. // can be legalized towards.
  346. int SmallestNarrowIdx = -1;
  347. int LargestWidenIdx = -1;
  348. int SmallestLegalizableToSameSizeIdx = -1;
  349. int LargestLegalizableToSameSizeIdx = -1;
  350. for(size_t i=0; i<v.size(); ++i) {
  351. switch (v[i].second) {
  352. case FewerElements:
  353. case NarrowScalar:
  354. if (SmallestNarrowIdx == -1)
  355. SmallestNarrowIdx = i;
  356. break;
  357. case WidenScalar:
  358. case MoreElements:
  359. LargestWidenIdx = i;
  360. break;
  361. case Unsupported:
  362. break;
  363. default:
  364. if (SmallestLegalizableToSameSizeIdx == -1)
  365. SmallestLegalizableToSameSizeIdx = i;
  366. LargestLegalizableToSameSizeIdx = i;
  367. }
  368. }
  369. if (SmallestNarrowIdx != -1) {
  370. assert(SmallestLegalizableToSameSizeIdx != -1);
  371. assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
  372. }
  373. if (LargestWidenIdx != -1)
  374. assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
  375. #endif
  376. }
  377. /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with
  378. /// from size 1.
  379. static void checkFullSizeAndActionsVector(const SizeAndActionsVec& v) {
  380. #ifndef NDEBUG
  381. // Data structure invariant: The first bit size must be size 1.
  382. assert(v.size() >= 1);
  383. assert(v[0].first == 1);
  384. checkPartialSizeAndActionsVector(v);
  385. #endif
  386. }
  387. /// Sets actions for all bit sizes on a particular generic opcode, type
  388. /// index and scalar or pointer type.
  389. void setActions(unsigned TypeIndex,
  390. SmallVector<SizeAndActionsVec, 1> &Actions,
  391. const SizeAndActionsVec &SizeAndActions) {
  392. checkFullSizeAndActionsVector(SizeAndActions);
  393. if (Actions.size() <= TypeIndex)
  394. Actions.resize(TypeIndex + 1);
  395. Actions[TypeIndex] = SizeAndActions;
  396. }
  397. static SizeAndAction findAction(const SizeAndActionsVec &Vec,
  398. const uint32_t Size);
  399. /// Returns the next action needed to get the scalar or pointer type closer
  400. /// to being legal
  401. /// E.g. findLegalAction({G_REM, 13}) should return
  402. /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will
  403. /// probably be called, which should return (Lower, 32).
  404. /// This is assuming the setScalarAction on G_REM was something like:
  405. /// setScalarAction(G_REM, 0,
  406. /// {{1, WidenScalar}, // bit sizes [ 1, 31[
  407. /// {32, Lower}, // bit sizes [32, 33[
  408. /// {33, NarrowScalar} // bit sizes [65, +inf[
  409. /// });
  410. std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
  411. findScalarLegalAction(const InstrAspect &Aspect) const;
  412. /// Returns the next action needed towards legalizing the vector type.
  413. std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
  414. findVectorLegalAction(const InstrAspect &Aspect) const;
  415. static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
  416. static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
  417. // Data structures used temporarily during construction of legality data:
  418. using TypeMap = DenseMap<LLT, LegacyLegalizeActions::LegacyLegalizeAction>;
  419. SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
  420. SmallVector<SizeChangeStrategy, 1>
  421. ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
  422. SmallVector<SizeChangeStrategy, 1>
  423. VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
  424. bool TablesInitialized = false;
  425. // Data structures used by getAction:
  426. SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
  427. SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
  428. std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
  429. AddrSpace2PointerActions[LastOp - FirstOp + 1];
  430. std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
  431. NumElements2Actions[LastOp - FirstOp + 1];
  432. };
  433. } // end namespace llvm
  434. #endif // LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
  435. #ifdef __GNUC__
  436. #pragma GCC diagnostic pop
  437. #endif