LLVM: lib/Frontend/OpenMP/OMPContext.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

21

22#define DEBUG_TYPE "openmp-ir-builder"

23

24using namespace llvm;

25using namespace omp;

26

28 Triple TargetOffloadTriple, int DeviceNum) {

29

30 if (!TargetOffloadTriple.getTriple().empty() && DeviceNum > -1) {

31

32 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_nohost));

33 switch (TargetOffloadTriple.getArch()) {

50 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_cpu));

51 break;

56 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_gpu));

57 break;

58 default:

59 break;

60 }

61

62#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

63 if (TraitSelector::TraitSelectorEnum == TraitSelector::target_device_arch) { \

64 if (TargetOffloadTriple.getArch() == \

65 TargetOffloadTriple.getArchTypeForLLVMName(Str)) \

66 ActiveTraits.set(unsigned(TraitProperty::Enum)); \

67 if (StringRef(Str) == "x86_64" && \

68 TargetOffloadTriple.getArch() == Triple::x86_64) \

69 ActiveTraits.set(unsigned(TraitProperty::Enum)); \

70 }

71#include "llvm/Frontend/OpenMP/OMPKinds.def"

72 } else {

73

74

76 ? TraitProperty::device_kind_nohost

77 : TraitProperty::device_kind_host));

78 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_host));

79 switch (TargetTriple.getArch()) {

96 ActiveTraits.set(unsigned(TraitProperty::device_kind_cpu));

97 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_cpu));

98 break;

103 ActiveTraits.set(unsigned(TraitProperty::device_kind_gpu));

104 ActiveTraits.set(unsigned(TraitProperty::target_device_kind_gpu));

105 break;

106 default:

107 break;

108 }

109

110

111#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

112 if (TraitSelector::TraitSelectorEnum == TraitSelector::device_arch || \

113 TraitSelector::TraitSelectorEnum == TraitSelector::target_device_arch) { \

114 if (TargetTriple.getArch() == TargetTriple.getArchTypeForLLVMName(Str)) \

115 ActiveTraits.set(unsigned(TraitProperty::Enum)); \

116 if (StringRef(Str) == "x86_64" && \

117 TargetTriple.getArch() == Triple::x86_64) \

118 ActiveTraits.set(unsigned(TraitProperty::Enum)); \

119 }

120#include "llvm/Frontend/OpenMP/OMPKinds.def"

121

122

123

124

125

126

127

128 ActiveTraits.set(unsigned(TraitProperty::implementation_vendor_llvm));

129

130

131 ActiveTraits.set(unsigned(TraitProperty::user_condition_true));

132

133

134 ActiveTraits.set(unsigned(TraitProperty::device_kind_any));

135

138 << "] New OpenMP context with the following properties:\n";

139 for (unsigned Bit : ActiveTraits.set_bits()) {

142 << "\n";

143 }

144 });

145 }

146}

147

148

149

151#ifdef EXPENSIVE_CHECKS

153 "Expected sorted arrays!");

154#endif

156 return false;

157 auto It0 = C0.begin(), End0 = C0.end();

158 auto It1 = C1.begin(), End1 = C1.end();

159 while (It0 != End0) {

160 if (It1 == End1)

161 return false;

162 if (*It0 == *It1) {

163 ++It0;

164 ++It1;

165 continue;

166 }

167 ++It0;

168 }

169 return true;

170}

171

172

173

174template

180

183

184

185

187 return false;

190 return false;

192 return false;

193 return true;

194}

195

196static int

200 bool DeviceOrImplementationSetOnly) {

201

202

203

204 enum MatchKind { MK_ALL, MK_ANY, MK_NONE };

205

206 MatchKind MK = MK_ALL;

207

208

210 unsigned(TraitProperty::implementation_extension_match_any)))

211 MK = MK_ANY;

213 unsigned(TraitProperty::implementation_extension_match_none)))

214 MK = MK_NONE;

215

216

217

218

220 bool WasFound) -> std::optional {

221

222

223 if (MK == MK_ANY) {

224 if (WasFound)

225 return true;

226 return std::nullopt;

227 }

228

229

230

231 if ((WasFound && MK == MK_ALL) || (!WasFound && MK == MK_NONE))

232 return std::nullopt;

233

234

236 if (MK == MK_ALL)

239 << " was not in the OpenMP context but match kind is all.\n";

240 if (MK == MK_NONE)

243 << " was in the OpenMP context but match kind is none.\n";

244 });

