diff options
Diffstat (limited to 'llvm/include/llvm/Frontend/OpenMP/OMPContext.h')
-rw-r--r-- | llvm/include/llvm/Frontend/OpenMP/OMPContext.h | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPContext.h b/llvm/include/llvm/Frontend/OpenMP/OMPContext.h new file mode 100644 index 000000000000..1a42d189db44 --- /dev/null +++ b/llvm/include/llvm/Frontend/OpenMP/OMPContext.h @@ -0,0 +1,187 @@ +//===- OpenMP/OMPContext.h ----- OpenMP context helper functions - C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file provides helper functions and classes to deal with OpenMP +/// contexts as used by `[begin/end] declare variant` and `metadirective`. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OPENMP_CONTEXT_H +#define LLVM_OPENMP_CONTEXT_H + +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Frontend/OpenMP/OMPConstants.h" + +namespace llvm { +namespace omp { + +/// OpenMP Context related IDs and helpers +/// +///{ + +/// IDs for all OpenMP context selector trait sets (construct/device/...). +enum class TraitSet { +#define OMP_TRAIT_SET(Enum, ...) Enum, +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + +/// IDs for all OpenMP context selector trait (device={kind/isa...}/...). +enum class TraitSelector { +#define OMP_TRAIT_SELECTOR(Enum, ...) Enum, +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + +/// IDs for all OpenMP context trait properties (host/gpu/bsc/llvm/...) +enum class TraitProperty { +#define OMP_TRAIT_PROPERTY(Enum, ...) Enum, +#define OMP_LAST_TRAIT_PROPERTY(Enum) Last = Enum +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + +/// Parse \p Str and return the trait set it matches or TraitSet::invalid. +TraitSet getOpenMPContextTraitSetKind(StringRef Str); + +/// Return the trait set for which \p Selector is a selector. +TraitSet getOpenMPContextTraitSetForSelector(TraitSelector Selector); + +/// Return the trait set for which \p Property is a property. +TraitSet getOpenMPContextTraitSetForProperty(TraitProperty Property); + +/// Return a textual representation of the trait set \p Kind. +StringRef getOpenMPContextTraitSetName(TraitSet Kind); + +/// Parse \p Str and return the trait set it matches or +/// TraitSelector::invalid. +TraitSelector getOpenMPContextTraitSelectorKind(StringRef Str); + +/// Return the trait selector for which \p Property is a property. +TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property); + +/// Return a textual representation of the trait selector \p Kind. +StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind); + +/// Parse \p Str and return the trait set it matches or +/// TraitProperty::invalid. +TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set, StringRef Str); + +/// Return the trait property for a singleton selector \p Selector. +TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector); + +/// Return a textual representation of the trait property \p Kind. +StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind); + +/// Return a textual representation of the trait property \p Kind with selector +/// and set name included. +StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind); + +/// Return a string listing all trait sets. +std::string listOpenMPContextTraitSets(); + +/// Return a string listing all trait selectors for \p Set. +std::string listOpenMPContextTraitSelectors(TraitSet Set); + +/// Return a string listing all trait properties for \p Set and \p Selector. +std::string listOpenMPContextTraitProperties(TraitSet Set, + TraitSelector Selector); +///} + +/// Return true if \p Selector can be nested in \p Set. Also sets +/// \p AllowsTraitScore and \p RequiresProperty to true/false if the user can +/// specify a score for properties in \p Selector and if the \p Selector +/// requires at least one property. +bool isValidTraitSelectorForTraitSet(TraitSelector Selector, TraitSet Set, + bool &AllowsTraitScore, + bool &RequiresProperty); + +/// Return true if \p Property can be nested in \p Selector and \p Set. +bool isValidTraitPropertyForTraitSetAndSelector(TraitProperty Property, + TraitSelector Selector, + TraitSet Set); + +/// Variant match information describes the required traits and how they are +/// scored (via the ScoresMap). In addition, the required consturct nesting is +/// decribed as well. +struct VariantMatchInfo { + /// Add the trait \p Property to the required trait set. If \p Score is not + /// null, it recorded as well. If \p Property is in the `construct` set it + /// is recorded in-order in the ConstructTraits as well. + void addTrait(TraitProperty Property, APInt *Score = nullptr) { + addTrait(getOpenMPContextTraitSetForProperty(Property), Property, Score); + } + /// Add the trait \p Property which is in set \p Set to the required trait + /// set. If \p Score is not null, it recorded as well. If \p Set is the + /// `construct` set it is recorded in-order in the ConstructTraits as well. + void addTrait(TraitSet Set, TraitProperty Property, APInt *Score = nullptr) { + if (Score) + ScoreMap[Property] = *Score; + RequiredTraits.set(unsigned(Property)); + if (Set == TraitSet::construct) + ConstructTraits.push_back(Property); + } + + BitVector RequiredTraits = BitVector(unsigned(TraitProperty::Last) + 1); + SmallVector<TraitProperty, 8> ConstructTraits; + SmallDenseMap<TraitProperty, APInt> ScoreMap; +}; + +/// The context for a source location is made up of active property traits, +/// e.g., device={kind(host)}, and constructs traits which describe the nesting +/// in OpenMP constructs at the location. +struct OMPContext { + OMPContext(bool IsDeviceCompilation, Triple TargetTriple); + + void addTrait(TraitProperty Property) { + addTrait(getOpenMPContextTraitSetForProperty(Property), Property); + } + void addTrait(TraitSet Set, TraitProperty Property) { + ActiveTraits.set(unsigned(Property)); + if (Set == TraitSet::construct) + ConstructTraits.push_back(Property); + } + + BitVector ActiveTraits = BitVector(unsigned(TraitProperty::Last) + 1); + SmallVector<TraitProperty, 8> ConstructTraits; +}; + +/// Return true if \p VMI is applicable in \p Ctx, that is, all traits required +/// by \p VMI are available in the OpenMP context \p Ctx. If \p DeviceSetOnly is +/// true, only the device selector set, if present, are checked. Note that we +/// still honor extension traits provided by the user. +bool isVariantApplicableInContext(const VariantMatchInfo &VMI, + const OMPContext &Ctx, + bool DeviceSetOnly = false); + +/// Return the index (into \p VMIs) of the variant with the highest score +/// from the ones applicble in \p Ctx. See llvm::isVariantApplicableInContext. +int getBestVariantMatchForContext(const SmallVectorImpl<VariantMatchInfo> &VMIs, + const OMPContext &Ctx); + +} // namespace omp + +template <> struct DenseMapInfo<omp::TraitProperty> { + static inline omp::TraitProperty getEmptyKey() { + return omp::TraitProperty(-1); + } + static inline omp::TraitProperty getTombstoneKey() { + return omp::TraitProperty(-2); + } + static unsigned getHashValue(omp::TraitProperty val) { + return std::hash<unsigned>{}(unsigned(val)); + } + static bool isEqual(omp::TraitProperty LHS, omp::TraitProperty RHS) { + return LHS == RHS; + } +}; + +} // end namespace llvm +#endif // LLVM_OPENMP_CONTEXT_H |