VPlanValue.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  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.
  75. enum {
  76. VPValueSC, /// A generic VPValue, like live-in values or defined by a recipe
  77. /// that defines multiple values.
  78. VPVRecipeSC /// A VPValue sub-class that is a VPRecipeBase.
  79. };
  80. /// Create a live-in VPValue.
  81. VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV, nullptr) {}
  82. /// Create a VPValue for a \p Def which is a subclass of VPValue.
  83. VPValue(VPDef *Def, Value *UV = nullptr) : VPValue(VPVRecipeSC, UV, Def) {}
  84. /// Create a VPValue for a \p Def which defines multiple values.
  85. VPValue(Value *UV, VPDef *Def) : VPValue(VPValueSC, UV, Def) {}
  86. VPValue(const VPValue &) = delete;
  87. VPValue &operator=(const VPValue &) = delete;
  88. virtual ~VPValue();
  89. /// \return an ID for the concrete type of this object.
  90. /// This is used to implement the classof checks. This should not be used
  91. /// for any other purpose, as the values may change as LLVM evolves.
  92. unsigned getVPValueID() const { return SubclassID; }
  93. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  94. void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const;
  95. void print(raw_ostream &OS, VPSlotTracker &Tracker) const;
  96. /// Dump the value to stderr (for debugging).
  97. void dump() const;
  98. #endif
  99. unsigned getNumUsers() const { return Users.size(); }
  100. void addUser(VPUser &User) { Users.push_back(&User); }
  101. /// Remove a single \p User from the list of users.
  102. void removeUser(VPUser &User) {
  103. bool Found = false;
  104. // The same user can be added multiple times, e.g. because the same VPValue
  105. // is used twice by the same VPUser. Remove a single one.
  106. erase_if(Users, [&User, &Found](VPUser *Other) {
  107. if (Found)
  108. return false;
  109. if (Other == &User) {
  110. Found = true;
  111. return true;
  112. }
  113. return false;
  114. });
  115. }
  116. typedef SmallVectorImpl<VPUser *>::iterator user_iterator;
  117. typedef SmallVectorImpl<VPUser *>::const_iterator const_user_iterator;
  118. typedef iterator_range<user_iterator> user_range;
  119. typedef iterator_range<const_user_iterator> const_user_range;
  120. user_iterator user_begin() { return Users.begin(); }
  121. const_user_iterator user_begin() const { return Users.begin(); }
  122. user_iterator user_end() { return Users.end(); }
  123. const_user_iterator user_end() const { return Users.end(); }
  124. user_range users() { return user_range(user_begin(), user_end()); }
  125. const_user_range users() const {
  126. return const_user_range(user_begin(), user_end());
  127. }
  128. /// Returns true if the value has more than one unique user.
  129. bool hasMoreThanOneUniqueUser() {
  130. if (getNumUsers() == 0)
  131. return false;
  132. // Check if all users match the first user.
  133. auto Current = std::next(user_begin());
  134. while (Current != user_end() && *user_begin() == *Current)
  135. Current++;
  136. return Current != user_end();
  137. }
  138. void replaceAllUsesWith(VPValue *New);
  139. /// Returns the recipe defining this VPValue or nullptr if it is not defined
  140. /// by a recipe, i.e. is a live-in.
  141. VPRecipeBase *getDefiningRecipe();
  142. const VPRecipeBase *getDefiningRecipe() const;
  143. /// Returns true if this VPValue is defined by a recipe.
  144. bool hasDefiningRecipe() const { return getDefiningRecipe(); }
  145. /// Returns the underlying IR value, if this VPValue is defined outside the
  146. /// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
  147. /// inside a VPlan.
  148. Value *getLiveInIRValue() {
  149. assert(!hasDefiningRecipe() &&
  150. "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
  151. return getUnderlyingValue();
  152. }
  153. const Value *getLiveInIRValue() const {
  154. assert(!hasDefiningRecipe() &&
  155. "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
  156. return getUnderlyingValue();
  157. }
  158. /// Returns true if the VPValue is defined outside any vector regions, i.e. it
  159. /// is a live-in value.
  160. /// TODO: Also handle recipes defined in pre-header blocks.
  161. bool isDefinedOutsideVectorRegions() const { return !hasDefiningRecipe(); }
  162. };
  163. typedef DenseMap<Value *, VPValue *> Value2VPValueTy;
  164. typedef DenseMap<VPValue *, Value *> VPValue2ValueTy;
  165. raw_ostream &operator<<(raw_ostream &OS, const VPValue &V);
  166. /// This class augments VPValue with operands which provide the inverse def-use
  167. /// edges from VPValue's users to their defs.
  168. class VPUser {
  169. public:
  170. /// Subclass identifier (for isa/dyn_cast).
  171. enum class VPUserID {
  172. Recipe,
  173. LiveOut,
  174. };
  175. private:
  176. SmallVector<VPValue *, 2> Operands;
  177. VPUserID ID;
  178. protected:
  179. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  180. /// Print the operands to \p O.
  181. void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const;
  182. #endif
  183. VPUser(ArrayRef<VPValue *> Operands, VPUserID ID) : ID(ID) {
  184. for (VPValue *Operand : Operands)
  185. addOperand(Operand);
  186. }
  187. VPUser(std::initializer_list<VPValue *> Operands, VPUserID ID)
  188. : VPUser(ArrayRef<VPValue *>(Operands), ID) {}
  189. template <typename IterT>
  190. VPUser(iterator_range<IterT> Operands, VPUserID ID) : ID(ID) {
  191. for (VPValue *Operand : Operands)
  192. addOperand(Operand);
  193. }
  194. public:
  195. VPUser() = delete;
  196. VPUser(const VPUser &) = delete;
  197. VPUser &operator=(const VPUser &) = delete;
  198. virtual ~VPUser() {
  199. for (VPValue *Op : operands())
  200. Op->removeUser(*this);
  201. }
  202. VPUserID getVPUserID() const { return ID; }
  203. void addOperand(VPValue *Operand) {
  204. Operands.push_back(Operand);
  205. Operand->addUser(*this);
  206. }
  207. unsigned getNumOperands() const { return Operands.size(); }
  208. inline VPValue *getOperand(unsigned N) const {
  209. assert(N < Operands.size() && "Operand index out of bounds");
  210. return Operands[N];
  211. }
  212. void setOperand(unsigned I, VPValue *New) {
  213. Operands[I]->removeUser(*this);
  214. Operands[I] = New;
  215. New->addUser(*this);
  216. }
  217. void removeLastOperand() {
  218. VPValue *Op = Operands.pop_back_val();
  219. Op->removeUser(*this);
  220. }
  221. typedef SmallVectorImpl<VPValue *>::iterator operand_iterator;
  222. typedef SmallVectorImpl<VPValue *>::const_iterator const_operand_iterator;
  223. typedef iterator_range<operand_iterator> operand_range;
  224. typedef iterator_range<const_operand_iterator> const_operand_range;
  225. operand_iterator op_begin() { return Operands.begin(); }
  226. const_operand_iterator op_begin() const { return Operands.begin(); }
  227. operand_iterator op_end() { return Operands.end(); }
  228. const_operand_iterator op_end() const { return Operands.end(); }
  229. operand_range operands() { return operand_range(op_begin(), op_end()); }
  230. const_operand_range operands() const {
  231. return const_operand_range(op_begin(), op_end());
  232. }
  233. /// Returns true if the VPUser uses scalars of operand \p Op. Conservatively
  234. /// returns if only first (scalar) lane is used, as default.
  235. virtual bool usesScalars(const VPValue *Op) const {
  236. assert(is_contained(operands(), Op) &&
  237. "Op must be an operand of the recipe");
  238. return onlyFirstLaneUsed(Op);
  239. }
  240. /// Returns true if the VPUser only uses the first lane of operand \p Op.
  241. /// Conservatively returns false.
  242. virtual bool onlyFirstLaneUsed(const VPValue *Op) const {
  243. assert(is_contained(operands(), Op) &&
  244. "Op must be an operand of the recipe");
  245. return false;
  246. }
  247. };
  248. /// This class augments a recipe with a set of VPValues defined by the recipe.
  249. /// It allows recipes to define zero, one or multiple VPValues. A VPDef owns
  250. /// the VPValues it defines and is responsible for deleting its defined values.
  251. /// Single-value VPDefs that also inherit from VPValue must make sure to inherit
  252. /// from VPDef before VPValue.
  253. class VPDef {
  254. friend class VPValue;
  255. /// Subclass identifier (for isa/dyn_cast).
  256. const unsigned char SubclassID;
  257. /// The VPValues defined by this VPDef.
  258. TinyPtrVector<VPValue *> DefinedValues;
  259. /// Add \p V as a defined value by this VPDef.
  260. void addDefinedValue(VPValue *V) {
  261. assert(V->Def == this &&
  262. "can only add VPValue already linked with this VPDef");
  263. DefinedValues.push_back(V);
  264. }
  265. /// Remove \p V from the values defined by this VPDef. \p V must be a defined
  266. /// value of this VPDef.
  267. void removeDefinedValue(VPValue *V) {
  268. assert(V->Def == this && "can only remove VPValue linked with this VPDef");
  269. assert(is_contained(DefinedValues, V) &&
  270. "VPValue to remove must be in DefinedValues");
  271. erase_value(DefinedValues, V);
  272. V->Def = nullptr;
  273. }
  274. public:
  275. /// An enumeration for keeping track of the concrete subclass of VPRecipeBase
  276. /// that is actually instantiated. Values of this enumeration are kept in the
  277. /// SubclassID field of the VPRecipeBase objects. They are used for concrete
  278. /// type identification.
  279. using VPRecipeTy = enum {
  280. VPBranchOnMaskSC,
  281. VPDerivedIVSC,
  282. VPExpandSCEVSC,
  283. VPInstructionSC,
  284. VPInterleaveSC,
  285. VPReductionSC,
  286. VPReplicateSC,
  287. VPScalarIVStepsSC,
  288. VPWidenCallSC,
  289. VPWidenCanonicalIVSC,
  290. VPWidenGEPSC,
  291. VPWidenMemoryInstructionSC,
  292. VPWidenSC,
  293. VPWidenSelectSC,
  294. // Phi-like recipes. Need to be kept together.
  295. VPBlendSC,
  296. VPPredInstPHISC,
  297. // Header-phi recipes. Need to be kept together.
  298. VPCanonicalIVPHISC,
  299. VPActiveLaneMaskPHISC,
  300. VPFirstOrderRecurrencePHISC,
  301. VPWidenPHISC,
  302. VPWidenIntOrFpInductionSC,
  303. VPWidenPointerInductionSC,
  304. VPReductionPHISC,
  305. VPFirstPHISC = VPBlendSC,
  306. VPFirstHeaderPHISC = VPCanonicalIVPHISC,
  307. VPLastPHISC = VPReductionPHISC,
  308. };
  309. VPDef(const unsigned char SC) : SubclassID(SC) {}
  310. virtual ~VPDef() {
  311. for (VPValue *D : make_early_inc_range(DefinedValues)) {
  312. assert(D->Def == this &&
  313. "all defined VPValues should point to the containing VPDef");
  314. assert(D->getNumUsers() == 0 &&
  315. "all defined VPValues should have no more users");
  316. D->Def = nullptr;
  317. delete D;
  318. }
  319. }
  320. /// Returns the only VPValue defined by the VPDef. Can only be called for
  321. /// VPDefs with a single defined value.
  322. VPValue *getVPSingleValue() {
  323. assert(DefinedValues.size() == 1 && "must have exactly one defined value");
  324. assert(DefinedValues[0] && "defined value must be non-null");
  325. return DefinedValues[0];
  326. }
  327. const VPValue *getVPSingleValue() const {
  328. assert(DefinedValues.size() == 1 && "must have exactly one defined value");
  329. assert(DefinedValues[0] && "defined value must be non-null");
  330. return DefinedValues[0];
  331. }
  332. /// Returns the VPValue with index \p I defined by the VPDef.
  333. VPValue *getVPValue(unsigned I) {
  334. assert(DefinedValues[I] && "defined value must be non-null");
  335. return DefinedValues[I];
  336. }
  337. const VPValue *getVPValue(unsigned I) const {
  338. assert(DefinedValues[I] && "defined value must be non-null");
  339. return DefinedValues[I];
  340. }
  341. /// Returns an ArrayRef of the values defined by the VPDef.
  342. ArrayRef<VPValue *> definedValues() { return DefinedValues; }
  343. /// Returns an ArrayRef of the values defined by the VPDef.
  344. ArrayRef<VPValue *> definedValues() const { return DefinedValues; }
  345. /// Returns the number of values defined by the VPDef.
  346. unsigned getNumDefinedValues() const { return DefinedValues.size(); }
  347. /// \return an ID for the concrete type of this object.
  348. /// This is used to implement the classof checks. This should not be used
  349. /// for any other purpose, as the values may change as LLVM evolves.
  350. unsigned getVPDefID() const { return SubclassID; }
  351. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  352. /// Dump the VPDef to stderr (for debugging).
  353. void dump() const;
  354. /// Each concrete VPDef prints itself.
  355. virtual void print(raw_ostream &O, const Twine &Indent,
  356. VPSlotTracker &SlotTracker) const = 0;
  357. #endif
  358. };
  359. class VPlan;
  360. class VPBasicBlock;
  361. /// This class can be used to assign consecutive numbers to all VPValues in a
  362. /// VPlan and allows querying the numbering for printing, similar to the
  363. /// ModuleSlotTracker for IR values.
  364. class VPSlotTracker {
  365. DenseMap<const VPValue *, unsigned> Slots;
  366. unsigned NextSlot = 0;
  367. void assignSlot(const VPValue *V);
  368. void assignSlots(const VPlan &Plan);
  369. public:
  370. VPSlotTracker(const VPlan *Plan = nullptr) {
  371. if (Plan)
  372. assignSlots(*Plan);
  373. }
  374. unsigned getSlot(const VPValue *V) const {
  375. auto I = Slots.find(V);
  376. if (I == Slots.end())
  377. return -1;
  378. return I->second;
  379. }
  380. };
  381. } // namespace llvm
  382. #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H