245 return false;

246 };

247

250 if (DeviceOrImplementationSetOnly &&

253 TraitSet::implementation)

254 continue;

255

256

257

259 TraitSelector::implementation_extension)

260 continue;

261

262 bool IsActiveTrait = Ctx.ActiveTraits.test(unsigned(Property));

263

264

265

266 if (Property == TraitProperty::device_isa___ANY)

268 return Ctx.matchesISATrait(RawString);

269 });

270 if (Property == TraitProperty::target_device_isa___ANY)

272 return Ctx.matchesISATrait(RawString);

273 });

274

275 if (std::optional Result = HandleTrait(Property, IsActiveTrait))

276 return *Result;

277 }

278

279 if (!DeviceOrImplementationSetOnly) {

280

281

282 unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size();

285 TraitSet::construct &&

286 "Variant context is ill-formed!");

287

288

289 bool FoundInOrder = false;

290 while (!FoundInOrder && ConstructIdx != NoConstructTraits)

291 FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] == Property);

292 if (ConstructMatches)

293 ConstructMatches->push_back(ConstructIdx - 1);

294

295 if (std::optional Result = HandleTrait(Property, FoundInOrder))

296 return *Result;

297

298 if (!FoundInOrder) {

301 << " was not nested properly.\n");

302 return false;

303 }

304

305

306 }

307

309 "Broken invariant!");

310 }

311

312 if (MK == MK_ANY) {

314 << "] None of the properties was in the OpenMP context "

315 "but match kind is any.\n");

316 return false;

317 }

318

319 return true;

320}

321

324 bool DeviceOrImplementationSetOnly) {

326 VMI, Ctx, nullptr, DeviceOrImplementationSetOnly);

327}

328

332 APInt Score(64, 1);

333

337

338 if (VMI.ScoreMap.count(Property)) {

339 const APInt &UserScore = VMI.ScoreMap.lookup(Property);

340 assert(UserScore.uge(0) && "Expect non-negative user scores!");

342 continue;

343 }

344

346 case TraitSet::construct:

347

348

349 continue;

350 case TraitSet::implementation:

351

352 continue;

353 case TraitSet::user:

354

355 continue;

356 case TraitSet::device:

357

358 break;

359 case TraitSet::target_device:

360

361 break;

362 case TraitSet::invalid:

364 }

365

366

367 if (Property == TraitProperty::device_kind_any)

368 continue;

369 if (Property == TraitProperty::target_device_kind_any)

370 continue;

371

373 case TraitSelector::device_kind:

374 Score += (1ULL << (NoConstructTraits + 0));

375 continue;

376 case TraitSelector::device_arch:

377 Score += (1ULL << (NoConstructTraits + 1));

378 continue;

379 case TraitSelector::device_isa:

380 Score += (1ULL << (NoConstructTraits + 2));

381 continue;

382 case TraitSelector::target_device_kind:

383 Score += (1ULL << (NoConstructTraits + 0));

384 continue;

385 case TraitSelector::target_device_arch:

386 Score += (1ULL << (NoConstructTraits + 1));

387 continue;

388 case TraitSelector::target_device_isa:

389 Score += (1ULL << (NoConstructTraits + 2));

390 continue;

391 default:

392 continue;

393 }

394 }

395

396 unsigned ConstructIdx = 0;

397 assert(NoConstructTraits == ConstructMatches.size() &&

398 "Mismatch in the construct traits!");

401 TraitSet::construct &&

402 "Ill-formed variant match info!");

403 (void)Property;

404

405 Score += (1ULL << ConstructMatches[ConstructIdx++]);

406 }

407

409 << "\n");

410 return Score;

411}

412

415

416 APInt BestScore(64, 0);

417 int BestVMIIdx = -1;

419

420 for (unsigned u = 0, e = VMIs.size(); u < e; ++u) {

422

424

426 VMI, Ctx, &ConstructMatches,

427 false))

428 continue;

429

431 if (Score.ult(BestScore))

432 continue;

433

