Home | History | Annotate | Line # | Download | only in OpenMP
      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 
     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 property it matches in the set \p Set and
     74 /// selector \p Selector or TraitProperty::invalid.
     75 TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set,
     76                                                 TraitSelector Selector,
     77                                                 StringRef Str);
     78 
     79 /// Return the trait property for a singleton selector \p Selector.
     80 TraitProperty 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.
     85 StringRef 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.
     90 StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind);
     91 
     92 /// Return a string listing all trait sets.
     93 std::string listOpenMPContextTraitSets();
     94 
     95 /// Return a string listing all trait selectors for \p Set.
     96 std::string listOpenMPContextTraitSelectors(TraitSet Set);
     97 
     98 /// Return a string listing all trait properties for \p Set and \p Selector.
     99 std::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.
    107 bool 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.
    112 bool 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.
    119 struct 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.
    157 struct 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.
    183 bool 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.
    189 int getBestVariantMatchForContext(const SmallVectorImpl<VariantMatchInfo> &VMIs,
    190                                   const OMPContext &Ctx);
    191 
    192 } // namespace omp
    193 
    194 template <> 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