OMPContext.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- OpenMP/OMPContext.h ----- OpenMP context helper functions - 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. ///
  15. /// This file provides helper functions and classes to deal with OpenMP
  16. /// contexts as used by `[begin/end] declare variant` and `metadirective`.
  17. ///
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_FRONTEND_OPENMP_OMPCONTEXT_H
  20. #define LLVM_FRONTEND_OPENMP_OMPCONTEXT_H
  21. #include "llvm/ADT/APInt.h"
  22. #include "llvm/ADT/BitVector.h"
  23. #include "llvm/ADT/DenseMap.h"
  24. #include "llvm/ADT/DenseMapInfo.h"
  25. #include "llvm/Frontend/OpenMP/OMPConstants.h"
  26. namespace llvm {
  27. class Triple;
  28. namespace omp {
  29. /// OpenMP Context related IDs and helpers
  30. ///
  31. ///{
  32. /// IDs for all OpenMP context selector trait sets (construct/device/...).
  33. enum class TraitSet {
  34. #define OMP_TRAIT_SET(Enum, ...) Enum,
  35. #include "llvm/Frontend/OpenMP/OMPKinds.def"
  36. };
  37. /// IDs for all OpenMP context selector trait (device={kind/isa...}/...).
  38. enum class TraitSelector {
  39. #define OMP_TRAIT_SELECTOR(Enum, ...) Enum,
  40. #include "llvm/Frontend/OpenMP/OMPKinds.def"
  41. };
  42. /// IDs for all OpenMP context trait properties (host/gpu/bsc/llvm/...)
  43. enum class TraitProperty {
  44. #define OMP_TRAIT_PROPERTY(Enum, ...) Enum,
  45. #define OMP_LAST_TRAIT_PROPERTY(Enum) Last = Enum
  46. #include "llvm/Frontend/OpenMP/OMPKinds.def"
  47. };
  48. /// Parse \p Str and return the trait set it matches or TraitSet::invalid.
  49. TraitSet getOpenMPContextTraitSetKind(StringRef Str);
  50. /// Return the trait set for which \p Selector is a selector.
  51. TraitSet getOpenMPContextTraitSetForSelector(TraitSelector Selector);
  52. /// Return the trait set for which \p Property is a property.
  53. TraitSet getOpenMPContextTraitSetForProperty(TraitProperty Property);
  54. /// Return a textual representation of the trait set \p Kind.
  55. StringRef getOpenMPContextTraitSetName(TraitSet Kind);
  56. /// Parse \p Str and return the trait set it matches or
  57. /// TraitSelector::invalid.
  58. TraitSelector getOpenMPContextTraitSelectorKind(StringRef Str);
  59. /// Return the trait selector for which \p Property is a property.
  60. TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property);
  61. /// Return a textual representation of the trait selector \p Kind.
  62. StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind);
  63. /// Parse \p Str and return the trait property it matches in the set \p Set and
  64. /// selector \p Selector or TraitProperty::invalid.
  65. TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set,
  66. TraitSelector Selector,
  67. StringRef Str);
  68. /// Return the trait property for a singleton selector \p Selector.
  69. TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector);
  70. /// Return a textual representation of the trait property \p Kind, which might
  71. /// be the raw string we parsed (\p RawString) if we do not translate the
  72. /// property into a (distinct) enum.
  73. StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind,
  74. StringRef RawString);
  75. /// Return a textual representation of the trait property \p Kind with selector
  76. /// and set name included.
  77. StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind);
  78. /// Return a string listing all trait sets.
  79. std::string listOpenMPContextTraitSets();
  80. /// Return a string listing all trait selectors for \p Set.
  81. std::string listOpenMPContextTraitSelectors(TraitSet Set);
  82. /// Return a string listing all trait properties for \p Set and \p Selector.
  83. std::string listOpenMPContextTraitProperties(TraitSet Set,
  84. TraitSelector Selector);
  85. ///}
  86. /// Return true if \p Selector can be nested in \p Set. Also sets
  87. /// \p AllowsTraitScore and \p RequiresProperty to true/false if the user can
  88. /// specify a score for properties in \p Selector and if the \p Selector
  89. /// requires at least one property.
  90. bool isValidTraitSelectorForTraitSet(TraitSelector Selector, TraitSet Set,
  91. bool &AllowsTraitScore,
  92. bool &RequiresProperty);
  93. /// Return true if \p Property can be nested in \p Selector and \p Set.
  94. bool isValidTraitPropertyForTraitSetAndSelector(TraitProperty Property,
  95. TraitSelector Selector,
  96. TraitSet Set);
  97. /// Variant match information describes the required traits and how they are
  98. /// scored (via the ScoresMap). In addition, the required consturct nesting is
  99. /// decribed as well.
  100. struct VariantMatchInfo {
  101. /// Add the trait \p Property to the required trait set. \p RawString is the
  102. /// string we parsed and derived \p Property from. If \p Score is not null, it
  103. /// recorded as well. If \p Property is in the `construct` set it is recorded
  104. /// in-order in the ConstructTraits as well.
  105. void addTrait(TraitProperty Property, StringRef RawString,
  106. APInt *Score = nullptr) {
  107. addTrait(getOpenMPContextTraitSetForProperty(Property), Property, RawString,
  108. Score);
  109. }
  110. /// Add the trait \p Property which is in set \p Set to the required trait
  111. /// set. \p RawString is the string we parsed and derived \p Property from. If
  112. /// \p Score is not null, it recorded as well. If \p Set is the `construct`
  113. /// set it is recorded in-order in the ConstructTraits as well.
  114. void addTrait(TraitSet Set, TraitProperty Property, StringRef RawString,
  115. APInt *Score = nullptr) {
  116. if (Score)
  117. ScoreMap[Property] = *Score;
  118. // Special handling for `device={isa(...)}` as we do not match the enum but
  119. // the raw string.
  120. if (Property == TraitProperty::device_isa___ANY)
  121. ISATraits.push_back(RawString);
  122. RequiredTraits.set(unsigned(Property));
  123. if (Set == TraitSet::construct)
  124. ConstructTraits.push_back(Property);
  125. }
  126. BitVector RequiredTraits = BitVector(unsigned(TraitProperty::Last) + 1);
  127. SmallVector<StringRef, 8> ISATraits;
  128. SmallVector<TraitProperty, 8> ConstructTraits;
  129. SmallDenseMap<TraitProperty, APInt> ScoreMap;
  130. };
  131. /// The context for a source location is made up of active property traits,
  132. /// e.g., device={kind(host)}, and constructs traits which describe the nesting
  133. /// in OpenMP constructs at the location.
  134. struct OMPContext {
  135. OMPContext(bool IsDeviceCompilation, Triple TargetTriple);
  136. virtual ~OMPContext() = default;
  137. void addTrait(TraitProperty Property) {
  138. addTrait(getOpenMPContextTraitSetForProperty(Property), Property);
  139. }
  140. void addTrait(TraitSet Set, TraitProperty Property) {
  141. ActiveTraits.set(unsigned(Property));
  142. if (Set == TraitSet::construct)
  143. ConstructTraits.push_back(Property);
  144. }
  145. /// Hook for users to check if an ISA trait matches. The trait is described as
  146. /// the string that got parsed and it depends on the target and context if
  147. /// this matches or not.
  148. virtual bool matchesISATrait(StringRef) const { return false; }
  149. BitVector ActiveTraits = BitVector(unsigned(TraitProperty::Last) + 1);
  150. SmallVector<TraitProperty, 8> ConstructTraits;
  151. };
  152. /// Return true if \p VMI is applicable in \p Ctx, that is, all traits required
  153. /// by \p VMI are available in the OpenMP context \p Ctx. If \p DeviceSetOnly is
  154. /// true, only the device selector set, if present, are checked. Note that we
  155. /// still honor extension traits provided by the user.
  156. bool isVariantApplicableInContext(const VariantMatchInfo &VMI,
  157. const OMPContext &Ctx,
  158. bool DeviceSetOnly = false);
  159. /// Return the index (into \p VMIs) of the variant with the highest score
  160. /// from the ones applicble in \p Ctx. See llvm::isVariantApplicableInContext.
  161. int getBestVariantMatchForContext(const SmallVectorImpl<VariantMatchInfo> &VMIs,
  162. const OMPContext &Ctx);
  163. } // namespace omp
  164. template <> struct DenseMapInfo<omp::TraitProperty> {
  165. static inline omp::TraitProperty getEmptyKey() {
  166. return omp::TraitProperty(-1);
  167. }
  168. static inline omp::TraitProperty getTombstoneKey() {
  169. return omp::TraitProperty(-2);
  170. }
  171. static unsigned getHashValue(omp::TraitProperty val) {
  172. return std::hash<unsigned>{}(unsigned(val));
  173. }
  174. static bool isEqual(omp::TraitProperty LHS, omp::TraitProperty RHS) {
  175. return LHS == RHS;
  176. }
  177. };
  178. } // end namespace llvm
  179. #endif // LLVM_FRONTEND_OPENMP_OMPCONTEXT_H
  180. #ifdef __GNUC__
  181. #pragma GCC diagnostic pop
  182. #endif