434 if (Score.eq(BestScore)) {

435

437 continue;

438

440 continue;

441 }

442

443 BestVMI = &VMI;

444 BestVMIIdx = u;

445 BestScore = Score;

446 }

447

448 return BestVMIIdx;

449}

450

453#define OMP_TRAIT_SET(Enum, Str) .Case(Str, TraitSet::Enum)

454#include "llvm/Frontend/OpenMP/OMPKinds.def"

455 .Default(TraitSet::invalid);

456}

457

460 switch (Selector) {

461#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \

462 case TraitSelector::Enum: \

463 return TraitSet::TraitSetEnum;

464#include "llvm/Frontend/OpenMP/OMPKinds.def"

465 }

467}

470 switch (Property) {

471#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

472 case TraitProperty::Enum: \

473 return TraitSet::TraitSetEnum;

474#include "llvm/Frontend/OpenMP/OMPKinds.def"

475 }

477}

479 switch (Kind) {

480#define OMP_TRAIT_SET(Enum, Str) \

481 case TraitSet::Enum: \

482 return Str;

483#include "llvm/Frontend/OpenMP/OMPKinds.def"

484 }

486}

487

490 if (Set == TraitSet::target_device && S == "kind")

491 return TraitSelector::target_device_kind;

492 if (Set == TraitSet::target_device && S == "arch")

493 return TraitSelector::target_device_arch;

494 if (Set == TraitSet::target_device && S == "isa")

495 return TraitSelector::target_device_isa;

497#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \

498 .Case(Str, TraitSelector::Enum)

499#include "llvm/Frontend/OpenMP/OMPKinds.def"

500 .Default(TraitSelector::invalid);

501}

504 switch (Property) {

505#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

506 case TraitProperty::Enum: \

507 return TraitSelector::TraitSelectorEnum;

508#include "llvm/Frontend/OpenMP/OMPKinds.def"

509 }

511}

513 switch (Kind) {

514#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \

515 case TraitSelector::Enum: \

516 return Str;

517#include "llvm/Frontend/OpenMP/OMPKinds.def"

518 }

520}

521

524

525

526 if (Set == TraitSet::device && Selector == TraitSelector::device_isa)

527 return TraitProperty::device_isa___ANY;

528 if (Set == TraitSet::target_device &&

529 Selector == TraitSelector::target_device_isa)

530 return TraitProperty::target_device_isa___ANY;

531#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

532 if (Set == TraitSet::TraitSetEnum && Str == S) \

533 return TraitProperty::Enum;

534#include "llvm/Frontend/OpenMP/OMPKinds.def"

535 return TraitProperty::invalid;

536}

541#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

542 .Case(Str, Selector == TraitSelector::TraitSelectorEnum \

543 ? TraitProperty::Enum \

544 : TraitProperty::invalid)

545#include "llvm/Frontend/OpenMP/OMPKinds.def"

546 .Default(TraitProperty::invalid);

547}

550 if (Kind == TraitProperty::device_isa___ANY)

551 return RawString;

552 if (Kind == TraitProperty::target_device_isa___ANY)

553 return RawString;

554 switch (Kind) {

555#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

556 case TraitProperty::Enum: \

557 return Str;

558#include "llvm/Frontend/OpenMP/OMPKinds.def"

559 }

561}

563 switch (Kind) {

564#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

565 case TraitProperty::Enum: \

566 return "(" #TraitSetEnum "," #TraitSelectorEnum "," Str ")";

567#include "llvm/Frontend/OpenMP/OMPKinds.def"

568 }

570}

571

574 bool &AllowsTraitScore,

575 bool &RequiresProperty) {

576 AllowsTraitScore = Set != TraitSet::construct && Set != TraitSet::device &&

577 Set != TraitSet::target_device;

578 switch (Selector) {

579#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \

580 case TraitSelector::Enum: \

581 RequiresProperty = ReqProp; \

582 return Set == TraitSet::TraitSetEnum;

583#include "llvm/Frontend/OpenMP/OMPKinds.def"

584 }

586}

587

590 switch (Property) {

591#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

592 case TraitProperty::Enum: \

593 return Set == TraitSet::TraitSetEnum && \

594 Selector == TraitSelector::TraitSelectorEnum;

595#include "llvm/Frontend/OpenMP/OMPKinds.def"

596 }

