211 lines
8.5 KiB
C
211 lines
8.5 KiB
C
|
//===- 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 property it matches in the set \p Set and
|
||
|
/// selector \p Selector or TraitProperty::invalid.
|
||
|
TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set,
|
||
|
TraitSelector Selector,
|
||
|
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, which might
|
||
|
/// be the raw string we parsed (\p RawString) if we do not translate the
|
||
|
/// property into a (distinct) enum.
|
||
|
StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind,
|
||
|
StringRef RawString);
|
||
|
|
||
|
/// 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. \p RawString is the
|
||
|
/// string we parsed and derived \p Property from. 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, StringRef RawString,
|
||
|
APInt *Score = nullptr) {
|
||
|
addTrait(getOpenMPContextTraitSetForProperty(Property), Property, RawString,
|
||
|
Score);
|
||
|
}
|
||
|
/// Add the trait \p Property which is in set \p Set to the required trait
|
||
|
/// set. \p RawString is the string we parsed and derived \p Property from. 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, StringRef RawString,
|
||
|
APInt *Score = nullptr) {
|
||
|
if (Score)
|
||
|
ScoreMap[Property] = *Score;
|
||
|
|
||
|
// Special handling for `device={isa(...)}` as we do not match the enum but
|
||
|
// the raw string.
|
||
|
if (Property == TraitProperty::device_isa___ANY)
|
||
|
ISATraits.push_back(RawString);
|
||
|
|
||
|
RequiredTraits.set(unsigned(Property));
|
||
|
if (Set == TraitSet::construct)
|
||
|
ConstructTraits.push_back(Property);
|
||
|
}
|
||
|
|
||
|
BitVector RequiredTraits = BitVector(unsigned(TraitProperty::Last) + 1);
|
||
|
SmallVector<StringRef, 8> ISATraits;
|
||
|
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);
|
||
|
virtual ~OMPContext() = default;
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
/// Hook for users to check if an ISA trait matches. The trait is described as
|
||
|
/// the string that got parsed and it depends on the target and context if
|
||
|
/// this matches or not.
|
||
|
virtual bool matchesISATrait(StringRef) const { return false; }
|
||
|
|
||
|
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
|