VPlanValue.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. //===- VPlanValue.h - Represent Values in Vectorizer Plan -----------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file contains the declarations of the entities induced by Vectorization
  11. /// Plans, e.g. the instructions the VPlan intends to generate if executed.
  12. /// VPlan models the following entities:
  13. /// VPValue VPUser VPDef
  14. /// | |
  15. /// VPInstruction
  16. /// These are documented in docs/VectorizationPlan.rst.
  17. ///
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H
  20. #define LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H
  21. #include "llvm/ADT/DenseMap.h"
  22. #include "llvm/ADT/STLExtras.h"
  23. #include "llvm/ADT/SmallVector.h"
  24. #include "llvm/ADT/TinyPtrVector.h"
  25. #include "llvm/ADT/iterator_range.h"
  26. namespace llvm {
  27. // Forward declarations.
  28. class raw_ostream;
  29. class Value;
  30. class VPDef;
  31. class VPSlotTracker;
  32. class VPUser;
  33. class VPRecipeBase;
  34. class VPWidenMemoryInstructionRecipe;
  35. // This is the base class of the VPlan Def/Use graph, used for modeling the data
  36. // flow into, within and out of the VPlan. VPValues can stand for live-ins
  37. // coming from the input IR, instructions which VPlan will generate if executed
  38. // and live-outs which the VPlan will need to fix accordingly.
  39. class VPValue {
  40. friend class VPBuilder;
  41. friend class VPDef;
  42. friend class VPInstruction;
  43. friend struct VPlanTransforms;
  44. friend class VPBasicBlock;
  45. friend class VPInterleavedAccessInfo;
  46. friend class VPSlotTracker;
  47. friend class VPRecipeBase;
  48. friend class VPWidenMemoryInstructionRecipe;
  49. const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
  50. SmallVector<VPUser *, 1> Users;
  51. protected:
  52. // Hold the underlying Value, if any, attached to this VPValue.
  53. Value *UnderlyingVal;
  54. /// Pointer to the VPDef that defines this VPValue. If it is nullptr, the
  55. /// VPValue is not defined by any recipe modeled in VPlan.
  56. VPDef *Def;
  57. VPValue(const unsigned char SC, Value *UV = nullptr, VPDef *Def = nullptr);
  58. // DESIGN PRINCIPLE: Access to the underlying IR must be strictly limited to
  59. // the front-end and back-end of VPlan so that the middle-end is as
  60. // independent as possible of the underlying IR. We grant access to the
  61. // underlying IR using friendship. In that way, we should be able to use VPlan
  62. // for multiple underlying IRs (Polly?) by providing a new VPlan front-end,
  63. // back-end and analysis information for the new IR.
  64. // Set \p Val as the underlying Value of this VPValue.
  65. void setUnderlyingValue(Value *Val) {
  66. assert(!UnderlyingVal && "Underlying Value is already set.");
  67. UnderlyingVal = Val;
  68. }
  69. public:
  70. /// Return the underlying Value attached to this VPValue.
  71. Value *getUnderlyingValue() { return UnderlyingVal; }
  72. const Value *getUnderlyingValue() const { return UnderlyingVal; }
  73. /// An enumeration for keeping track of the concrete subclass of VPValue that
  74. /// are actually instantiated. Values of this enumeration are kept in the
  75. /// SubclassID field of the VPValue objects. They are used for concrete
  76. /// type identification.
  77. enum {
  78. VPValueSC,
  79. VPVInstructionSC,
  80. VPVMemoryInstructionSC,
  81. VPVReductionSC,
  82. VPVReplicateSC,
  83. VPVWidenSC,
  84. VPVWidenCallSC,
  85. VPVWidenCanonicalIVSC,
  86. VPVWidenGEPSC,
  87. VPVWidenSelectSC,
  88. // Phi-like VPValues. Need to be kept together.
  89. VPVBlendSC,
  90. VPVCanonicalIVPHISC,
  91. VPVFirstOrderRecurrencePHISC,
  92. VPVWidenPHISC,
  93. VPVWidenIntOrFpInductionSC,
  94. VPVPredInstPHI,
  95. VPVReductionPHISC,
  96. };
  97. VPValue(Value *UV = nullptr, VPDef *Def = nullptr)
  98. : VPValue(VPValueSC, UV, Def) {}
  99. VPValue(const VPValue &) = delete;
  100. VPValue &operator=(const VPValue &) = delete;
  101. virtual ~VPValue();
  102. /// \return an ID for the concrete type of this object.
  103. /// This is used to implement the classof checks. This should not be used
  104. /// for any other purpose, as the values may change as LLVM evolves.
  105. unsigned getVPValueID() const { return SubclassID; }
  106. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  107. void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const;
  108. void print(raw_ostream &OS, VPSlotTracker &Tracker) const;
  109. /// Dump the value to stderr (for debugging).
  110. void dump() const;
  111. #endif
  112. unsigned getNumUsers() const { return Users.size(); }
  113. void addUser(VPUser &User) { Users.push_back(&User); }
  114. /// Remove a single \p User from the list of users.
  115. void removeUser(VPUser &User) {
  116. bool Found = false;
  117. // The same user can be added multiple times, e.g. because the same VPValue
  118. // is used twice by the same VPUser. Remove a single one.
  119. erase_if(Users, [&User, &Found](VPUser *Other) {
  120. if (Found)
  121. return false;
  122. if (Other == &User) {
  123. Found = true;
  124. return true;
  125. }
  126. return false;
  127. });
  128. }
  129. typedef SmallVectorImpl<VPUser *>::iterator user_iterator;
  130. typedef SmallVectorImpl<VPUser *>::const_iterator const_user_iterator;
  131. typedef iterator_range<user_iterator> user_range;
  132. typedef iterator_range<const_user_iterator> const_user_range;
  133. user_iterator user_begin() { return Users.begin(); }
  134. const_user_iterator user_begin() const { return Users.begin(); }
  135. user_iterator user_end() { return Users.end(); }
  136. const_user_iterator user_end() const { return Users.end(); }
  137. user_range users() { return user_range(user_begin(), user_end()); }
  138. const_user_range users() const {
  139. return const_user_range(user_begin(), user_end());
  140. }
  141. /// Returns true if the value has more than one unique user.
  142. bool hasMoreThanOneUniqueUser() {
  143. if (getNumUsers() == 0)
  144. return false;
  145. // Check if all users match the first user.
  146. auto Current = std::next(user_begin());
  147. while (Current != user_end() && *user_begin() == *Current)
  148. Current++;
  149. return Current != user_end();
  150. }
  151. void replaceAllUsesWith(VPValue *New);
  152. VPDef *getDef() { return Def; }
  153. const VPDef *getDef() const { return Def; }
  154. /// Returns the underlying IR value, if this VPValue is defined outside the
  155. /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
  156. /// inside a VPlan.
  157. Value *getLiveInIRValue() {
  158. assert(!getDef() &&
  159. "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
  160. return getUnderlyingValue();
  161. }
  162. const Value *getLiveInIRValue() const {
  163. assert(!getDef() &&
  164. "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
  165. return getUnderlyingValue();
  166. }
  167. };
  168. typedef DenseMap<Value *, VPValue *> Value2VPValueTy;
  169. typedef DenseMap<VPValue *, Value *> VPValue2ValueTy;
  170. raw_ostream &operator<<(raw_ostream &OS, const VPValue &V);
  171. /// This class augments VPValue with operands which provide the inverse def-use
  172. /// edges from VPValue's users to their defs.
  173. class VPUser {
  174. public:
  175. /// Subclass identifier (for isa/dyn_cast).
  176. enum class VPUserID {
  177. Recipe,
  178. // TODO: Currently VPUsers are used in VPBlockBase, but in the future the
  179. // only VPUsers should either be recipes or live-outs.
  180. Block
  181. };
  182. private:
  183. SmallVector<VPValue *, 2> Operands;
  184. VPUserID ID;
  185. protected:
  186. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  187. /// Print the operands to \p O.
  188. void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const;
  189. #endif
  190. VPUser(ArrayRef<VPValue *> Operands, VPUserID ID) : ID(ID) {
  191. for (VPValue *Operand : Operands)
  192. addOperand(Operand);
  193. }
  194. VPUser(std::initializer_list<VPValue *> Operands, VPUserID ID)
  195. : VPUser(ArrayRef<VPValue *>(Operands), ID) {}
  196. template <typename IterT>
  197. VPUser(iterator_range<IterT> Operands, VPUserID ID) : ID(ID) {
  198. for (VPValue *Operand : Operands)
  199. addOperand(Operand);
  200. }
  201. public:
  202. VPUser() = delete;
  203. VPUser(const VPUser &) = delete;
  204. VPUser &operator=(const VPUser &) = delete;
  205. virtual ~VPUser() {
  206. for (VPValue *Op : operands())
  207. Op->removeUser(*this);
  208. }
  209. VPUserID getVPUserID() const { return ID; }
  210. void addOperand(VPValue *Operand) {
  211. Operands.push_back(Operand);
  212. Operand->addUser(*this);
  213. }
  214. unsigned getNumOperands() const { return Operands.size(); }
  215. inline VPValue *getOperand(unsigned N) const {
  216. assert(N < Operands.size() && "Operand index out of bounds");
  217. return Operands[N];
  218. }
  219. void setOperand(unsigned I, VPValue *New) {
  220. Operands[I]->removeUser(*this);
  221. Operands[I] = New;
  222. New->addUser(*this);
  223. }
  224. void removeLastOperand() {
  225. VPValue *Op = Operands.pop_back_val();
  226. Op->removeUser(*this);
  227. }
  228. typedef SmallVectorImpl<VPValue *>::iterator operand_iterator;
  229. typedef SmallVectorImpl<VPValue *>::const_iterator const_operand_iterator;
  230. typedef iterator_range<operand_iterator> operand_range;
  231. typedef iterator_range<const_operand_iterator> const_operand_range;
  232. operand_iterator op_begin() { return Operands.begin(); }
  233. const_operand_iterator op_begin() const { return Operands.begin(); }
  234. operand_iterator op_end() { return Operands.end(); }
  235. const_operand_iterator op_end() const { return Operands.end(); }
  236. operand_range operands() { return operand_range(op_begin(), op_end()); }
  237. const_operand_range operands() const {
  238. return const_operand_range(op_begin(), op_end());
  239. }
  240. /// Method to support type inquiry through isa, cast, and dyn_cast.
  241. static inline bool classof(const VPDef *Recipe);
  242. };
  243. /// This class augments a recipe with a set of VPValues defined by the recipe.
  244. /// It allows recipes to define zero, one or multiple VPValues. A VPDef owns
  245. /// the VPValues it defines and is responsible for deleting its defined values.
  246. /// Single-value VPDefs that also inherit from VPValue must make sure to inherit
  247. /// from VPDef before VPValue.
  248. class VPDef {
  249. friend class VPValue;
  250. /// Subclass identifier (for isa/dyn_cast).
  251. const unsigned char SubclassID;
  252. /// The VPValues defined by this VPDef.
  253. TinyPtrVector<VPValue *> DefinedValues;
  254. /// Add \p V as a defined value by this VPDef.
  255. void addDefinedValue(VPValue *V) {
  256. assert(V->getDef() == this &&
  257. "can only add VPValue already linked with this VPDef");
  258. DefinedValues.push_back(V);
  259. }
  260. /// Remove \p V from the values defined by this VPDef. \p V must be a defined
  261. /// value of this VPDef.
  262. void removeDefinedValue(VPValue *V) {
  263. assert(V->getDef() == this &&
  264. "can only remove VPValue linked with this VPDef");
  265. assert(is_contained(DefinedValues, V) &&
  266. "VPValue to remove must be in DefinedValues");
  267. erase_value(DefinedValues, V);
  268. V->Def = nullptr;
  269. }
  270. public:
  271. /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
  272. /// that is actually instantiated. Values of this enumeration are kept in the
  273. /// SubclassID field of the VPRecipeBase objects. They are used for concrete
  274. /// type identification.
  275. using VPRecipeTy = enum {
  276. VPBranchOnMaskSC,
  277. VPInstructionSC,
  278. VPInterleaveSC,
  279. VPReductionSC,
  280. VPReplicateSC,
  281. VPWidenCallSC,
  282. VPWidenCanonicalIVSC,
  283. VPWidenGEPSC,
  284. VPWidenMemoryInstructionSC,
  285. VPWidenSC,
  286. VPWidenSelectSC,
  287. // Phi-like recipes. Need to be kept together.
  288. VPBlendSC,
  289. VPCanonicalIVPHISC,
  290. VPFirstOrderRecurrencePHISC,
  291. VPWidenPHISC,
  292. VPWidenIntOrFpInductionSC,
  293. VPPredInstPHISC,
  294. VPReductionPHISC,
  295. VPFirstPHISC = VPBlendSC,
  296. VPLastPHISC = VPReductionPHISC,
  297. };
  298. VPDef(const unsigned char SC) : SubclassID(SC) {}
  299. virtual ~VPDef() {
  300. for (VPValue *D : make_early_inc_range(DefinedValues)) {
  301. assert(D->Def == this &&
  302. "all defined VPValues should point to the containing VPDef");
  303. assert(D->getNumUsers() == 0 &&
  304. "all defined VPValues should have no more users");
  305. D->Def = nullptr;
  306. delete D;
  307. }
  308. }
  309. /// Returns the only VPValue defined by the VPDef. Can only be called for
  310. /// VPDefs with a single defined value.
  311. VPValue *getVPSingleValue() {
  312. assert(DefinedValues.size() == 1 && "must have exactly one defined value");
  313. assert(DefinedValues[0] && "defined value must be non-null");
  314. return DefinedValues[0];
  315. }
  316. const VPValue *getVPSingleValue() const {
  317. assert(DefinedValues.size() == 1 && "must have exactly one defined value");
  318. assert(DefinedValues[0] && "defined value must be non-null");
  319. return DefinedValues[0];
  320. }
  321. /// Returns the VPValue with index \p I defined by the VPDef.
  322. VPValue *getVPValue(unsigned I) {
  323. assert(DefinedValues[I] && "defined value must be non-null");
  324. return DefinedValues[I];
  325. }
  326. const VPValue *getVPValue(unsigned I) const {
  327. assert(DefinedValues[I] && "defined value must be non-null");
  328. return DefinedValues[I];
  329. }
  330. /// Returns an ArrayRef of the values defined by the VPDef.
  331. ArrayRef<VPValue *> definedValues() { return DefinedValues; }
  332. /// Returns an ArrayRef of the values defined by the VPDef.
  333. ArrayRef<VPValue *> definedValues() const { return DefinedValues; }
  334. /// Returns the number of values defined by the VPDef.
  335. unsigned getNumDefinedValues() const { return DefinedValues.size(); }
  336. /// \return an ID for the concrete type of this object.
  337. /// This is used to implement the classof checks. This should not be used
  338. /// for any other purpose, as the values may change as LLVM evolves.
  339. unsigned getVPDefID() const { return SubclassID; }
  340. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  341. /// Dump the VPDef to stderr (for debugging).
  342. void dump() const;
  343. /// Each concrete VPDef prints itself.
  344. virtual void print(raw_ostream &O, const Twine &Indent,
  345. VPSlotTracker &SlotTracker) const = 0;
  346. #endif
  347. };
  348. class VPlan;
  349. class VPBasicBlock;
  350. /// This class can be used to assign consecutive numbers to all VPValues in a
  351. /// VPlan and allows querying the numbering for printing, similar to the
  352. /// ModuleSlotTracker for IR values.
  353. class VPSlotTracker {
  354. DenseMap<const VPValue *, unsigned> Slots;
  355. unsigned NextSlot = 0;
  356. void assignSlot(const VPValue *V);
  357. void assignSlots(const VPlan &Plan);
  358. public:
  359. VPSlotTracker(const VPlan *Plan = nullptr) {
  360. if (Plan)
  361. assignSlots(*Plan);
  362. }
  363. unsigned getSlot(const VPValue *V) const {
  364. auto I = Slots.find(V);
  365. if (I == Slots.end())
  366. return -1;
  367. return I->second;
  368. }
  369. };
  370. } // namespace llvm
  371. #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H