598}

599

601 std::string S;

602#define OMP_TRAIT_SET(Enum, Str) \

603 if (StringRef(Str) != "invalid") \

604 S.append("'").append(Str).append("'").append(" ");

605#include "llvm/Frontend/OpenMP/OMPKinds.def"

606 S.pop_back();

607 return S;

608}

609

611 std::string S;

612#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, ReqProp) \

613 if (TraitSet::TraitSetEnum == Set && StringRef(Str) != "Invalid") \

614 S.append("'").append(Str).append("'").append(" ");

615#include "llvm/Frontend/OpenMP/OMPKinds.def"

616 S.pop_back();

617 return S;

618}

619

620std::string

623 std::string S;

624#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \

625 if (TraitSet::TraitSetEnum == Set && \

626 TraitSelector::TraitSelectorEnum == Selector && \

627 StringRef(Str) != "invalid") \

628 S.append("'").append(Str).append("'").append(" ");

629#include "llvm/Frontend/OpenMP/OMPKinds.def"

630 if (S.empty())

631 return "";

632 S.pop_back();

633 return S;

634}

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.

Definition OMPContext.cpp:175

static APInt getVariantMatchScore(const VariantMatchInfo &VMI, const OMPContext &Ctx, SmallVectorImpl< unsigned > &ConstructMatches)

Definition OMPContext.cpp:329

static int isVariantApplicableInContextHelper(const VariantMatchInfo &VMI, const OMPContext &Ctx, SmallVectorImpl< unsigned > *ConstructMatches, bool DeviceOrImplementationSetOnly)

Definition OMPContext.cpp:197

static bool isSubset(ArrayRef< T > C0, ArrayRef< T > C1)

Return true if C0 is a subset of C1.

Definition OMPContext.cpp:150

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.

Definition OMPContext.cpp:600

LLVM_ABI StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind)

Return a textual representation of the trait property Kind with selector and set name included.

Definition OMPContext.cpp:562

LLVM_ABI bool isValidTraitSelectorForTraitSet(TraitSelector Selector, TraitSet Set, bool &AllowsTraitScore, bool &RequiresProperty)

}

Definition OMPContext.cpp:572

LLVM_ABI TraitSet getOpenMPContextTraitSetForSelector(TraitSelector Selector)

Return the trait set for which Selector is a selector.

Definition OMPContext.cpp:459

LLVM_ABI TraitSelector getOpenMPContextTraitSelectorKind(StringRef Str, TraitSet Set)

Parse Str and return the trait set it matches or TraitSelector::invalid.

Definition OMPContext.cpp:488

LLVM_ABI TraitSet getOpenMPContextTraitSetForProperty(TraitProperty Property)

Return the trait set for which Property is a property.

Definition OMPContext.cpp:469

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.

Definition OMPContext.cpp:413

LLVM_ABI StringRef getOpenMPContextTraitSetName(TraitSet Kind)

Return a textual representation of the trait set Kind.

Definition OMPContext.cpp:478

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 (...

Definition OMPContext.cpp:548

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...

Definition OMPContext.cpp:522

LLVM_ABI StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind)

Return a textual representation of the trait selector Kind.

Definition OMPContext.cpp:512

LLVM_ABI std::string listOpenMPContextTraitSelectors(TraitSet Set)

Return a string listing all trait selectors for Set.

Definition OMPContext.cpp:610

TraitSet

OpenMP Context related IDs and helpers.

LLVM_ABI TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property)

Return the trait selector for which Property is a property.

Definition OMPContext.cpp:503

LLVM_ABI TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector)

Return the trait property for a singleton selector Selector.

Definition OMPContext.cpp:538

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...

Definition OMPContext.cpp:322

LLVM_ABI TraitSet getOpenMPContextTraitSetKind(StringRef Str)

Parse Str and return the trait set it matches or TraitSet::invalid.

Definition OMPContext.cpp:451

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.

Definition OMPContext.cpp:588

LLVM_ABI std::string listOpenMPContextTraitProperties(TraitSet Set, TraitSelector Selector)

Return a string listing all trait properties for Set and Selector.

Definition OMPContext.cpp:621

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)

Definition OMPContext.cpp:27

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