22#define DEBUG_TYPE "openmp-ir-builder"
28 Triple TargetOffloadTriple,
int DeviceNum) {
30 if (!TargetOffloadTriple.
getTriple().empty() && DeviceNum > -1) {
32 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_nohost));
33 switch (TargetOffloadTriple.
getArch()) {
50 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_cpu));
56 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_gpu));
62#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
63 if (TraitSelector::TraitSelectorEnum == TraitSelector::target_device_arch) { \
64 if (TargetOffloadTriple.getArch() == Triple::parseArch(Str)) \
65 ActiveTraits.set(unsigned(TraitProperty::Enum)); \
67#include "llvm/Frontend/OpenMP/OMPKinds.def"
72 ? TraitProperty::device_kind_nohost
73 : TraitProperty::device_kind_host));
74 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_host));
75 switch (TargetTriple.
getArch()) {
92 ActiveTraits.set(
unsigned(TraitProperty::device_kind_cpu));
93 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_cpu));
99 ActiveTraits.set(
unsigned(TraitProperty::device_kind_gpu));
100 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_gpu));
107#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
108 if (TraitSelector::TraitSelectorEnum == TraitSelector::device_arch || \
109 TraitSelector::TraitSelectorEnum == TraitSelector::target_device_arch) { \
110 if (TargetTriple.getArch() == Triple::parseArch(Str)) \
111 ActiveTraits.set(unsigned(TraitProperty::Enum)); \
113#include "llvm/Frontend/OpenMP/OMPKinds.def"
121 ActiveTraits.set(
unsigned(TraitProperty::implementation_vendor_llvm));
124 ActiveTraits.set(
unsigned(TraitProperty::user_condition_true));
127 ActiveTraits.set(
unsigned(TraitProperty::device_kind_any));
131 <<
"] New OpenMP context with the following properties:\n";
144#ifdef EXPENSIVE_CHECKS
146 "Expected sorted arrays!");
150 auto It0 = C0.
begin(), End0 = C0.
end();
151 auto It1 = C1.
begin(), End1 = C1.
end();
152 while (It0 != End0) {
193 bool DeviceOrImplementationSetOnly) {
197 enum MatchKind { MK_ALL, MK_ANY, MK_NONE };
199 MatchKind MK = MK_ALL;
203 unsigned(TraitProperty::implementation_extension_match_any)))
206 unsigned(TraitProperty::implementation_extension_match_none)))
213 bool WasFound) -> std::optional<bool> {
224 if ((WasFound && MK == MK_ALL) || (!WasFound && MK == MK_NONE))
232 <<
" was not in the OpenMP context but match kind is all.\n";
236 <<
" was in the OpenMP context but match kind is none.\n";
243 if (DeviceOrImplementationSetOnly &&
246 TraitSet::implementation)
252 TraitSelector::implementation_extension)
255 bool IsActiveTrait = Ctx.ActiveTraits.test(
unsigned(Property));
259 if (Property == TraitProperty::device_isa___ANY)
261 return Ctx.matchesISATrait(RawString);
263 if (Property == TraitProperty::target_device_isa___ANY)
265 return Ctx.matchesISATrait(RawString);
268 if (std::optional<bool> Result = HandleTrait(Property, IsActiveTrait))
272 if (!DeviceOrImplementationSetOnly) {
275 unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size();
278 TraitSet::construct &&
279 "Variant context is ill-formed!");
282 bool FoundInOrder =
false;
283 while (!FoundInOrder && ConstructIdx != NoConstructTraits)
284 FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] == Property);
285 if (ConstructMatches)
286 ConstructMatches->
push_back(ConstructIdx - 1);
288 if (std::optional<bool> Result = HandleTrait(Property, FoundInOrder))
294 <<
" was not nested properly.\n");
302 "Broken invariant!");
307 <<
"] None of the properties was in the OpenMP context "
308 "but match kind is any.\n");
317 bool DeviceOrImplementationSetOnly) {
319 VMI, Ctx,
nullptr, DeviceOrImplementationSetOnly);
333 assert(UserScore.
uge(0) &&
"Expect non-negative user scores!");
339 case TraitSet::construct:
343 case TraitSet::implementation:
349 case TraitSet::device:
352 case TraitSet::target_device:
355 case TraitSet::invalid:
360 if (Property == TraitProperty::device_kind_any)
362 if (Property == TraitProperty::target_device_kind_any)
366 case TraitSelector::device_kind:
367 Score += (1ULL << (NoConstructTraits + 0));
369 case TraitSelector::device_arch:
370 Score += (1ULL << (NoConstructTraits + 1));
372 case TraitSelector::device_isa:
373 Score += (1ULL << (NoConstructTraits + 2));
375 case TraitSelector::target_device_kind:
376 Score += (1ULL << (NoConstructTraits + 0));
378 case TraitSelector::target_device_arch:
379 Score += (1ULL << (NoConstructTraits + 1));
381 case TraitSelector::target_device_isa:
382 Score += (1ULL << (NoConstructTraits + 2));
389 unsigned ConstructIdx = 0;
390 assert(NoConstructTraits == ConstructMatches.
size() &&
391 "Mismatch in the construct traits!");
394 TraitSet::construct &&
395 "Ill-formed variant match info!");
398 Score += (1ULL << ConstructMatches[ConstructIdx++]);
409 APInt BestScore(64, 0);
413 for (
unsigned u = 0, e = VMIs.
size(); u < e; ++u) {
419 VMI, Ctx, &ConstructMatches,
424 if (Score.
ult(BestScore))
427 if (Score.
eq(BestScore)) {
446#define OMP_TRAIT_SET(Enum, Str) .Case(Str, TraitSet::Enum)
447#include "llvm/Frontend/OpenMP/OMPKinds.def"
454#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
455 case TraitSelector::Enum: \
456 return TraitSet::TraitSetEnum;
457#include "llvm/Frontend/OpenMP/OMPKinds.def"
464#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
465 case TraitProperty::Enum: \
466 return TraitSet::TraitSetEnum;
467#include "llvm/Frontend/OpenMP/OMPKinds.def"
473#define OMP_TRAIT_SET(Enum, Str) \
474 case TraitSet::Enum: \
476#include "llvm/Frontend/OpenMP/OMPKinds.def"
483 if (Set == TraitSet::target_device && S ==
"kind")
484 return TraitSelector::target_device_kind;
485 if (Set == TraitSet::target_device && S ==
"arch")
486 return TraitSelector::target_device_arch;
487 if (Set == TraitSet::target_device && S ==
"isa")
488 return TraitSelector::target_device_isa;
490#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
491 .Case(Str, TraitSelector::Enum)
492#include "llvm/Frontend/OpenMP/OMPKinds.def"
493 .
Default(TraitSelector::invalid);
498#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
499 case TraitProperty::Enum: \
500 return TraitSelector::TraitSelectorEnum;
501#include "llvm/Frontend/OpenMP/OMPKinds.def"
507#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
508 case TraitSelector::Enum: \
510#include "llvm/Frontend/OpenMP/OMPKinds.def"
519 if (Set == TraitSet::device && Selector == TraitSelector::device_isa)
520 return TraitProperty::device_isa___ANY;
521 if (Set == TraitSet::target_device &&
522 Selector == TraitSelector::target_device_isa)
523 return TraitProperty::target_device_isa___ANY;
524#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
525 if (Set == TraitSet::TraitSetEnum && Str == S) \
526 return TraitProperty::Enum;
527#include "llvm/Frontend/OpenMP/OMPKinds.def"
528 return TraitProperty::invalid;
534#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
535 .Case(Str, Selector == TraitSelector::TraitSelectorEnum \
536 ? TraitProperty::Enum \
537 : TraitProperty::invalid)
538#include "llvm/Frontend/OpenMP/OMPKinds.def"
539 .
Default(TraitProperty::invalid);
543 if (Kind == TraitProperty::device_isa___ANY)
545 if (Kind == TraitProperty::target_device_isa___ANY)
548#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
549 case TraitProperty::Enum: \
551#include "llvm/Frontend/OpenMP/OMPKinds.def"
557#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
558 case TraitProperty::Enum: \
559 return "(" #TraitSetEnum "," #TraitSelectorEnum "," Str ")";
560#include "llvm/Frontend/OpenMP/OMPKinds.def"
567 bool &AllowsTraitScore,
568 bool &RequiresProperty) {
569 AllowsTraitScore = Set != TraitSet::construct && Set != TraitSet::device &&
570 Set != TraitSet::target_device;
572#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
573 case TraitSelector::Enum: \
574 RequiresProperty = ReqProp; \
575 return Set == TraitSet::TraitSetEnum;
576#include "llvm/Frontend/OpenMP/OMPKinds.def"
584#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
585 case TraitProperty::Enum: \
586 return Set == TraitSet::TraitSetEnum && \
587 Selector == TraitSelector::TraitSelectorEnum;
588#include "llvm/Frontend/OpenMP/OMPKinds.def"
595#define OMP_TRAIT_SET(Enum, Str) \
596 if (StringRef(Str) != "invalid") \
597 S.append("'").append(Str).append("'").append(" ");
598#include "llvm/Frontend/OpenMP/OMPKinds.def"
605#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
606 if (TraitSet::TraitSetEnum == Set && StringRef(Str) != "Invalid") \
607 S.append("'").append(Str).append("'").append(" ");
608#include "llvm/Frontend/OpenMP/OMPKinds.def"
617#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
618 if (TraitSet::TraitSetEnum == Set && \
619 TraitSelector::TraitSelectorEnum == Selector && \
620 StringRef(Str) != "invalid") \
621 S.append("'").append(Str).append("'").append(" ");
622#include "llvm/Frontend/OpenMP/OMPKinds.def"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isStrictSubset(ArrayRef< T > C0, ArrayRef< T > C1)
Return true if C0 is a strict subset of C1.
static APInt getVariantMatchScore(const VariantMatchInfo &VMI, const OMPContext &Ctx, SmallVectorImpl< unsigned > &ConstructMatches)
static int isVariantApplicableInContextHelper(const VariantMatchInfo &VMI, const OMPContext &Ctx, SmallVectorImpl< unsigned > *ConstructMatches, bool DeviceOrImplementationSetOnly)
static bool isSubset(ArrayRef< T > C0, ArrayRef< T > C1)
Return true if C0 is a subset of C1.
This file provides helper functions and classes to deal with OpenMP contexts as used by [begin/end] d...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool eq(const APInt &RHS) const
Equality comparison.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool test(unsigned Idx) const
size_type count() const
count - Returns the number of bits which are set.
iterator_range< const_set_bits_iterator > set_bits() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
A switch()-like statement whose cases are string literals.
Triple - Helper class for working with autoconf configuration names.
ArchType getArch() const
Get the parsed architecture type of this triple.
const std::string & getTriple() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI std::string listOpenMPContextTraitSets()
Return a string listing all trait sets.
LLVM_ABI StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind)
Return a textual representation of the trait property Kind with selector and set name included.
LLVM_ABI bool isValidTraitSelectorForTraitSet(TraitSelector Selector, TraitSet Set, bool &AllowsTraitScore, bool &RequiresProperty)
}
LLVM_ABI TraitSet getOpenMPContextTraitSetForSelector(TraitSelector Selector)
Return the trait set for which Selector is a selector.
LLVM_ABI TraitSelector getOpenMPContextTraitSelectorKind(StringRef Str, TraitSet Set)
Parse Str and return the trait set it matches or TraitSelector::invalid.
LLVM_ABI TraitSet getOpenMPContextTraitSetForProperty(TraitProperty Property)
Return the trait set for which Property is a property.
LLVM_ABI int getBestVariantMatchForContext(const SmallVectorImpl< VariantMatchInfo > &VMIs, const OMPContext &Ctx)
Return the index (into VMIs) of the variant with the highest score from the ones applicable in Ctx.
LLVM_ABI StringRef getOpenMPContextTraitSetName(TraitSet Kind)
Return a textual representation of the trait set Kind.
LLVM_ABI StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind, StringRef RawString)
Return a textual representation of the trait property Kind, which might be the raw string we parsed (...
LLVM_ABI TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set, TraitSelector Selector, StringRef Str)
Parse Str and return the trait property it matches in the set Set and selector Selector or TraitPrope...
LLVM_ABI StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind)
Return a textual representation of the trait selector Kind.
LLVM_ABI std::string listOpenMPContextTraitSelectors(TraitSet Set)
Return a string listing all trait selectors for Set.
TraitSet
OpenMP Context related IDs and helpers.
LLVM_ABI TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property)
Return the trait selector for which Property is a property.
LLVM_ABI TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector)
Return the trait property for a singleton selector Selector.
TraitSelector
IDs for all OpenMP context selector trait (device={kind/isa...}/...).
LLVM_ABI bool isVariantApplicableInContext(const VariantMatchInfo &VMI, const OMPContext &Ctx, bool DeviceOrImplementationSetOnly=false)
Return true if VMI is applicable in Ctx, that is, all traits required by VMI are available in the Ope...
LLVM_ABI TraitSet getOpenMPContextTraitSetKind(StringRef Str)
Parse Str and return the trait set it matches or TraitSet::invalid.
TraitProperty
IDs for all OpenMP context trait properties (host/gpu/bsc/llvm/...)
LLVM_ABI bool isValidTraitPropertyForTraitSetAndSelector(TraitProperty Property, TraitSelector Selector, TraitSet Set)
Return true if Property can be nested in Selector and Set.
LLVM_ABI std::string listOpenMPContextTraitProperties(TraitSet Set, TraitSelector Selector)
Return a string listing all trait properties for Set and Selector.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
The context for a source location is made up of active property traits, e.g., device={kind(host)}...
LLVM_ABI OMPContext(bool IsDeviceCompilation, Triple TargetTriple, Triple TargetOffloadTriple, int DeviceNum)
Variant match information describes the required traits and how they are scored (via the ScoresMap).
SmallVector< StringRef, 8 > ISATraits
SmallVector< TraitProperty, 8 > ConstructTraits
SmallDenseMap< TraitProperty, APInt > ScoreMap