24#define DEBUG_TYPE "openmp-ir-builder"
30 Triple TargetOffloadTriple,
int DeviceNum) {
32 if (!TargetOffloadTriple.
getTriple().empty() && DeviceNum > -1) {
34 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_nohost));
35 switch (TargetOffloadTriple.
getArch()) {
52 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_cpu));
58 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_gpu));
64#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
65 if (TraitSelector::TraitSelectorEnum == TraitSelector::target_device_arch) { \
66 if (TargetOffloadTriple.getArch() == Triple::parseArch(Str)) \
67 ActiveTraits.set(unsigned(TraitProperty::Enum)); \
69#include "llvm/Frontend/OpenMP/OMPKinds.def"
74 ? TraitProperty::device_kind_nohost
75 : TraitProperty::device_kind_host));
76 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_host));
77 switch (TargetTriple.
getArch()) {
94 ActiveTraits.set(
unsigned(TraitProperty::device_kind_cpu));
95 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_cpu));
101 ActiveTraits.set(
unsigned(TraitProperty::device_kind_gpu));
102 ActiveTraits.set(
unsigned(TraitProperty::target_device_kind_gpu));
109#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
110 if (TraitSelector::TraitSelectorEnum == TraitSelector::device_arch || \
111 TraitSelector::TraitSelectorEnum == TraitSelector::target_device_arch) { \
112 if (TargetTriple.getArch() == Triple::parseArch(Str)) \
113 ActiveTraits.set(unsigned(TraitProperty::Enum)); \
115#include "llvm/Frontend/OpenMP/OMPKinds.def"
123 ActiveTraits.set(
unsigned(TraitProperty::implementation_vendor_llvm));
126 ActiveTraits.set(
unsigned(TraitProperty::user_condition_true));
129 ActiveTraits.set(
unsigned(TraitProperty::device_kind_any));
133 <<
"] New OpenMP context with the following properties:\n";
146 if (
C0.size() >
C1.size())
148 auto It0 =
C0.begin(), End0 =
C0.end();
149 auto It1 =
C1.begin(), End1 =
C1.end();
150 while (It0 != End0) {
183 {TraitProperty::user_condition_true, TraitProperty::user_condition_false,
184 TraitProperty::user_condition_unknown})
189 return llvm::is_contained(VMI1.ISATraits, Trait);
197 bool DeviceOrImplementationSetOnly) {
201 enum MatchKind { MK_ALL, MK_ANY, MK_NONE };
203 MatchKind MK = MK_ALL;
207 unsigned(TraitProperty::implementation_extension_match_any)))
210 unsigned(TraitProperty::implementation_extension_match_none)))
213 bool AnyTraitMatched =
false;
219 bool WasFound) ->
bool {
220 AnyTraitMatched |= WasFound;
226 if ((WasFound && MK == MK_ALL) || (!WasFound && MK == MK_NONE))
234 <<
" was not in the OpenMP context but match kind is all.\n";
238 <<
" was in the OpenMP context but match kind is none.\n";
245 if (DeviceOrImplementationSetOnly &&
248 TraitSet::implementation)
254 TraitSelector::implementation_extension)
257 bool IsActiveTrait = Ctx.ActiveTraits.test(
unsigned(
Property));
261 if (
Property == TraitProperty::device_isa___ANY ||
262 Property == TraitProperty::target_device_isa___ANY)
264 return Trait.Property != Property || Ctx.matchesISATrait(Trait.Name);
267 if (!HandleTrait(
Property, IsActiveTrait))
270 if (MK == MK_ANY && AnyTraitMatched)
274 if (!DeviceOrImplementationSetOnly) {
277 unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size();
280 TraitSet::construct &&
281 "Variant context is ill-formed!");
286 unsigned SearchStart = ConstructIdx;
287 bool FoundInOrder =
false;
288 while (!FoundInOrder && ConstructIdx != NoConstructTraits)
289 FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] ==
Property);
290 if (!FoundInOrder && MK != MK_ALL)
291 ConstructIdx = SearchStart;
292 if (ConstructMatches && FoundInOrder)
293 ConstructMatches->
push_back(ConstructIdx - 1);
295 if (!HandleTrait(
Property, FoundInOrder)) {
298 <<
" was not nested properly.\n");
308 if (ConstructMatches &&
310 ConstructIdx = NoConstructTraits;
313 while (ConstructIdx > 0 &&
314 Ctx.ConstructTraits[ConstructIdx - 1] !=
Property)
316 assert(ConstructIdx > 0 &&
"Previously matched construct not found!");
317 (*ConstructMatches)[
I - 1] = --ConstructIdx;
323 Ctx.ConstructTraits) &&
324 "Broken invariant!");
327 if (MK == MK_ANY && !AnyTraitMatched) {
329 <<
"] None of the properties was in the OpenMP context "
330 "but match kind is any.\n");
339 bool DeviceOrImplementationSetOnly) {
341 VMI, Ctx,
nullptr, DeviceOrImplementationSetOnly);
354 Score +=
Value.zextOrTrunc(Width);
356 auto AddPowerOfTwo = [&](
unsigned Exponent) {
360 unsigned NoConstructTraits = Ctx.ConstructTraits.size();
364 if (!ScoredSelectors.
insert(Selector).second)
367 AddScore(*UserScore);
371 case TraitSelector::device_kind:
372 case TraitSelector::target_device_kind:
373 AddPowerOfTwo(NoConstructTraits);
375 case TraitSelector::device_arch:
376 case TraitSelector::target_device_arch:
377 AddPowerOfTwo(NoConstructTraits + 1);
379 case TraitSelector::device_isa:
380 case TraitSelector::target_device_isa:
381 AddPowerOfTwo(NoConstructTraits + 2);
392 Property == TraitProperty::device_kind_any ||
393 Property == TraitProperty::target_device_kind_any)
397 It == VMI.
ScoreMap.end() ?
nullptr : &It->second);
401 "Mismatch in the construct traits!");
402 for (
unsigned Match : ConstructMatches) {
404 AddPowerOfTwo(Match);
418 APInt BestScore(1, 0);
421 for (
unsigned u = 0, e = VMIs.
size(); u < e; ++u) {
427 VMI, Ctx, &ConstructMatches,
435 if (Score.
ult(BestScore))
437 if (Score.
ugt(BestScore)) {
448 for (
unsigned Idx : BestVMIIdxs) {
454 auto *It =
llvm::find_if(BestVMIIdxs, [&](
unsigned OtherIdx) {
457 if (It == BestVMIIdxs.
end())
466#define OMP_TRAIT_SET(Enum, Str) .Case(Str, TraitSet::Enum)
467#include "llvm/Frontend/OpenMP/OMPKinds.def"
474#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
475 case TraitSelector::Enum: \
476 return TraitSet::TraitSetEnum;
477#include "llvm/Frontend/OpenMP/OMPKinds.def"
484#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
485 case TraitProperty::Enum: \
486 return TraitSet::TraitSetEnum;
487#include "llvm/Frontend/OpenMP/OMPKinds.def"
493#define OMP_TRAIT_SET(Enum, Str) \
494 case TraitSet::Enum: \
496#include "llvm/Frontend/OpenMP/OMPKinds.def"
503 if (Set == TraitSet::target_device && S ==
"kind")
504 return TraitSelector::target_device_kind;
505 if (Set == TraitSet::target_device && S ==
"arch")
506 return TraitSelector::target_device_arch;
507 if (Set == TraitSet::target_device && S ==
"isa")
508 return TraitSelector::target_device_isa;
510#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
511 .Case(Str, TraitSelector::Enum)
512#include "llvm/Frontend/OpenMP/OMPKinds.def"
513 .
Default(TraitSelector::invalid);
518#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
519 case TraitProperty::Enum: \
520 return TraitSelector::TraitSelectorEnum;
521#include "llvm/Frontend/OpenMP/OMPKinds.def"
527#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
528 case TraitSelector::Enum: \
530#include "llvm/Frontend/OpenMP/OMPKinds.def"
539 if (Set == TraitSet::device && Selector == TraitSelector::device_isa)
540 return TraitProperty::device_isa___ANY;
541 if (Set == TraitSet::target_device &&
542 Selector == TraitSelector::target_device_isa)
543 return TraitProperty::target_device_isa___ANY;
544#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
545 if (Set == TraitSet::TraitSetEnum && Str == S) \
546 return TraitProperty::Enum;
547#include "llvm/Frontend/OpenMP/OMPKinds.def"
548 return TraitProperty::invalid;
554#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
555 .Case(Str, Selector == TraitSelector::TraitSelectorEnum \
556 ? TraitProperty::Enum \
557 : TraitProperty::invalid)
558#include "llvm/Frontend/OpenMP/OMPKinds.def"
559 .
Default(TraitProperty::invalid);
563 if (Kind == TraitProperty::device_isa___ANY)
565 if (Kind == TraitProperty::target_device_isa___ANY)
568#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
569 case TraitProperty::Enum: \
571#include "llvm/Frontend/OpenMP/OMPKinds.def"
577#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
578 case TraitProperty::Enum: \
579 return "(" #TraitSetEnum "," #TraitSelectorEnum "," Str ")";
580#include "llvm/Frontend/OpenMP/OMPKinds.def"
587 bool &AllowsTraitScore,
588 bool &RequiresProperty) {
589 AllowsTraitScore = Set != TraitSet::construct && Set != TraitSet::device &&
590 Set != TraitSet::target_device;
592#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
593 case TraitSelector::Enum: \
594 RequiresProperty = ReqProp; \
595 return Set == TraitSet::TraitSetEnum;
596#include "llvm/Frontend/OpenMP/OMPKinds.def"
604#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
605 case TraitProperty::Enum: \
606 return Set == TraitSet::TraitSetEnum && \
607 Selector == TraitSelector::TraitSelectorEnum;
608#include "llvm/Frontend/OpenMP/OMPKinds.def"
615#define OMP_TRAIT_SET(Enum, Str) \
616 if (StringRef(Str) != "invalid") \
617 S.append("'").append(Str).append("'").append(" ");
618#include "llvm/Frontend/OpenMP/OMPKinds.def"
625#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
626 if (TraitSet::TraitSetEnum == Set && StringRef(Str) != "Invalid") \
627 S.append("'").append(Str).append("'").append(" ");
628#include "llvm/Frontend/OpenMP/OMPKinds.def"
637#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
638 if (TraitSet::TraitSetEnum == Set && \
639 TraitSelector::TraitSelectorEnum == Selector && \
640 StringRef(Str) != "invalid") \
641 S.append("'").append(Str).append("'").append(" ");
642#include "llvm/Frontend/OpenMP/OMPKinds.def"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseSet and SmallDenseSet classes.
static APInt getVariantMatchScore(const VariantMatchInfo &VMI, const OMPContext &Ctx, SmallVectorImpl< unsigned > &ConstructMatches)
static bool isOrderedSubset(ArrayRef< T > C0, ArrayRef< T > C1)
Return true if C0 is an ordered subsequence of C1.
static int isVariantApplicableInContextHelper(const VariantMatchInfo &VMI, const OMPContext &Ctx, SmallVectorImpl< unsigned > *ConstructMatches, bool DeviceOrImplementationSetOnly)
static bool isStrictSubset(const VariantMatchInfo &VMI0, const VariantMatchInfo &VMI1)
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.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
LLVM_ABI void print(raw_ostream &OS, bool isSigned) const
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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
Implements a dense probed hash-table based set with some number of buckets stored inline.
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
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
#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.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_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.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
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)
A device or target_device isa property and the ISA name it requires.
Variant match information describes the required traits and how they are scored (via the ScoresMap).
SmallVector< TraitProperty, 8 > ConstructTraits
SmallVector< ISATrait, 8 > ISATraits
SmallDenseMap< TraitProperty, APInt > ScoreMap