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) {
184 bool DeviceOrImplementationSetOnly) {
188 enum MatchKind { MK_ALL, MK_ANY, MK_NONE };
190 MatchKind MK = MK_ALL;
194 unsigned(TraitProperty::implementation_extension_match_any)))
197 unsigned(TraitProperty::implementation_extension_match_none)))
204 bool WasFound) -> std::optional<bool> {
215 if ((WasFound && MK == MK_ALL) || (!WasFound && MK == MK_NONE))
223 <<
" was not in the OpenMP context but match kind is all.\n";
227 <<
" was in the OpenMP context but match kind is none.\n";
234 if (DeviceOrImplementationSetOnly &&
237 TraitSet::implementation)
243 TraitSelector::implementation_extension)
246 bool IsActiveTrait = Ctx.ActiveTraits.test(
unsigned(Property));
250 if (Property == TraitProperty::device_isa___ANY)
252 return Ctx.matchesISATrait(RawString);
254 if (Property == TraitProperty::target_device_isa___ANY)
256 return Ctx.matchesISATrait(RawString);
259 if (std::optional<bool> Result = HandleTrait(Property, IsActiveTrait))
263 if (!DeviceOrImplementationSetOnly) {
266 unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size();
269 TraitSet::construct &&
270 "Variant context is ill-formed!");
273 bool FoundInOrder =
false;
274 while (!FoundInOrder && ConstructIdx != NoConstructTraits)
275 FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] == Property);
276 if (ConstructMatches)
277 ConstructMatches->
push_back(ConstructIdx - 1);
279 if (std::optional<bool> Result = HandleTrait(Property, FoundInOrder))
285 <<
" was not nested properly.\n");
293 "Broken invariant!");
298 <<
"] None of the properties was in the OpenMP context "
299 "but match kind is any.\n");
308 bool DeviceOrImplementationSetOnly) {
310 VMI, Ctx,
nullptr, DeviceOrImplementationSetOnly);
324 assert(UserScore.
uge(0) &&
"Expect non-negative user scores!");
330 case TraitSet::construct:
334 case TraitSet::implementation:
340 case TraitSet::device:
343 case TraitSet::target_device:
346 case TraitSet::invalid:
351 if (Property == TraitProperty::device_kind_any)
353 if (Property == TraitProperty::target_device_kind_any)
357 case TraitSelector::device_kind:
358 Score += (1ULL << (NoConstructTraits + 0));
360 case TraitSelector::device_arch:
361 Score += (1ULL << (NoConstructTraits + 1));
363 case TraitSelector::device_isa:
364 Score += (1ULL << (NoConstructTraits + 2));
366 case TraitSelector::target_device_kind:
367 Score += (1ULL << (NoConstructTraits + 0));
369 case TraitSelector::target_device_arch:
370 Score += (1ULL << (NoConstructTraits + 1));
372 case TraitSelector::target_device_isa:
373 Score += (1ULL << (NoConstructTraits + 2));
380 unsigned ConstructIdx = 0;
381 assert(NoConstructTraits == ConstructMatches.
size() &&
382 "Mismatch in the construct traits!");
385 TraitSet::construct &&
386 "Ill-formed variant match info!");
389 Score += (1ULL << ConstructMatches[ConstructIdx++]);
400 APInt BestScore(64, 0);
404 for (
unsigned u = 0, e = VMIs.
size(); u < e; ++u) {
410 VMI, Ctx, &ConstructMatches,
415 if (Score.
ult(BestScore))
418 if (Score.
eq(BestScore)) {
437#define OMP_TRAIT_SET(Enum, Str) .Case(Str, TraitSet::Enum)
438#include "llvm/Frontend/OpenMP/OMPKinds.def"
445#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
446 case TraitSelector::Enum: \
447 return TraitSet::TraitSetEnum;
448#include "llvm/Frontend/OpenMP/OMPKinds.def"
455#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
456 case TraitProperty::Enum: \
457 return TraitSet::TraitSetEnum;
458#include "llvm/Frontend/OpenMP/OMPKinds.def"
464#define OMP_TRAIT_SET(Enum, Str) \
465 case TraitSet::Enum: \
467#include "llvm/Frontend/OpenMP/OMPKinds.def"
474 if (Set == TraitSet::target_device && S ==
"kind")
475 return TraitSelector::target_device_kind;
476 if (Set == TraitSet::target_device && S ==
"arch")
477 return TraitSelector::target_device_arch;
478 if (Set == TraitSet::target_device && S ==
"isa")
479 return TraitSelector::target_device_isa;
481#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
482 .Case(Str, TraitSelector::Enum)
483#include "llvm/Frontend/OpenMP/OMPKinds.def"
484 .
Default(TraitSelector::invalid);
489#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
490 case TraitProperty::Enum: \
491 return TraitSelector::TraitSelectorEnum;
492#include "llvm/Frontend/OpenMP/OMPKinds.def"
498#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
499 case TraitSelector::Enum: \
501#include "llvm/Frontend/OpenMP/OMPKinds.def"
510 if (Set == TraitSet::device && Selector == TraitSelector::device_isa)
511 return TraitProperty::device_isa___ANY;
512 if (Set == TraitSet::target_device &&
513 Selector == TraitSelector::target_device_isa)
514 return TraitProperty::target_device_isa___ANY;
515#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
516 if (Set == TraitSet::TraitSetEnum && Str == S) \
517 return TraitProperty::Enum;
518#include "llvm/Frontend/OpenMP/OMPKinds.def"
519 return TraitProperty::invalid;
525#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
526 .Case(Str, Selector == TraitSelector::TraitSelectorEnum \
527 ? TraitProperty::Enum \
528 : TraitProperty::invalid)
529#include "llvm/Frontend/OpenMP/OMPKinds.def"
530 .
Default(TraitProperty::invalid);
534 if (Kind == TraitProperty::device_isa___ANY)
536 if (Kind == TraitProperty::target_device_isa___ANY)
539#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
540 case TraitProperty::Enum: \
542#include "llvm/Frontend/OpenMP/OMPKinds.def"
548#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
549 case TraitProperty::Enum: \
550 return "(" #TraitSetEnum "," #TraitSelectorEnum "," Str ")";
551#include "llvm/Frontend/OpenMP/OMPKinds.def"
558 bool &AllowsTraitScore,
559 bool &RequiresProperty) {
560 AllowsTraitScore = Set != TraitSet::construct && Set != TraitSet::device &&
561 Set != TraitSet::target_device;
563#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
564 case TraitSelector::Enum: \
565 RequiresProperty = ReqProp; \
566 return Set == TraitSet::TraitSetEnum;
567#include "llvm/Frontend/OpenMP/OMPKinds.def"
575#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
576 case TraitProperty::Enum: \
577 return Set == TraitSet::TraitSetEnum && \
578 Selector == TraitSelector::TraitSelectorEnum;
579#include "llvm/Frontend/OpenMP/OMPKinds.def"
586#define OMP_TRAIT_SET(Enum, Str) \
587 if (StringRef(Str) != "invalid") \
588 S.append("'").append(Str).append("'").append(" ");
589#include "llvm/Frontend/OpenMP/OMPKinds.def"
596#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
597 if (TraitSet::TraitSetEnum == Set && StringRef(Str) != "Invalid") \
598 S.append("'").append(Str).append("'").append(" ");
599#include "llvm/Frontend/OpenMP/OMPKinds.def"
608#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
609 if (TraitSet::TraitSetEnum == Set && \
610 TraitSelector::TraitSelectorEnum == Selector && \
611 StringRef(Str) != "invalid") \
612 S.append("'").append(Str).append("'").append(" ");
613#include "llvm/Frontend/OpenMP/OMPKinds.def"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 isStrictSubset(const VariantMatchInfo &VMI0, const VariantMatchInfo &VMI1)
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
size_type count() const
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.
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