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_FRONTEND_OPENMP_OMPCONTEXT_H 16#define LLVM_FRONTEND_OPENMP_OMPCONTEXT_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 25namespace llvm { 26namespace omp { 27 28/// OpenMP Context related IDs and helpers 29/// 30///{ 31 32/// IDs for all OpenMP context selector trait sets (construct/device/...). 33enum 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...}/...). 39enum 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/...) 45enum 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. 52TraitSet getOpenMPContextTraitSetKind(StringRef Str); 53 54/// Return the trait set for which \p Selector is a selector. 55TraitSet getOpenMPContextTraitSetForSelector(TraitSelector Selector); 56 57/// Return the trait set for which \p Property is a property. 58TraitSet getOpenMPContextTraitSetForProperty(TraitProperty Property); 59 60/// Return a textual representation of the trait set \p Kind. 61StringRef getOpenMPContextTraitSetName(TraitSet Kind); 62 63/// Parse \p Str and return the trait set it matches or 64/// TraitSelector::invalid. 65TraitSelector getOpenMPContextTraitSelectorKind(StringRef Str); 66 67/// Return the trait selector for which \p Property is a property. 68TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property); 69 70/// Return a textual representation of the trait selector \p Kind. 71StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind); 72 73/// Parse \p Str and return the trait property it matches in the set \p Set and 74/// selector \p Selector or TraitProperty::invalid. 75TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set, 76 TraitSelector Selector, 77 StringRef Str); 78 79/// Return the trait property for a singleton selector \p Selector. 80TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector); 81 82/// Return a textual representation of the trait property \p Kind, which might 83/// be the raw string we parsed (\p RawString) if we do not translate the 84/// property into a (distinct) enum. 85StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind, 86 StringRef RawString); 87 88/// Return a textual representation of the trait property \p Kind with selector 89/// and set name included. 90StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind); 91 92/// Return a string listing all trait sets. 93std::string listOpenMPContextTraitSets(); 94 95/// Return a string listing all trait selectors for \p Set. 96std::string listOpenMPContextTraitSelectors(TraitSet Set); 97 98/// Return a string listing all trait properties for \p Set and \p Selector. 99std::string listOpenMPContextTraitProperties(TraitSet Set, 100 TraitSelector Selector); 101///} 102 103/// Return true if \p Selector can be nested in \p Set. Also sets 104/// \p AllowsTraitScore and \p RequiresProperty to true/false if the user can 105/// specify a score for properties in \p Selector and if the \p Selector 106/// requires at least one property. 107bool isValidTraitSelectorForTraitSet(TraitSelector Selector, TraitSet Set, 108 bool &AllowsTraitScore, 109 bool &RequiresProperty); 110 111/// Return true if \p Property can be nested in \p Selector and \p Set. 112bool isValidTraitPropertyForTraitSetAndSelector(TraitProperty Property, 113 TraitSelector Selector, 114 TraitSet Set); 115 116/// Variant match information describes the required traits and how they are 117/// scored (via the ScoresMap). In addition, the required consturct nesting is 118/// decribed as well. 119struct VariantMatchInfo { 120 /// Add the trait \p Property to the required trait set. \p RawString is the 121 /// string we parsed and derived \p Property from. If \p Score is not null, it 122 /// recorded as well. If \p Property is in the `construct` set it is recorded 123 /// in-order in the ConstructTraits as well. 124 void addTrait(TraitProperty Property, StringRef RawString, 125 APInt *Score = nullptr) { 126 addTrait(getOpenMPContextTraitSetForProperty(Property), Property, RawString, 127 Score); 128 } 129 /// Add the trait \p Property which is in set \p Set to the required trait 130 /// set. \p RawString is the string we parsed and derived \p Property from. If 131 /// \p Score is not null, it recorded as well. If \p Set is the `construct` 132 /// set it is recorded in-order in the ConstructTraits as well. 133 void addTrait(TraitSet Set, TraitProperty Property, StringRef RawString, 134 APInt *Score = nullptr) { 135 if (Score) 136 ScoreMap[Property] = *Score; 137 138 // Special handling for `device={isa(...)}` as we do not match the enum but 139 // the raw string. 140 if (Property == TraitProperty::device_isa___ANY) 141 ISATraits.push_back(RawString); 142 143 RequiredTraits.set(unsigned(Property)); 144 if (Set == TraitSet::construct) 145 ConstructTraits.push_back(Property); 146 } 147 148 BitVector RequiredTraits = BitVector(unsigned(TraitProperty::Last) + 1); 149 SmallVector<StringRef, 8> ISATraits; 150 SmallVector<TraitProperty, 8> ConstructTraits; 151 SmallDenseMap<TraitProperty, APInt> ScoreMap; 152}; 153 154/// The context for a source location is made up of active property traits, 155/// e.g., device={kind(host)}, and constructs traits which describe the nesting 156/// in OpenMP constructs at the location. 157struct OMPContext { 158 OMPContext(bool IsDeviceCompilation, Triple TargetTriple); 159 virtual ~OMPContext() = default; 160 161 void addTrait(TraitProperty Property) { 162 addTrait(getOpenMPContextTraitSetForProperty(Property), Property); 163 } 164 void addTrait(TraitSet Set, TraitProperty Property) { 165 ActiveTraits.set(unsigned(Property)); 166 if (Set == TraitSet::construct) 167 ConstructTraits.push_back(Property); 168 } 169 170 /// Hook for users to check if an ISA trait matches. The trait is described as 171 /// the string that got parsed and it depends on the target and context if 172 /// this matches or not. 173 virtual bool matchesISATrait(StringRef) const { return false; } 174 175 BitVector ActiveTraits = BitVector(unsigned(TraitProperty::Last) + 1); 176 SmallVector<TraitProperty, 8> ConstructTraits; 177}; 178 179/// Return true if \p VMI is applicable in \p Ctx, that is, all traits required 180/// by \p VMI are available in the OpenMP context \p Ctx. If \p DeviceSetOnly is 181/// true, only the device selector set, if present, are checked. Note that we 182/// still honor extension traits provided by the user. 183bool isVariantApplicableInContext(const VariantMatchInfo &VMI, 184 const OMPContext &Ctx, 185 bool DeviceSetOnly = false); 186 187/// Return the index (into \p VMIs) of the variant with the highest score 188/// from the ones applicble in \p Ctx. See llvm::isVariantApplicableInContext. 189int getBestVariantMatchForContext(const SmallVectorImpl<VariantMatchInfo> &VMIs, 190 const OMPContext &Ctx); 191 192} // namespace omp 193 194template <> struct DenseMapInfo<omp::TraitProperty> { 195 static inline omp::TraitProperty getEmptyKey() { 196 return omp::TraitProperty(-1); 197 } 198 static inline omp::TraitProperty getTombstoneKey() { 199 return omp::TraitProperty(-2); 200 } 201 static unsigned getHashValue(omp::TraitProperty val) { 202 return std::hash<unsigned>{}(unsigned(val)); 203 } 204 static bool isEqual(omp::TraitProperty LHS, omp::TraitProperty RHS) { 205 return LHS == RHS; 206 } 207}; 208 209} // end namespace llvm 210#endif // LLVM_FRONTEND_OPENMP_OMPCONTEXT_H 211