VPlanValue.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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. VPVWidenGEPSC,
  86. VPVWidenSelectSC,
  87. };
  88. VPValue(Value *UV = nullptr, VPDef *Def = nullptr)
  89. : VPValue(VPValueSC, UV, Def) {}
  90. VPValue(const VPValue &) = delete;
  91. VPValue &operator=(const VPValue &) = delete;
  92. virtual ~VPValue();
  93. /// \return an ID for the concrete type of this object.
  94. /// This is used to implement the classof checks. This should not be used
  95. /// for any other purpose, as the values may change as LLVM evolves.
  96. unsigned getVPValueID() const { return SubclassID; }
  97. void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const;
  98. void print(raw_ostream &OS, VPSlotTracker &Tracker) const;
  99. /// Dump the value to stderr (for debugging).
  100. void dump() const;
  101. unsigned getNumUsers() const { return Users.size(); }
  102. void addUser(VPUser &User) { Users.push_back(&User); }
  103. /// Remove a single \p User from the list of users.
  104. void removeUser(VPUser &User) {
  105. bool Found = false;
  106. // The same user can be added multiple times, e.g. because the same VPValue
  107. // is used twice by the same VPUser. Remove a single one.
  108. erase_if(Users, [&User, &Found](VPUser *Other) {
  109. if (Found)
  110. return false;
  111. if (Other == &User) {
  112. Found = true;
  113. return true;
  114. }
  115. return false;
  116. });
  117. }
  118. typedef SmallVectorImpl<VPUser *>::iterator user_iterator;
  119. typedef SmallVectorImpl<VPUser *>::const_iterator const_user_iterator;
  120. typedef iterator_range<user_iterator> user_range;
  121. typedef iterator_range<const_user_iterator> const_user_range;
  122. user_iterator user_begin() { return Users.begin(); }
  123. const_user_iterator user_begin() const { return Users.begin(); }
  124. user_iterator user_end() { return Users.end(); }
  125. const_user_iterator user_end() const { return Users.end(); }
  126. user_range users() { return user_range(user_begin(), user_end()); }
  127. const_user_range users() const {
  128. return const_user_range(user_begin(), user_end());
  129. }
  130. /// Returns true if the value has more than one unique user.
  131. bool hasMoreThanOneUniqueUser() {
  132. if (getNumUsers() == 0)
  133. return false;
  134. // Check if all users match the first user.
  135. auto Current = std::next(user_begin());
  136. while (Current != user_end() && *user_begin() == *Current)
  137. Current++;
  138. return Current != user_end();
  139. }
  140. void replaceAllUsesWith(VPValue *New);
  141. VPDef *getDef() { return Def; }
  142. /// Returns the underlying IR value, if this VPValue is defined outside the
  143. /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
  144. /// inside a VPlan.
  145. Value *getLiveInIRValue() {
  146. assert(!getDef() &&
  147. "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
  148. return getUnderlyingValue();
  149. }
  150. };
  151. typedef DenseMap<Value *, VPValue *> Value2VPValueTy;
  152. typedef DenseMap<VPValue *, Value *> VPValue2ValueTy;
  153. raw_ostream &operator<<(raw_ostream &OS, const VPValue &V);
  154. /// This class augments VPValue with operands which provide the inverse def-use
  155. /// edges from VPValue's users to their defs.
  156. class VPUser {
  157. SmallVector<VPValue *, 2> Operands;
  158. protected:
  159. /// Print the operands to \p O.
  160. void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const;
  161. public:
  162. VPUser() {}
  163. VPUser(ArrayRef<VPValue *> Operands) {
  164. for (VPValue *Operand : Operands)
  165. addOperand(Operand);
  166. }
  167. VPUser(std::initializer_list<VPValue *> Operands)
  168. : VPUser(ArrayRef<VPValue *>(Operands)) {}
  169. template <typename IterT> VPUser(iterator_range<IterT> Operands) {
  170. for (VPValue *Operand : Operands)
  171. addOperand(Operand);
  172. }
  173. VPUser(const VPUser &) = delete;
  174. VPUser &operator=(const VPUser &) = delete;
  175. virtual ~VPUser() {
  176. for (VPValue *Op : operands())
  177. Op->removeUser(*this);
  178. }
  179. void addOperand(VPValue *Operand) {
  180. Operands.push_back(Operand);
  181. Operand->addUser(*this);
  182. }
  183. unsigned getNumOperands() const { return Operands.size(); }
  184. inline VPValue *getOperand(unsigned N) const {
  185. assert(N < Operands.size() && "Operand index out of bounds");
  186. return Operands[N];
  187. }
  188. void setOperand(unsigned I, VPValue *New) {
  189. Operands[I]->removeUser(*this);
  190. Operands[I] = New;
  191. New->addUser(*this);
  192. }
  193. typedef SmallVectorImpl<VPValue *>::iterator operand_iterator;
  194. typedef SmallVectorImpl<VPValue *>::const_iterator const_operand_iterator;
  195. typedef iterator_range<operand_iterator> operand_range;
  196. typedef iterator_range<const_operand_iterator> const_operand_range;
  197. operand_iterator op_begin() { return Operands.begin(); }
  198. const_operand_iterator op_begin() const { return Operands.begin(); }
  199. operand_iterator op_end() { return Operands.end(); }
  200. const_operand_iterator op_end() const { return Operands.end(); }
  201. operand_range operands() { return operand_range(op_begin(), op_end()); }
  202. const_operand_range operands() const {
  203. return const_operand_range(op_begin(), op_end());
  204. }
  205. /// Method to support type inquiry through isa, cast, and dyn_cast.
  206. static inline bool classof(const VPDef *Recipe);
  207. };
  208. /// This class augments a recipe with a set of VPValues defined by the recipe.
  209. /// It allows recipes to define zero, one or multiple VPValues. A VPDef owns
  210. /// the VPValues it defines and is responsible for deleting its defined values.
  211. /// Single-value VPDefs that also inherit from VPValue must make sure to inherit
  212. /// from VPDef before VPValue.
  213. class VPDef {
  214. friend class VPValue;
  215. /// Subclass identifier (for isa/dyn_cast).
  216. const unsigned char SubclassID;
  217. /// The VPValues defined by this VPDef.
  218. TinyPtrVector<VPValue *> DefinedValues;
  219. /// Add \p V as a defined value by this VPDef.
  220. void addDefinedValue(VPValue *V) {
  221. assert(V->getDef() == this &&
  222. "can only add VPValue already linked with this VPDef");
  223. DefinedValues.push_back(V);
  224. }
  225. /// Remove \p V from the values defined by this VPDef. \p V must be a defined
  226. /// value of this VPDef.
  227. void removeDefinedValue(VPValue *V) {
  228. assert(V->getDef() == this &&
  229. "can only remove VPValue linked with this VPDef");
  230. assert(is_contained(DefinedValues, V) &&
  231. "VPValue to remove must be in DefinedValues");
  232. erase_value(DefinedValues, V);
  233. V->Def = nullptr;
  234. }
  235. public:
  236. /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
  237. /// that is actually instantiated. Values of this enumeration are kept in the
  238. /// SubclassID field of the VPRecipeBase objects. They are used for concrete
  239. /// type identification.
  240. using VPRecipeTy = enum {
  241. VPBlendSC,
  242. VPBranchOnMaskSC,
  243. VPInstructionSC,
  244. VPInterleaveSC,
  245. VPPredInstPHISC,
  246. VPReductionSC,
  247. VPReplicateSC,
  248. VPWidenCallSC,
  249. VPWidenCanonicalIVSC,
  250. VPWidenGEPSC,
  251. VPWidenIntOrFpInductionSC,
  252. VPWidenMemoryInstructionSC,
  253. VPWidenPHISC,
  254. VPWidenSC,
  255. VPWidenSelectSC
  256. };
  257. VPDef(const unsigned char SC) : SubclassID(SC) {}
  258. virtual ~VPDef() {
  259. for (VPValue *D : make_early_inc_range(DefinedValues)) {
  260. assert(D->Def == this &&
  261. "all defined VPValues should point to the containing VPDef");
  262. assert(D->getNumUsers() == 0 &&
  263. "all defined VPValues should have no more users");
  264. D->Def = nullptr;
  265. delete D;
  266. }
  267. }
  268. /// Returns the VPValue with index \p I defined by the VPDef.
  269. VPValue *getVPValue(unsigned I = 0) {
  270. assert(DefinedValues[I] && "defined value must be non-null");
  271. return DefinedValues[I];
  272. }
  273. const VPValue *getVPValue(unsigned I = 0) const {
  274. assert(DefinedValues[I] && "defined value must be non-null");
  275. return DefinedValues[I];
  276. }
  277. /// Returns an ArrayRef of the values defined by the VPDef.
  278. ArrayRef<VPValue *> definedValues() { return DefinedValues; }
  279. /// Returns an ArrayRef of the values defined by the VPDef.
  280. ArrayRef<VPValue *> definedValues() const { return DefinedValues; }
  281. /// Returns the number of values defined by the VPDef.
  282. unsigned getNumDefinedValues() const { return DefinedValues.size(); }
  283. /// \return an ID for the concrete type of this object.
  284. /// This is used to implement the classof checks. This should not be used
  285. /// for any other purpose, as the values may change as LLVM evolves.
  286. unsigned getVPDefID() const { return SubclassID; }
  287. /// Dump the VPDef to stderr (for debugging).
  288. void dump() const;
  289. /// Each concrete VPDef prints itself.
  290. virtual void print(raw_ostream &O, const Twine &Indent,
  291. VPSlotTracker &SlotTracker) const = 0;
  292. };
  293. class VPlan;
  294. class VPBasicBlock;
  295. class VPRegionBlock;
  296. /// This class can be used to assign consecutive numbers to all VPValues in a
  297. /// VPlan and allows querying the numbering for printing, similar to the
  298. /// ModuleSlotTracker for IR values.
  299. class VPSlotTracker {
  300. DenseMap<const VPValue *, unsigned> Slots;
  301. unsigned NextSlot = 0;
  302. void assignSlots(const VPBlockBase *VPBB);
  303. void assignSlots(const VPRegionBlock *Region);
  304. void assignSlots(const VPBasicBlock *VPBB);
  305. void assignSlot(const VPValue *V);
  306. void assignSlots(const VPlan &Plan);
  307. public:
  308. VPSlotTracker(const VPlan *Plan = nullptr) {
  309. if (Plan)
  310. assignSlots(*Plan);
  311. }
  312. unsigned getSlot(const VPValue *V) const {
  313. auto I = Slots.find(V);
  314. if (I == Slots.end())
  315. return -1;
  316. return I->second;
  317. }
  318. };
  319. } // namespace llvm
  320. #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H