LLVM 24.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/DenseSet.h"
17#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/Debug.h"
22#include <algorithm>
23
24#define DEBUG_TYPE "openmp-ir-builder"
25
26using namespace llvm;
27using namespace omp;
28
29OMPContext::OMPContext(bool IsDeviceCompilation, Triple TargetTriple,
30 Triple TargetOffloadTriple, int DeviceNum) {
31 // Add the appropriate target device kind trait based on the target triple
32 if (!TargetOffloadTriple.getTriple().empty() && DeviceNum > -1) {
33 // If target triple is present, then target device is not a host
34 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_nohost));
35 switch (TargetOffloadTriple.getArch()) {
36 case Triple::arm:
37 case Triple::armeb:
38 case Triple::aarch64:
41 case Triple::mips:
42 case Triple::mipsel:
43 case Triple::mips64:
45 case Triple::ppc:
46 case Triple::ppcle:
47 case Triple::ppc64:
48 case Triple::ppc64le:
49 case Triple::systemz:
50 case Triple::x86:
51 case Triple::x86_64:
52 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_cpu));
53 break;
54 case Triple::amdgpu:
55 case Triple::nvptx:
56 case Triple::nvptx64:
57 case Triple::spirv64:
58 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_gpu));
59 break;
60 default:
61 break;
62 }
63 // Add the appropriate device architecture trait based on the triple.
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)); \
68 }
69#include "llvm/Frontend/OpenMP/OMPKinds.def"
70 } else {
71 // Add the appropriate device kind trait based on the triple and the
72 // IsDeviceCompilation flag.
73 ActiveTraits.set(unsigned(IsDeviceCompilation
74 ? TraitProperty::device_kind_nohost
75 : TraitProperty::device_kind_host));
76 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_host));
77 switch (TargetTriple.getArch()) {
78 case Triple::arm:
79 case Triple::armeb:
80 case Triple::aarch64:
83 case Triple::mips:
84 case Triple::mipsel:
85 case Triple::mips64:
87 case Triple::ppc:
88 case Triple::ppcle:
89 case Triple::ppc64:
90 case Triple::ppc64le:
91 case Triple::systemz:
92 case Triple::x86:
93 case Triple::x86_64:
94 ActiveTraits.set(unsigned(TraitProperty::device_kind_cpu));
95 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_cpu));
96 break;
97 case Triple::amdgpu:
98 case Triple::nvptx:
99 case Triple::nvptx64:
100 case Triple::spirv64:
101 ActiveTraits.set(unsigned(TraitProperty::device_kind_gpu));
102 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_gpu));
103 break;
104 default:
105 break;
106 }
107
108 // Add the appropriate device architecture trait based on the triple.
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)); \
114 }
115#include "llvm/Frontend/OpenMP/OMPKinds.def"
116
117 // TODO: What exactly do we want to see as device ISA trait?
118 // The discussion on the list did not seem to have come to an agreed
119 // upon solution.
120
121 // LLVM is the "OpenMP vendor" but we could also interpret vendor as the
122 // target vendor.
123 ActiveTraits.set(unsigned(TraitProperty::implementation_vendor_llvm));
124
125 // The user condition true is accepted but not false.
126 ActiveTraits.set(unsigned(TraitProperty::user_condition_true));
127
128 // This is for sure some device.
129 ActiveTraits.set(unsigned(TraitProperty::device_kind_any));
130
131 LLVM_DEBUG({
132 dbgs() << "[" << DEBUG_TYPE
133 << "] New OpenMP context with the following properties:\n";
134 for (unsigned Bit : ActiveTraits.set_bits()) {
137 << "\n";
138 }
139 });
140 }
141}
142
143/// Return true if \p C0 is an ordered subsequence of \p C1.
144template <typename T>
146 if (C0.size() > C1.size())
147 return false;
148 auto It0 = C0.begin(), End0 = C0.end();
149 auto It1 = C1.begin(), End1 = C1.end();
150 while (It0 != End0) {
151 if (It1 == End1)
152 return false;
153 if (*It0 == *It1) {
154 ++It0;
155 ++It1;
156 continue;
157 }
158 ++It1;
159 }
160 return true;
161}
162
163static bool isStrictSubset(const VariantMatchInfo &VMI0,
164 const VariantMatchInfo &VMI1) {
165 // VMI0 is a strict subset if its required traits are a subset of VMI1's, its
166 // construct traits are an ordered subsequence of VMI1's, and either relation
167 // is strict.
168 if (VMI0.RequiredTraits.count() > VMI1.RequiredTraits.count())
169 return false;
170 for (unsigned Bit : VMI0.RequiredTraits.set_bits())
171 if (!VMI1.RequiredTraits.test(Bit))
172 return false;
174 VMI1.ConstructTraits))
175 return false;
176 if (VMI0.RequiredTraits.count() < VMI1.RequiredTraits.count())
177 return true;
178 // With the same traits, only a repeated construct makes VMI0 strict.
179 if (VMI0.ConstructTraits.size() == VMI1.ConstructTraits.size())
180 return false;
181 // Different conditions or ISA names share a trait, so they can't be compared.
183 {TraitProperty::user_condition_true, TraitProperty::user_condition_false,
184 TraitProperty::user_condition_unknown})
185 if (VMI0.RequiredTraits.test(unsigned(Property)))
186 return false;
187 return llvm::all_of(VMI0.ISATraits,
188 [&](const VariantMatchInfo::ISATrait &Trait) {
189 return llvm::is_contained(VMI1.ISATraits, Trait);
190 });
191}
192
193static int
195 const OMPContext &Ctx,
196 SmallVectorImpl<unsigned> *ConstructMatches,
197 bool DeviceOrImplementationSetOnly) {
198
199 // The match kind determines if we need to match all traits, any of the
200 // traits, or none of the traits for it to be an applicable context.
201 enum MatchKind { MK_ALL, MK_ANY, MK_NONE };
202
203 MatchKind MK = MK_ALL;
204 // Determine the match kind the user wants, "all" is the default and provided
205 // to the user only for completeness.
206 if (VMI.RequiredTraits.test(
207 unsigned(TraitProperty::implementation_extension_match_any)))
208 MK = MK_ANY;
209 if (VMI.RequiredTraits.test(
210 unsigned(TraitProperty::implementation_extension_match_none)))
211 MK = MK_NONE;
212
213 bool AnyTraitMatched = false;
214
215 // Apply the match kind selected by implementation={extension(...)} to
216 // each property. Continue after match_any succeeds to record all construct
217 // match positions needed for scoring.
218 auto HandleTrait = [MK, &AnyTraitMatched](TraitProperty Property,
219 bool WasFound) -> bool {
220 AnyTraitMatched |= WasFound;
221 if (MK == MK_ANY)
222 return true;
223
224 // In "all" or "none" mode we accept a matching or non-matching property
225 // respectively and move on. We are not done yet!
226 if ((WasFound && MK == MK_ALL) || (!WasFound && MK == MK_NONE))
227 return true;
228
229 // We missed a property, provide some debug output and indicate failure.
230 LLVM_DEBUG({
231 if (MK == MK_ALL)
232 dbgs() << "[" << DEBUG_TYPE << "] Property "
234 << " was not in the OpenMP context but match kind is all.\n";
235 if (MK == MK_NONE)
236 dbgs() << "[" << DEBUG_TYPE << "] Property "
238 << " was in the OpenMP context but match kind is none.\n";
239 });
240 return false;
241 };
242
243 for (unsigned Bit : VMI.RequiredTraits.set_bits()) {
245 if (DeviceOrImplementationSetOnly &&
246 getOpenMPContextTraitSetForProperty(Property) != TraitSet::device &&
248 TraitSet::implementation)
249 continue;
250
251 // So far all extensions are handled elsewhere, we skip them here as they
252 // are not part of the OpenMP context.
254 TraitSelector::implementation_extension)
255 continue;
256
257 bool IsActiveTrait = Ctx.ActiveTraits.test(unsigned(Property));
258
259 // We overwrite the isa trait as it is actually up to the OMPContext hook to
260 // check the raw string(s).
261 if (Property == TraitProperty::device_isa___ANY ||
262 Property == TraitProperty::target_device_isa___ANY)
263 IsActiveTrait = llvm::all_of(VMI.ISATraits, [&](const auto &Trait) {
264 return Trait.Property != Property || Ctx.matchesISATrait(Trait.Name);
265 });
266
267 if (!HandleTrait(Property, IsActiveTrait))
268 return false;
269 // The match_any result is known; skip ISA lookups, which can warn.
270 if (MK == MK_ANY && AnyTraitMatched)
271 break;
272 }
273
274 if (!DeviceOrImplementationSetOnly) {
275 // Scan the construct sequence in order, recording matching context
276 // positions for scoring.
277 unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size();
280 TraitSet::construct &&
281 "Variant context is ill-formed!");
282
283 // Verify the nesting. A failed match in match_any or match_none must not
284 // consume the remaining context, since a later selector property can
285 // still match.
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);
294
295 if (!HandleTrait(Property, FoundInOrder)) {
296 LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Construct property "
298 << " was not nested properly.\n");
299 return false;
300 }
301
302 // TODO: Verify SIMD
303 }
304
305 // A complete ordered match can have several embeddings in the context.
306 // Match backwards to choose the highest-valued one for scoring. Keep the
307 // forward scan's partial matches for the match_any extension.
308 if (ConstructMatches &&
309 ConstructMatches->size() == VMI.ConstructTraits.size()) {
310 ConstructIdx = NoConstructTraits;
311 for (unsigned I = VMI.ConstructTraits.size(); I > 0; --I) {
313 while (ConstructIdx > 0 &&
314 Ctx.ConstructTraits[ConstructIdx - 1] != Property)
315 --ConstructIdx;
316 assert(ConstructIdx > 0 && "Previously matched construct not found!");
317 (*ConstructMatches)[I - 1] = --ConstructIdx;
318 }
319 }
320
321 if (MK == MK_ALL)
323 Ctx.ConstructTraits) &&
324 "Broken invariant!");
325 }
326
327 if (MK == MK_ANY && !AnyTraitMatched) {
328 LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE
329 << "] None of the properties was in the OpenMP context "
330 "but match kind is any.\n");
331 return false;
332 }
333
334 return true;
335}
336
338 const VariantMatchInfo &VMI, const OMPContext &Ctx,
339 bool DeviceOrImplementationSetOnly) {
341 VMI, Ctx, /* ConstructMatches */ nullptr, DeviceOrImplementationSetOnly);
342}
343
345 const OMPContext &Ctx,
346 SmallVectorImpl<unsigned> &ConstructMatches) {
347 APInt Score(1, 1);
348
349 // A sum of valid scores can exceed the width of any individual score.
350 // Retain all active bits and allow one more bit for each addition's carry.
351 auto AddScore = [&](const APInt &Value) {
352 unsigned Width = std::max(Score.getActiveBits(), Value.getActiveBits()) + 1;
353 Score = Score.zextOrTrunc(Width);
354 Score += Value.zextOrTrunc(Width);
355 };
356 auto AddPowerOfTwo = [&](unsigned Exponent) {
357 AddScore(APInt::getOneBitSet(Exponent + 1, Exponent));
358 };
359
360 unsigned NoConstructTraits = Ctx.ConstructTraits.size();
361 SmallDenseSet<TraitSelector, 8> ScoredSelectors;
362 auto AddSelectorScore = [&](TraitSelector Selector, const APInt *UserScore) {
363 // Scores belong to selectors, not to individual properties.
364 if (!ScoredSelectors.insert(Selector).second)
365 return;
366 if (UserScore) {
367 AddScore(*UserScore);
368 return;
369 }
370 switch (Selector) {
371 case TraitSelector::device_kind:
372 case TraitSelector::target_device_kind:
373 AddPowerOfTwo(NoConstructTraits);
374 break;
375 case TraitSelector::device_arch:
376 case TraitSelector::target_device_arch:
377 AddPowerOfTwo(NoConstructTraits + 1);
378 break;
379 case TraitSelector::device_isa:
380 case TraitSelector::target_device_isa:
381 AddPowerOfTwo(NoConstructTraits + 2);
382 break;
383 default:
384 break;
385 }
386 };
387 for (unsigned Bit : VMI.RequiredTraits.set_bits()) {
389 // Construct scores use ordered positions below. kind(any) is treated as
390 // if no kind selector were specified.
391 if (getOpenMPContextTraitSetForProperty(Property) == TraitSet::construct ||
392 Property == TraitProperty::device_kind_any ||
393 Property == TraitProperty::target_device_kind_any)
394 continue;
395 auto It = VMI.ScoreMap.find(Property);
397 It == VMI.ScoreMap.end() ? nullptr : &It->second);
398 }
399
400 assert(VMI.ConstructTraits.size() >= ConstructMatches.size() &&
401 "Mismatch in the construct traits!");
402 for (unsigned Match : ConstructMatches) {
403 // ConstructMatches is the position p - 1 and we need 2^(p-1).
404 AddPowerOfTwo(Match);
405 }
406
407 LLVM_DEBUG({
408 dbgs() << "[" << DEBUG_TYPE << "] Variant has a score of ";
409 Score.print(dbgs(), /*isSigned=*/false);
410 dbgs() << "\n";
411 });
412 return Score;
413}
414
416 const SmallVectorImpl<VariantMatchInfo> &VMIs, const OMPContext &Ctx) {
417
418 APInt BestScore(1, 0);
419 SmallVector<unsigned, 4> BestVMIIdxs;
420
421 for (unsigned u = 0, e = VMIs.size(); u < e; ++u) {
422 const VariantMatchInfo &VMI = VMIs[u];
423
424 SmallVector<unsigned, 8> ConstructMatches;
425 // If the variant is not applicable its not the best.
427 VMI, Ctx, &ConstructMatches,
428 /* DeviceOrImplementationSetOnly */ false))
429 continue;
430 // Check if its clearly not the best.
431 APInt Score = getVariantMatchScore(VMI, Ctx, ConstructMatches);
432 unsigned Width = std::max(Score.getBitWidth(), BestScore.getBitWidth());
433 Score = Score.zextOrTrunc(Width);
434 BestScore = BestScore.zextOrTrunc(Width);
435 if (Score.ult(BestScore))
436 continue;
437 if (Score.ugt(BestScore)) {
438 BestScore = Score;
439 BestVMIIdxs.clear();
440 }
441 BestVMIIdxs.push_back(u);
442 }
443
444 // A strict subset of another tied variant is never best; otherwise the first
445 // one wins. Tied variants often share a few supersets, so try the ones found
446 // so far before scanning all of them.
448 for (unsigned Idx : BestVMIIdxs) {
449 const VariantMatchInfo &VMI = VMIs[Idx];
450 if (llvm::any_of(Supersets, [&](const VariantMatchInfo *Superset) {
451 return isStrictSubset(VMI, *Superset);
452 }))
453 continue;
454 auto *It = llvm::find_if(BestVMIIdxs, [&](unsigned OtherIdx) {
455 return isStrictSubset(VMI, VMIs[OtherIdx]);
456 });
457 if (It == BestVMIIdxs.end())
458 return Idx;
459 Supersets.push_back(&VMIs[*It]);
460 }
461 return -1;
462}
463
465 return StringSwitch<TraitSet>(S)
466#define OMP_TRAIT_SET(Enum, Str) .Case(Str, TraitSet::Enum)
467#include "llvm/Frontend/OpenMP/OMPKinds.def"
468 .Default(TraitSet::invalid);
469}
470
473 switch (Selector) {
474#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
475 case TraitSelector::Enum: \
476 return TraitSet::TraitSetEnum;
477#include "llvm/Frontend/OpenMP/OMPKinds.def"
478 }
479 llvm_unreachable("Unknown trait selector!");
480}
483 switch (Property) {
484#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
485 case TraitProperty::Enum: \
486 return TraitSet::TraitSetEnum;
487#include "llvm/Frontend/OpenMP/OMPKinds.def"
488 }
489 llvm_unreachable("Unknown trait set!");
490}
492 switch (Kind) {
493#define OMP_TRAIT_SET(Enum, Str) \
494 case TraitSet::Enum: \
495 return Str;
496#include "llvm/Frontend/OpenMP/OMPKinds.def"
497 }
498 llvm_unreachable("Unknown trait set!");
499}
500
502 TraitSet Set) {
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);
514}
517 switch (Property) {
518#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
519 case TraitProperty::Enum: \
520 return TraitSelector::TraitSelectorEnum;
521#include "llvm/Frontend/OpenMP/OMPKinds.def"
522 }
523 llvm_unreachable("Unknown trait set!");
524}
526 switch (Kind) {
527#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \
528 case TraitSelector::Enum: \
529 return Str;
530#include "llvm/Frontend/OpenMP/OMPKinds.def"
531 }
532 llvm_unreachable("Unknown trait selector!");
533}
534
536 TraitSet Set, TraitSelector Selector, StringRef S) {
537 // Special handling for `device={isa(...)}` as we accept anything here. It is
538 // up to the target to decide if the feature is available.
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;
549}
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);
560}
562 StringRef RawString) {
563 if (Kind == TraitProperty::device_isa___ANY)
564 return RawString;
565 if (Kind == TraitProperty::target_device_isa___ANY)
566 return RawString;
567 switch (Kind) {
568#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \
569 case TraitProperty::Enum: \
570 return Str;
571#include "llvm/Frontend/OpenMP/OMPKinds.def"
572 }
573 llvm_unreachable("Unknown trait property!");
574}
576 switch (Kind) {
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"
581 }
582 llvm_unreachable("Unknown trait property!");
583}
584
586 TraitSet Set,
587 bool &AllowsTraitScore,
588 bool &RequiresProperty) {
589 AllowsTraitScore = Set != TraitSet::construct && Set != TraitSet::device &&
590 Set != TraitSet::target_device;
591 switch (Selector) {
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"
597 }
598 llvm_unreachable("Unknown trait selector!");
599}
600
603 switch (Property) {
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"
609 }
610 llvm_unreachable("Unknown trait property!");
611}
612
614 std::string S;
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"
619 S.pop_back();
620 return S;
621}
622
624 std::string S;
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"
629 S.pop_back();
630 return S;
631}
632
633std::string
635 TraitSelector Selector) {
636 std::string S;
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"
643 if (S.empty())
644 return "<none>";
645 S.pop_back();
646 return S;
647}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseSet and SmallDenseSet classes.
#define DEBUG_TYPE
#define I(x, y, z)
Definition MD5.cpp:57
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...
int64_t C1
int64_t C0
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition APInt.cpp:1078
unsigned getActiveBits() const
Compute the number of active bits in the value.
Definition APInt.h:1532
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition APInt.h:1186
LLVM_ABI void print(raw_ostream &OS, bool isSigned) const
Definition APInt.cpp:2345
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition APInt.h:1115
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:235
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool test(unsigned Idx) const
Returns true if bit Idx is set.
Definition BitVector.h:483
size_type count() const
Returns the number of bits which are set.
Definition BitVector.h:182
iterator_range< const_set_bits_iterator > set_bits() const
Definition BitVector.h:160
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition DenseSet.h:295
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.
Definition StringRef.h:56
A switch()-like statement whose cases are string literals.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:516
const std::string & getTriple() const
Definition Triple.h:583
LLVM Value Representation.
Definition Value.h:75
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
#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:1755
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
The context for a source location is made up of active property traits, e.g., device={kind(host)}...
Definition OMPContext.h:172
LLVM_ABI OMPContext(bool IsDeviceCompilation, Triple TargetTriple, Triple TargetOffloadTriple, int DeviceNum)
A device or target_device isa property and the ISA name it requires.
Definition OMPContext.h:126
Variant match information describes the required traits and how they are scored (via the ScoresMap).
Definition OMPContext.h:124
SmallVector< TraitProperty, 8 > ConstructTraits
Definition OMPContext.h:165
SmallVector< ISATrait, 8 > ISATraits
Definition OMPContext.h:164
SmallDenseMap< TraitProperty, APInt > ScoreMap
Definition OMPContext.h:166