LLVM 23.0.0git
OMPContext.cpp
Go to the documentation of this file.
1//===- OMPContext.cpp ------ Collection of helpers for OpenMP contexts ----===//
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 implements helper functions and classes to deal with OpenMP
11/// contexts as used by `[begin/end] declare variant` and `metadirective`.
12///
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/StringRef.h"
18#include "llvm/Support/Debug.h"
21
22#define DEBUG_TYPE "openmp-ir-builder"
23
24using namespace llvm;
25using namespace omp;
26
27OMPContext::OMPContext(bool IsDeviceCompilation, Triple TargetTriple,
28 Triple TargetOffloadTriple, int DeviceNum) {
29 // Add the appropriate target device kind trait based on the target triple
30 if (!TargetOffloadTriple.getTriple().empty() && DeviceNum > -1) {
31 // If target triple is present, then target device is not a host
32 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_nohost));
33 switch (TargetOffloadTriple.getArch()) {
34 case Triple::arm:
35 case Triple::armeb:
36 case Triple::aarch64:
39 case Triple::mips:
40 case Triple::mipsel:
41 case Triple::mips64:
43 case Triple::ppc:
44 case Triple::ppcle:
45 case Triple::ppc64:
46 case Triple::ppc64le:
47 case Triple::systemz:
48 case Triple::x86:
49 case Triple::x86_64:
50 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_cpu));
51 break;
52 case Triple::amdgcn:
53 case Triple::nvptx:
54 case Triple::nvptx64:
55 case Triple::spirv64:
56 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_gpu));
57 break;
58 default:
59 break;
60 }
61 // Add the appropriate device architecture trait based on the triple.
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)); \
66 }
67#include "llvm/Frontend/OpenMP/OMPKinds.def"
68 } else {
69 // Add the appropriate device kind trait based on the triple and the
70 // IsDeviceCompilation flag.
71 ActiveTraits.set(unsigned(IsDeviceCompilation
72 ? TraitProperty::device_kind_nohost
73 : TraitProperty::device_kind_host));
74 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_host));
75 switch (TargetTriple.getArch()) {
76 case Triple::arm:
77 case Triple::armeb:
78 case Triple::aarch64:
81 case Triple::mips:
82 case Triple::mipsel:
83 case Triple::mips64:
85 case Triple::ppc:
86 case Triple::ppcle:
87 case Triple::ppc64:
88 case Triple::ppc64le:
89 case Triple::systemz:
90 case Triple::x86:
91 case Triple::x86_64:
92 ActiveTraits.set(unsigned(TraitProperty::device_kind_cpu));
93 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_cpu));
94 break;
95 case Triple::amdgcn:
96 case Triple::nvptx:
97 case Triple::nvptx64:
98 case Triple::spirv64:
99 ActiveTraits.set(unsigned(TraitProperty::device_kind_gpu));
100 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_gpu));
101 break;
102 default:
103 break;
104 }
105
106 // Add the appropriate device architecture trait based on the triple.
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)); \
112 }
113#include "llvm/Frontend/OpenMP/OMPKinds.def"
114
115 // TODO: What exactly do we want to see as device ISA trait?
116 // The discussion on the list did not seem to have come to an agreed
117 // upon solution.
118
119 // LLVM is the "OpenMP vendor" but we could also interpret vendor as the
120 // target vendor.
121 ActiveTraits.set(unsigned(TraitProperty::implementation_vendor_llvm));
122
123 // The user condition true is accepted but not false.
124 ActiveTraits.set(unsigned(TraitProperty::user_condition_true));
125
126 // This is for sure some device.
127 ActiveTraits.set(unsigned(TraitProperty::device_kind_any));
128
129 LLVM_DEBUG({
130 dbgs() << "[" << DEBUG_TYPE
131 << "] New OpenMP context with the following properties:\n";
132 for (unsigned Bit : ActiveTraits.set_bits()) {
133 TraitProperty Property = TraitProperty(Bit);
134 dbgs() << "\t " << getOpenMPContextTraitPropertyFullName(Property)
135 << "\n";
136 }
137 });
138 }
139}
140
141/// Return true if \p C0 is a subset of \p C1. Note that both arrays are
142/// expected to be sorted.
143template <typename T> static bool isSubset(ArrayRef<T> C0, ArrayRef<T> C1) {
144#ifdef EXPENSIVE_CHECKS
146 "Expected sorted arrays!");
147#endif
148 if (C0.size() > C1.size())
149 return false;
150 auto It0 = C0.begin(), End0 = C0.end();
151 auto It1 = C1.begin(), End1 = C1.end();
152 while (It0 != End0) {
153 if (It1 == End1)
154 return false;
155 if (*It0 == *It1) {
156 ++It0;
157 ++It1;
158 continue;
159 }
160 ++It0;
161 }
162 return true;
163}
164
165/// Return true if \p C0 is a strict subset of \p C1. Note that both arrays are
166/// expected to be sorted.
167template <typename T>
169 if (C0.size() >= C1.size())
170 return false;
171 return isSubset<T>(C0, C1);
172}
173
174static bool isStrictSubset(const VariantMatchInfo &VMI0,
175 const VariantMatchInfo &VMI1) {
176 // If all required traits are a strict subset and the ordered vectors storing
177 // the construct traits, we say it is a strict subset. Note that the latter
178 // relation is not required to be strict.
179 if (VMI0.RequiredTraits.count() >= VMI1.RequiredTraits.count())
180 return false;
181 for (unsigned Bit : VMI0.RequiredTraits.set_bits())
182 if (!VMI1.RequiredTraits.test(Bit))
183 return false;
185 return false;
186 return true;
187}
188
189static int
191 const OMPContext &Ctx,
192 SmallVectorImpl<unsigned> *ConstructMatches,
193 bool DeviceOrImplementationSetOnly) {
194
195 // The match kind determines if we need to match all traits, any of the
196 // traits, or none of the traits for it to be an applicable context.
197 enum MatchKind { MK_ALL, MK_ANY, MK_NONE };
198
199 MatchKind MK = MK_ALL;
200 // Determine the match kind the user wants, "all" is the default and provided
201 // to the user only for completeness.
202 if (VMI.RequiredTraits.test(
203 unsigned(TraitProperty::implementation_extension_match_any)))
204 MK = MK_ANY;
205 if (VMI.RequiredTraits.test(
206 unsigned(TraitProperty::implementation_extension_match_none)))
207 MK = MK_NONE;
208
209 // Helper to deal with a single property that was (not) found in the OpenMP
210 // context based on the match kind selected by the user via
211 // `implementation={extensions(match_[all,any,none])}'
212 auto HandleTrait = [MK](TraitProperty Property,
213 bool WasFound) -> std::optional<bool> /* Result */ {
214 // For kind "any" a single match is enough but we ignore non-matched
215 // properties.
216 if (MK == MK_ANY) {
217 if (WasFound)
218 return true;
219 return std::nullopt;
220 }
221
222 // In "all" or "none" mode we accept a matching or non-matching property
223 // respectively and move on. We are not done yet!
224 if ((WasFound && MK == MK_ALL) || (!WasFound && MK == MK_NONE))
225 return std::nullopt;
226
227 // We missed a property, provide some debug output and indicate failure.
228 LLVM_DEBUG({
229 if (MK == MK_ALL)
230 dbgs() << "[" << DEBUG_TYPE << "] Property "
231 << getOpenMPContextTraitPropertyName(Property, "")
232 << " was not in the OpenMP context but match kind is all.\n";
233 if (MK == MK_NONE)
234 dbgs() << "[" << DEBUG_TYPE << "] Property "
235 << getOpenMPContextTraitPropertyName(Property, "")
236 << " was in the OpenMP context but match kind is none.\n";
237 });
238 return false;
239 };
240
241 for (unsigned Bit : VMI.RequiredTraits.set_bits()) {
242 TraitProperty Property = TraitProperty(Bit);
243 if (DeviceOrImplementationSetOnly &&
244 getOpenMPContextTraitSetForProperty(Property) != TraitSet::device &&
246 TraitSet::implementation)
247 continue;
248
249 // So far all extensions are handled elsewhere, we skip them here as they
250 // are not part of the OpenMP context.
252 TraitSelector::implementation_extension)
253 continue;
254
255 bool IsActiveTrait = Ctx.ActiveTraits.test(unsigned(Property));
256
257 // We overwrite the isa trait as it is actually up to the OMPContext hook to
258 // check the raw string(s).
259 if (Property == TraitProperty::device_isa___ANY)
260 IsActiveTrait = llvm::all_of(VMI.ISATraits, [&](StringRef RawString) {
261 return Ctx.matchesISATrait(RawString);
262 });
263 if (Property == TraitProperty::target_device_isa___ANY)
264 IsActiveTrait = llvm::all_of(VMI.ISATraits, [&](StringRef RawString) {
265 return Ctx.matchesISATrait(RawString);
266 });
267
268 if (std::optional<bool> Result = HandleTrait(Property, IsActiveTrait))
269 return *Result;
270 }
271
272 if (!DeviceOrImplementationSetOnly) {
273 // We could use isSubset here but we also want to record the match
274 // locations.
275 unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size();
276 for (TraitProperty Property : VMI.ConstructTraits) {
278 TraitSet::construct &&
279 "Variant context is ill-formed!");
280
281 // Verify the nesting.
282 bool FoundInOrder = false;
283 while (!FoundInOrder && ConstructIdx != NoConstructTraits)
284 FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] == Property);
285 if (ConstructMatches)
286 ConstructMatches->push_back(ConstructIdx - 1);
287
288 if (std::optional<bool> Result = HandleTrait(Property, FoundInOrder))
289 return *Result;
290
291 if (!FoundInOrder) {
292 LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Construct property "
293 << getOpenMPContextTraitPropertyName(Property, "")
294 << " was not nested properly.\n");
295 return false;
296 }
297
298 // TODO: Verify SIMD
299 }
300
301 assert(isSubset<TraitProperty>(VMI.ConstructTraits, Ctx.ConstructTraits) &&
302 "Broken invariant!");
303 }
304
305 if (MK == MK_ANY) {
306 LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE
307 << "] None of the properties was in the OpenMP context "
308 "but match kind is any.\n");
309 return false;
310 }
311
312 return true;
313}
314
316 const VariantMatchInfo &VMI, const OMPContext &Ctx,
317 bool DeviceOrImplementationSetOnly) {
319 VMI, Ctx, /* ConstructMatches */ nullptr, DeviceOrImplementationSetOnly);
320}
321
323 const OMPContext &Ctx,
324 SmallVectorImpl<unsigned> &ConstructMatches) {
325 APInt Score(64, 1);
326
327 unsigned NoConstructTraits = VMI.ConstructTraits.size();
328 for (unsigned Bit : VMI.RequiredTraits.set_bits()) {
329 TraitProperty Property = TraitProperty(Bit);
330 // If there is a user score attached, use it.
331 if (VMI.ScoreMap.count(Property)) {
332 const APInt &UserScore = VMI.ScoreMap.lookup(Property);
333 assert(UserScore.uge(0) && "Expect non-negative user scores!");
334 Score += UserScore.getZExtValue();
335 continue;
336 }
337
338 switch (getOpenMPContextTraitSetForProperty(Property)) {
339 case TraitSet::construct:
340 // We handle the construct traits later via the VMI.ConstructTraits
341 // container.
342 continue;
343 case TraitSet::implementation:
344 // No effect on the score (implementation defined).
345 continue;
346 case TraitSet::user:
347 // No effect on the score.
348 continue;
349 case TraitSet::device:
350 // Handled separately below.
351 break;
352 case TraitSet::target_device:
353 // TODO: Handling separately.
354 break;
355 case TraitSet::invalid:
356 llvm_unreachable("Unknown trait set is not to be used!");
357 }
358
359 // device={kind(any)} is "as if" no kind selector was specified.
360 if (Property == TraitProperty::device_kind_any)
361 continue;
362 if (Property == TraitProperty::target_device_kind_any)
363 continue;
364
366 case TraitSelector::device_kind:
367 Score += (1ULL << (NoConstructTraits + 0));
368 continue;
369 case TraitSelector::device_arch:
370 Score += (1ULL << (NoConstructTraits + 1));
371 continue;
372 case TraitSelector::device_isa:
373 Score += (1ULL << (NoConstructTraits + 2));
374 continue;
375 case TraitSelector::target_device_kind:
376 Score += (1ULL << (NoConstructTraits + 0));
377 continue;
378 case TraitSelector::target_device_arch:
379 Score += (1ULL << (NoConstructTraits + 1));
380 continue;
381 case TraitSelector::target_device_isa:
382 Score += (1ULL << (NoConstructTraits + 2));
383 continue;
384 default:
385 continue;
386 }
387 }
388
389 unsigned ConstructIdx = 0;
390 assert(NoConstructTraits == ConstructMatches.size() &&
391 "Mismatch in the construct traits!");
392 for (TraitProperty Property : VMI.ConstructTraits) {
394 TraitSet::construct &&
395 "Ill-formed variant match info!");
396 (void)Property;
397 // ConstructMatches is the position p - 1 and we need 2^(p-1).
398 Score += (1ULL << ConstructMatches[ConstructIdx++]);
399 }
400
401 LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Variant has a score of " << Score
402 << "\n");
403 return Score;
404}
405
407 const SmallVectorImpl<VariantMatchInfo> &VMIs, const OMPContext &Ctx) {
408
409 APInt BestScore(64, 0);
410 int BestVMIIdx = -1;
411 const VariantMatchInfo *BestVMI = nullptr;
412
413 for (unsigned u = 0, e = VMIs.size(); u < e; ++u) {
414 const VariantMatchInfo &VMI = VMIs[u];
415
416 SmallVector<unsigned, 8> ConstructMatches;
417 // If the variant is not applicable its not the best.
419 VMI, Ctx, &ConstructMatches,
420 /* DeviceOrImplementationSetOnly */ false))
421 continue;
422 // Check if its clearly not the best.
423 APInt Score = getVariantMatchScore(VMI, Ctx, ConstructMatches);
424 if (Score.ult(BestScore))
425 continue;
426 // Equal score need subset checks.
427 if (Score.eq(BestScore)) {
428 // Strict subset are never best.
429 if (isStrictSubset(VMI, *BestVMI))
430 continue;
431 // Same score and the current best is no strict subset so we keep it.
432 if (!isStrictSubset(*BestVMI, VMI))
433 continue;
434 }
435 // New best found.
436 BestVMI = &VMI;
437 BestVMIIdx = u;
438 BestScore = Score;
439 }
440
441 return BestVMIIdx;
442}
443
445 return StringSwitch<TraitSet>(S)
446#define OMP_TRAIT_SET(Enum, Str) .Case(Str, TraitSet::Enum)
447#include "llvm/Frontend/OpenMP/OMPKinds.def"
448 .Default(TraitSet::invalid);
449}
450
453 switch (Selector) {
454#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
455 case TraitSelector::Enum: \
456 return TraitSet::TraitSetEnum;
457#include "llvm/Frontend/OpenMP/OMPKinds.def"
458 }
459 llvm_unreachable("Unknown trait selector!");
460}
463 switch (Property) {
464#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
465 case TraitProperty::Enum: \
466 return TraitSet::TraitSetEnum;
467#include "llvm/Frontend/OpenMP/OMPKinds.def"
468 }
469 llvm_unreachable("Unknown trait set!");
470}
472 switch (Kind) {
473#define OMP_TRAIT_SET(Enum, Str) \
474 case TraitSet::Enum: \
475 return Str;
476#include "llvm/Frontend/OpenMP/OMPKinds.def"
477 }
478 llvm_unreachable("Unknown trait set!");
479}
480
482 TraitSet Set) {
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);
494}
497 switch (Property) {
498#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
499 case TraitProperty::Enum: \
500 return TraitSelector::TraitSelectorEnum;
501#include "llvm/Frontend/OpenMP/OMPKinds.def"
502 }
503 llvm_unreachable("Unknown trait set!");
504}
506 switch (Kind) {
507#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
508 case TraitSelector::Enum: \
509 return Str;
510#include "llvm/Frontend/OpenMP/OMPKinds.def"
511 }
512 llvm_unreachable("Unknown trait selector!");
513}
514
516 TraitSet Set, TraitSelector Selector, StringRef S) {
517 // Special handling for `device={isa(...)}` as we accept anything here. It is
518 // up to the target to decide if the feature is available.
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;
529}
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);
540}
542 StringRef RawString) {
543 if (Kind == TraitProperty::device_isa___ANY)
544 return RawString;
545 if (Kind == TraitProperty::target_device_isa___ANY)
546 return RawString;
547 switch (Kind) {
548#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
549 case TraitProperty::Enum: \
550 return Str;
551#include "llvm/Frontend/OpenMP/OMPKinds.def"
552 }
553 llvm_unreachable("Unknown trait property!");
554}
556 switch (Kind) {
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"
561 }
562 llvm_unreachable("Unknown trait property!");
563}
564
566 TraitSet Set,
567 bool &AllowsTraitScore,
568 bool &RequiresProperty) {
569 AllowsTraitScore = Set != TraitSet::construct && Set != TraitSet::device &&
570 Set != TraitSet::target_device;
571 switch (Selector) {
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"
577 }
578 llvm_unreachable("Unknown trait selector!");
579}
580
582 TraitProperty Property, TraitSelector Selector, TraitSet Set) {
583 switch (Property) {
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"
589 }
590 llvm_unreachable("Unknown trait property!");
591}
592
594 std::string S;
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"
599 S.pop_back();
600 return S;
601}
602
604 std::string S;
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"
609 S.pop_back();
610 return S;
611}
612
613std::string
615 TraitSelector Selector) {
616 std::string S;
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"
623 if (S.empty())
624 return "<none>";
625 S.pop_back();
626 return S;
627}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define DEBUG_TYPE
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...
#define LLVM_DEBUG(...)
Definition Debug.h:114
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1555
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1118
bool eq(const APInt &RHS) const
Equality comparison.
Definition APInt.h:1086
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Definition APInt.h:1228
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:131
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
iterator begin() const
Definition ArrayRef.h:130
bool test(unsigned Idx) const
Definition BitVector.h:480
size_type count() const
count - Returns the number of bits which are set.
Definition BitVector.h:181
iterator_range< const_set_bits_iterator > set_bits() const
Definition BitVector.h:159
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.
Definition StringRef.h:55
A switch()-like statement whose cases are string literals.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:427
const std::string & getTriple() const
Definition Triple.h:496
#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.
Definition OMPContext.h:34
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...}/...).
Definition OMPContext.h:40
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/...)
Definition OMPContext.h:46
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.
Definition STLExtras.h:1739
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
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...
Definition STLExtras.h:1970
The context for a source location is made up of active property traits, e.g., device={kind(host)}...
Definition OMPContext.h:164
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).
Definition OMPContext.h:124
SmallVector< StringRef, 8 > ISATraits
Definition OMPContext.h:156
SmallVector< TraitProperty, 8 > ConstructTraits
Definition OMPContext.h:157
SmallDenseMap< TraitProperty, APInt > ScoreMap
Definition OMPContext.h:158