Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:55

0001 //===- OpenMP/OMPContext.h ----- OpenMP context helper functions  - C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 ///
0010 /// This file provides helper functions and classes to deal with OpenMP
0011 /// contexts as used by `[begin/end] declare variant` and `metadirective`.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_FRONTEND_OPENMP_OMPCONTEXT_H
0016 #define LLVM_FRONTEND_OPENMP_OMPCONTEXT_H
0017 
0018 #include "llvm/ADT/APInt.h"
0019 #include "llvm/ADT/BitVector.h"
0020 #include "llvm/ADT/DenseMap.h"
0021 #include "llvm/ADT/DenseMapInfo.h"
0022 #include "llvm/Frontend/OpenMP/OMPConstants.h"
0023 
0024 namespace llvm {
0025 class Triple;
0026 namespace omp {
0027 
0028 /// OpenMP Context related IDs and helpers
0029 ///
0030 ///{
0031 
0032 /// IDs for all OpenMP context selector trait sets (construct/device/...).
0033 enum class TraitSet {
0034 #define OMP_TRAIT_SET(Enum, ...) Enum,
0035 #include "llvm/Frontend/OpenMP/OMPKinds.def"
0036 };
0037 
0038 /// IDs for all OpenMP context selector trait (device={kind/isa...}/...).
0039 enum class TraitSelector {
0040 #define OMP_TRAIT_SELECTOR(Enum, ...) Enum,
0041 #include "llvm/Frontend/OpenMP/OMPKinds.def"
0042 };
0043 
0044 /// IDs for all OpenMP context trait properties (host/gpu/bsc/llvm/...)
0045 enum class TraitProperty {
0046 #define OMP_TRAIT_PROPERTY(Enum, ...) Enum,
0047 #define OMP_LAST_TRAIT_PROPERTY(Enum) Last = Enum
0048 #include "llvm/Frontend/OpenMP/OMPKinds.def"
0049 };
0050 
0051 /// Parse \p Str and return the trait set it matches or TraitSet::invalid.
0052 TraitSet getOpenMPContextTraitSetKind(StringRef Str);
0053 
0054 /// Return the trait set for which \p Selector is a selector.
0055 TraitSet getOpenMPContextTraitSetForSelector(TraitSelector Selector);
0056 
0057 /// Return the trait set for which \p Property is a property.
0058 TraitSet getOpenMPContextTraitSetForProperty(TraitProperty Property);
0059 
0060 /// Return a textual representation of the trait set \p Kind.
0061 StringRef getOpenMPContextTraitSetName(TraitSet Kind);
0062 
0063 /// Parse \p Str and return the trait set it matches or
0064 /// TraitSelector::invalid.
0065 TraitSelector getOpenMPContextTraitSelectorKind(StringRef Str);
0066 
0067 /// Return the trait selector for which \p Property is a property.
0068 TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property);
0069 
0070 /// Return a textual representation of the trait selector \p Kind.
0071 StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind);
0072 
0073 /// Parse \p Str and return the trait property it matches in the set \p Set and
0074 /// selector \p Selector or TraitProperty::invalid.
0075 TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set,
0076                                                 TraitSelector Selector,
0077                                                 StringRef Str);
0078 
0079 /// Return the trait property for a singleton selector \p Selector.
0080 TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector);
0081 
0082 /// Return a textual representation of the trait property \p Kind, which might
0083 /// be the raw string we parsed (\p RawString) if we do not translate the
0084 /// property into a (distinct) enum.
0085 StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind,
0086                                             StringRef RawString);
0087 
0088 /// Return a textual representation of the trait property \p Kind with selector
0089 /// and set name included.
0090 StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind);
0091 
0092 /// Return a string listing all trait sets.
0093 std::string listOpenMPContextTraitSets();
0094 
0095 /// Return a string listing all trait selectors for \p Set.
0096 std::string listOpenMPContextTraitSelectors(TraitSet Set);
0097 
0098 /// Return a string listing all trait properties for \p Set and \p Selector.
0099 std::string listOpenMPContextTraitProperties(TraitSet Set,
0100                                              TraitSelector Selector);
0101 ///}
0102 
0103 /// Return true if \p Selector can be nested in \p Set. Also sets
0104 /// \p AllowsTraitScore and \p RequiresProperty to true/false if the user can
0105 /// specify a score for properties in \p Selector and if the \p Selector
0106 /// requires at least one property.
0107 bool isValidTraitSelectorForTraitSet(TraitSelector Selector, TraitSet Set,
0108                                      bool &AllowsTraitScore,
0109                                      bool &RequiresProperty);
0110 
0111 /// Return true if \p Property can be nested in \p Selector and \p Set.
0112 bool isValidTraitPropertyForTraitSetAndSelector(TraitProperty Property,
0113                                                 TraitSelector Selector,
0114                                                 TraitSet Set);
0115 
0116 /// Variant match information describes the required traits and how they are
0117 /// scored (via the ScoresMap). In addition, the required consturct nesting is
0118 /// decribed as well.
0119 struct VariantMatchInfo {
0120   /// Add the trait \p Property to the required trait set. \p RawString is the
0121   /// string we parsed and derived \p Property from. If \p Score is not null, it
0122   /// recorded as well. If \p Property is in the `construct` set it is recorded
0123   /// in-order in the ConstructTraits as well.
0124   void addTrait(TraitProperty Property, StringRef RawString,
0125                 APInt *Score = nullptr) {
0126     addTrait(getOpenMPContextTraitSetForProperty(Property), Property, RawString,
0127              Score);
0128   }
0129   /// Add the trait \p Property which is in set \p Set to the required trait
0130   /// set. \p RawString is the string we parsed and derived \p Property from. If
0131   /// \p Score is not null, it recorded as well. If \p Set is the `construct`
0132   /// set it is recorded in-order in the ConstructTraits as well.
0133   void addTrait(TraitSet Set, TraitProperty Property, StringRef RawString,
0134                 APInt *Score = nullptr) {
0135     if (Score)
0136       ScoreMap[Property] = *Score;
0137 
0138     // Special handling for `device={isa(...)}` as we do not match the enum but
0139     // the raw string.
0140     if (Property == TraitProperty::device_isa___ANY)
0141       ISATraits.push_back(RawString);
0142 
0143     RequiredTraits.set(unsigned(Property));
0144     if (Set == TraitSet::construct)
0145       ConstructTraits.push_back(Property);
0146   }
0147 
0148   BitVector RequiredTraits = BitVector(unsigned(TraitProperty::Last) + 1);
0149   SmallVector<StringRef, 8> ISATraits;
0150   SmallVector<TraitProperty, 8> ConstructTraits;
0151   SmallDenseMap<TraitProperty, APInt> ScoreMap;
0152 };
0153 
0154 /// The context for a source location is made up of active property traits,
0155 /// e.g., device={kind(host)}, and constructs traits which describe the nesting
0156 /// in OpenMP constructs at the location.
0157 struct OMPContext {
0158   OMPContext(bool IsDeviceCompilation, Triple TargetTriple);
0159   virtual ~OMPContext() = default;
0160 
0161   void addTrait(TraitProperty Property) {
0162     addTrait(getOpenMPContextTraitSetForProperty(Property), Property);
0163   }
0164   void addTrait(TraitSet Set, TraitProperty Property) {
0165     ActiveTraits.set(unsigned(Property));
0166     if (Set == TraitSet::construct)
0167       ConstructTraits.push_back(Property);
0168   }
0169 
0170   /// Hook for users to check if an ISA trait matches. The trait is described as
0171   /// the string that got parsed and it depends on the target and context if
0172   /// this matches or not.
0173   virtual bool matchesISATrait(StringRef) const { return false; }
0174 
0175   BitVector ActiveTraits = BitVector(unsigned(TraitProperty::Last) + 1);
0176   SmallVector<TraitProperty, 8> ConstructTraits;
0177 };
0178 
0179 /// Return true if \p VMI is applicable in \p Ctx, that is, all traits required
0180 /// by \p VMI are available in the OpenMP context \p Ctx. If \p DeviceSetOnly is
0181 /// true, only the device selector set, if present, are checked. Note that we
0182 /// still honor extension traits provided by the user.
0183 bool isVariantApplicableInContext(const VariantMatchInfo &VMI,
0184                                   const OMPContext &Ctx,
0185                                   bool DeviceSetOnly = false);
0186 
0187 /// Return the index (into \p VMIs) of the variant with the highest score
0188 /// from the ones applicble in \p Ctx. See llvm::isVariantApplicableInContext.
0189 int getBestVariantMatchForContext(const SmallVectorImpl<VariantMatchInfo> &VMIs,
0190                                   const OMPContext &Ctx);
0191 
0192 } // namespace omp
0193 
0194 template <> struct DenseMapInfo<omp::TraitProperty> {
0195   static inline omp::TraitProperty getEmptyKey() {
0196     return omp::TraitProperty(-1);
0197   }
0198   static inline omp::TraitProperty getTombstoneKey() {
0199     return omp::TraitProperty(-2);
0200   }
0201   static unsigned getHashValue(omp::TraitProperty val) {
0202     return std::hash<unsigned>{}(unsigned(val));
0203   }
0204   static bool isEqual(omp::TraitProperty LHS, omp::TraitProperty RHS) {
0205     return LHS == RHS;
0206   }
0207 };
0208 
0209 } // end namespace llvm
0210 #endif // LLVM_FRONTEND_OPENMP_OMPCONTEXT_H