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