LLVM: include/llvm/Frontend/OpenMP/ConstructDecompositionT.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18#ifndef LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H

19#define LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H

20

27

28#include

29#include

30#include

31#include

32#include <type_traits>

33#include <unordered_map>

34#include <unordered_set>

35#include

36#include

37

39 static llvm::omp::Directive worksharing[] = {

40 llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_for,

41 llvm::omp::Directive::OMPD_scope, llvm::omp::Directive::OMPD_sections,

42 llvm::omp::Directive::OMPD_single, llvm::omp::Directive::OMPD_workshare,

43 };

44 return worksharing;

45}

46

48 static llvm::omp::Directive worksharingLoop[] = {

49 llvm::omp::Directive::OMPD_do,

50 llvm::omp::Directive::OMPD_for,

51 };

52 return worksharingLoop;

53}

54

56template <typename Container, typename Predicate>

57typename std::remove_reference_t::iterator

60 if (first == container.end())

61 return first;

62 auto second = std::find_if(std::next(first), container.end(), pred);

63 if (second == container.end())

64 return first;

65 return container.end();

66}

67}

68

69namespace tomp {

70

77

78

79

80

81

82

83

84

85

86

87

88template <typename ClauseType, typename HelperType>

91

92 using TypeTy = typename ClauseTy::TypeTy;

93 using IdTy = typename ClauseTy::IdTy;

94 using ExprTy = typename ClauseTy::ExprTy;

97

98 using ClauseSet = std::unordered_set<const ClauseTy *>;

99

101 llvm::omp::Directive dir,

103 : version(ver), construct(dir), helper(helper) {

105 nodes.push_back(&clause);

106

107 bool success = split();

108 if (!success)

109 return;

110

111

112

113

114

115 for (auto &leaf : leafs) {

116 output.push_back({leaf.id, {}});

117 auto &out = output.back();

118 for (const ClauseTy *c : leaf.clauses)

119 out.clauses.push_back(*c);

120 }

121 }

122

125

126private:

127 bool split();

128

130 errors.emplace_back(node, ec);

131 return false;

132 }

133

134 struct LeafReprInternal {

135 llvm::omp::Directive id = llvm::omp::Directive::OMPD_unknown;

137 };

138

139 LeafReprInternal *findDirective(llvm::omp::Directive dirId) {

141 leafs, [&](const LeafReprInternal &leaf) { return leaf.id == dirId; });

142 return found != leafs.end() ? &*found : nullptr;

143 }

144

146 if (auto found = syms.find(object.id()); found != syms.end())

147 return &found->second;

148 return nullptr;

149 }

150

151 template

152 ClauseTy *makeClause(llvm::omp::Clause clauseId, S &&specific) {

153 implicit.push_back(typename ClauseTy::BaseT{clauseId, std::move(specific)});

154 return &implicit.back();

155 }

156

157 void addClauseSymsToMap(const ObjectTy &object, const ClauseTy *);

160 void addClauseSymsToMap(const TypeTy &item, const ClauseTy *);

161 void addClauseSymsToMap(const ExprTy &item, const ClauseTy *);

162 void addClauseSymsToMap(const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,

164

165 template

166 void addClauseSymsToMap(const std::optional &item, const ClauseTy *);

167 template

169 template <typename... U, size_t... Is>

170 void addClauseSymsToMap(const std::tuple<U...> &item, const ClauseTy *,

171 std::index_sequence<Is...> = {});

172 template

173 std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t>, void>

174 addClauseSymsToMap(U &&item, const ClauseTy *);

175

176 template

177 std::enable_if_t<llvm::remove_cvref_t::EmptyTrait::value, void>

178 addClauseSymsToMap(U &&item, const ClauseTy *);

179

180 template

181 std::enable_if_t<llvm::remove_cvref_t::IncompleteTrait::value, void>

182 addClauseSymsToMap(U &&item, const ClauseTy *);

183

184 template

185 std::enable_if_t<llvm::remove_cvref_t::WrapperTrait::value, void>

186 addClauseSymsToMap(U &&item, const ClauseTy *);

187

188 template

189 std::enable_if_t<llvm::remove_cvref_t::TupleTrait::value, void>

190 addClauseSymsToMap(U &&item, const ClauseTy *);

191

192 template

193 std::enable_if_t<llvm::remove_cvref_t::UnionTrait::value, void>

194 addClauseSymsToMap(U &&item, const ClauseTy *);

195

196

197

198

199 bool applyToUnique(const ClauseTy *node);

200

201

202

203 template

205

206

207

208 bool applyToInnermost(const ClauseTy *node);

209

210

211

212 bool applyToOutermost(const ClauseTy *node);

213

214

215

216

217 template

219

220

221

222 bool applyToAll(const ClauseTy *node);

223

224 template

225 bool applyClause(Clause &&clause, const ClauseTy *node);

226

227 bool applyClause(const tomp::clause::AllocateT<TypeTy, IdTy, ExprTy> &clause,

229 bool applyClause(const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &clause,

231 bool applyClause(const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,

233 bool

234 applyClause(const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,

236 bool applyClause(const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,

238 bool

239 applyClause(const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,

241 bool applyClause(const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,

243 bool applyClause(const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,

245 bool

246 applyClause(const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,

248 bool applyClause(const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &clause,

250 bool applyClause(const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,

252 bool applyClause(const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,

254 bool applyClause(const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,

256 bool applyClause(const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,

258 bool

259 applyClause(const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,

261

262 uint32_t version;

263 llvm::omp::Directive construct;

264 HelperType &helper;

267 std::list implicit;

268

269 std::unordered_map<IdTy, ClauseSet> syms;

270 std::unordered_set mapBases;

271};

272

273

274template <typename ClauseType, typename HelperType>

278

279template <typename C, typename H>

280void ConstructDecompositionT<C, H>::addClauseSymsToMap(const ObjectTy &object,

281 const ClauseTy *node) {

282 syms[object.id()].insert(node);

283}

284

285template <typename C, typename H>

286void ConstructDecompositionT<C, H>::addClauseSymsToMap(

288 for (auto &object : objects)

289 syms[object.id()].insert(node);

290}

291

292template <typename C, typename H>

293void ConstructDecompositionT<C, H>::addClauseSymsToMap(const TypeTy &item,

294 const ClauseTy *node) {

295

296}

297

298template <typename C, typename H>

299void ConstructDecompositionT<C, H>::addClauseSymsToMap(const ExprTy &item,

300 const ClauseTy *node) {

301

302}

303

304template <typename C, typename H>

305void ConstructDecompositionT<C, H>::addClauseSymsToMap(

306 const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,

307 const ClauseTy *node) {

308 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(item.t);

309 addClauseSymsToMap(objects, node);

310 for (auto &object : objects) {

311 if (auto base = helper.getBaseObject(object))

312 mapBases.insert(base->id());

313 }

314}

315

316template <typename C, typename H>

317template

318void ConstructDecompositionT<C, H>::addClauseSymsToMap(

319 const std::optional &item, const ClauseTy *node) {

320 if (item)

321 addClauseSymsToMap(*item, node);

322}

323

324template <typename C, typename H>

325template

326void ConstructDecompositionT<C, H>::addClauseSymsToMap(

328 for (auto &s : item)

329 addClauseSymsToMap(s, node);

330}

331

332template <typename C, typename H>

333template <typename... U, size_t... Is>

334void ConstructDecompositionT<C, H>::addClauseSymsToMap(

335 const std::tuple<U...> &item, const ClauseTy *node,

336 std::index_sequence<Is...>) {

337 (void)node;

338 (addClauseSymsToMap(std::get(item), node), ...);

339}

340

341template <typename C, typename H>

342template

343std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t>, void>

344ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,

345 const ClauseTy *node) {

346

347}

348

349template <typename C, typename H>

350template

351std::enable_if_t<llvm::remove_cvref_t::EmptyTrait::value, void>

352ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,

353 const ClauseTy *node) {

354

355}

356

357template <typename C, typename H>

358template

359std::enable_if_t<llvm::remove_cvref_t::IncompleteTrait::value, void>

360ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,

361 const ClauseTy *node) {

362

363}

364

365template <typename C, typename H>

366template

367std::enable_if_t<llvm::remove_cvref_t::WrapperTrait::value, void>

368ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,

369 const ClauseTy *node) {

370 addClauseSymsToMap(item.v, node);

371}

372

373template <typename C, typename H>

374template

375std::enable_if_t<llvm::remove_cvref_t::TupleTrait::value, void>

376ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,

377 const ClauseTy *node) {

378 constexpr size_t tuple_size =

379 std::tuple_size_v<llvm::remove_cvref_t<decltype(item.t)>>;

380 addClauseSymsToMap(item.t, node, std::make_index_sequence<tuple_size>{});

381}

382

383template <typename C, typename H>

384template

385std::enable_if_t<llvm::remove_cvref_t::UnionTrait::value, void>

386ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,

387 const ClauseTy *node) {

388 std::visit([&](auto &&s) { addClauseSymsToMap(s, node); }, item.u);

389}

390

391

392

393

394template <typename C, typename H>

395bool ConstructDecompositionT<C, H>::applyToUnique(const ClauseTy *node) {

397 return llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version);

398 });

399

400 if (unique != leafs.end()) {

401 unique->clauses.push_back(node);

402 return true;

403 }

404 return false;

405}

406

407

408

409template <typename C, typename H>

410template

411bool ConstructDecompositionT<C, H>::applyToFirst(

413 if (range.empty())

414 return false;

415

416 for (auto &leaf : range) {

417 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))

418 continue;

419 leaf.clauses.push_back(node);

420 return true;

421 }

422 return false;

423}

424

425

426

427template <typename C, typename H>

428bool ConstructDecompositionT<C, H>::applyToInnermost(const ClauseTy *node) {

430}

431

432

433

434template <typename C, typename H>

435bool ConstructDecompositionT<C, H>::applyToOutermost(const ClauseTy *node) {

437}

438

439template <typename C, typename H>

440template

441bool ConstructDecompositionT<C, H>::applyIf(const ClauseTy *node,

443 bool applied = false;

444 for (auto &leaf : leafs) {

445 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))

446 continue;

448 continue;

449 leaf.clauses.push_back(node);

450 applied = true;

451 }

452

453 return applied;

454}

455

456template <typename C, typename H>

457bool ConstructDecompositionT<C, H>::applyToAll(const ClauseTy *node) {

458 return applyIf(node, [](auto) { return true; });

459}

460

461template <typename C, typename H>

462template

463bool ConstructDecompositionT<C, H>::applyClause(Specific &&specific,

465

466

467

468

469

470

471

472 if (!applyToUnique(node))

474 return true;

475}

476

477

478

479

480

481

482

483

484

485

486

487

488template <typename C, typename H>

489bool ConstructDecompositionT<C, H>::applyClause(

491 const ClauseTy *node) {

492

493

494

495

496 bool applied = applyIf(node, [&](const auto &leaf) {

497 return llvm::any_of(leaf.clauses, [&](const ClauseTy *n) {

498 return llvm::omp::isPrivatizingClause(n->id);

499 });

500 });

501

502 if (!applied)

504 return true;

505}

506

507

508

509

510

511

512

513

514template <typename C, typename H>

515bool ConstructDecompositionT<C, H>::applyClause(

516 const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &clause,

517 const ClauseTy *node) {

518 if (!applyToInnermost(node))

520 return true;

521}

522

523

524

525

526

527

528

529

530template <typename C, typename H>

531bool ConstructDecompositionT<C, H>::applyClause(

532 const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,

533 const ClauseTy *node) {

534

535 if (!applyToAll(node))

537 return true;

538}

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570template <typename C, typename H>

571bool ConstructDecompositionT<C, H>::applyClause(

572 const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,

573 const ClauseTy *node) {

574 bool applied = false;

575

576

577 auto dirDistribute = findDirective(llvm::omp::OMPD_distribute);

578 auto dirTeams = findDirective(llvm::omp::OMPD_teams);

579 if (dirDistribute != nullptr) {

580 dirDistribute->clauses.push_back(node);

581 applied = true;

582

583 if (dirTeams != nullptr) {

584 auto *shared = makeClause(

585 llvm::omp::Clause::OMPC_shared,

586 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{clause.v});

587 dirTeams->clauses.push_back(shared);

588 }

589 } else if (dirTeams != nullptr) {

590 dirTeams->clauses.push_back(node);

591 applied = true;

592 }

593

594

595 auto findWorksharing = [&]() {

597 for (auto &leaf : leafs) {

598 auto found = llvm::find(worksharing, leaf.id);

599 if (found != std::end(worksharing))

600 return &leaf;

601 }

602 return static_cast<typename decltype(leafs)::value_type *>(nullptr);

603 };

604

605 auto dirWorksharing = findWorksharing();

606 if (dirWorksharing != nullptr) {

607 dirWorksharing->clauses.push_back(node);

608 applied = true;

609 }

610

611

612 auto dirTaskloop = findDirective(llvm::omp::OMPD_taskloop);

613 if (dirTaskloop != nullptr) {

614 dirTaskloop->clauses.push_back(node);

615 applied = true;

616 }

617

618

619 auto dirParallel = findDirective(llvm::omp::OMPD_parallel);

620 if (dirParallel != nullptr) {

621 if (dirTaskloop == nullptr && dirWorksharing == nullptr) {

622 dirParallel->clauses.push_back(node);

623 applied = true;

624 } else {

625

626 auto *shared = makeClause(

627 llvm::omp::Clause::OMPC_shared,

628 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{clause.v});

629 dirParallel->clauses.push_back(shared);

630 }

631 }

632

633

634 auto inLastprivate = [&](const ObjectTy &object) {

635 if (ClauseSet *set = findClausesWith(object)) {

636 return llvm::find_if(*set, [](const ClauseTy *c) {

637 return c->id == llvm::omp::Clause::OMPC_lastprivate;

638 }) != set->end();

639 }

640 return false;

641 };

642

643 auto dirTarget = findDirective(llvm::omp::OMPD_target);

644 if (dirTarget != nullptr) {

647 clause.v, std::back_inserter(objects), [&](const ObjectTy &object) {

648 return !inLastprivate(object) && !mapBases.count(object.id());

649 });

650 if (!objects.empty()) {

651 auto *firstp = makeClause(

652 llvm::omp::Clause::OMPC_firstprivate,

653 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{objects});

654 dirTarget->clauses.push_back(firstp);

655 applied = true;

656 }

657 }

658

659

660 if (auto dirTask = findDirective(llvm::omp::OMPD_task)) {

661 dirTask->clauses.push_back(node);

662 applied = true;

663 }

664

665 if (!applied)

667 return true;

668}

669

670

671

672

673

674

675

676

677

678

679

680

681template <typename C, typename H>

682bool ConstructDecompositionT<C, H>::applyClause(

683 const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,

684 const ClauseTy *node) {

685 using DirectiveNameModifier =

688 auto &modifier = std::get<std::optional>(clause.t);

689

690 if (modifier) {

691 llvm::omp::Directive dirId = *modifier;

692 auto *unmodified =

693 makeClause(llvm::omp::Clause::OMPC_if,

694 tomp::clause::IfT<TypeTy, IdTy, ExprTy>{

695 {std::nullopt,

696 std::get(clause.t)}});

697

698 if (auto *hasDir = findDirective(dirId)) {

699 hasDir->clauses.push_back(unmodified);

700 return true;

701 }

703 }

704

705 if (!applyToAll(node))

707 return true;

708}

709

710

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729template <typename C, typename H>

730bool ConstructDecompositionT<C, H>::applyClause(

731 const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,

732 const ClauseTy *node) {

733

734 if (!applyToAll(node))

736

737 auto inFirstprivate = [&](const ObjectTy &object) {

738 if (ClauseSet *set = findClausesWith(object)) {

739 return llvm::find_if(*set, [](const ClauseTy *c) {

740 return c->id == llvm::omp::Clause::OMPC_firstprivate;

741 }) != set->end();

742 }

743 return false;

744 };

745

746 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(clause.t);

747

748

751 objects, std::back_inserter(sharedObjects),

752 [&](const ObjectTy &object) { return !inFirstprivate(object); });

753

754 if (!sharedObjects.empty()) {

755

756 if (auto dirParallel = findDirective(llvm::omp::OMPD_parallel)) {

757 auto *shared = makeClause(

758 llvm::omp::Clause::OMPC_shared,

759 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});

760 dirParallel->clauses.push_back(shared);

761 }

762

763

764 if (auto dirTeams = findDirective(llvm::omp::OMPD_teams)) {

765 auto *shared = makeClause(

766 llvm::omp::Clause::OMPC_shared,

767 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});

768 dirTeams->clauses.push_back(shared);

769 }

770 }

771

772

773 if (auto dirTarget = findDirective(llvm::omp::OMPD_target)) {

776 objects, std::back_inserter(tofrom),

777 [&](const ObjectTy &object) { return !mapBases.count(object.id()); });

778

779 if (!tofrom.empty()) {

780 using MapType =

781 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;

782 auto *map =

783 makeClause(llvm::omp::Clause::OMPC_map,

784 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{

785 {MapType::Tofrom,

786 std::nullopt,

787 std::nullopt,

788 std::nullopt,

789 std::nullopt, std::nullopt,

790 std::move(tofrom)}});

791 dirTarget->clauses.push_back(map);

792 }

793 }

794

795 return true;

796}

797

798

799

800

801

802

803

804

805

806

807

808

809

810

811

812

813

814

815template <typename C, typename H>

816bool ConstructDecompositionT<C, H>::applyClause(

817 const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,

818 const ClauseTy *node) {

819

820 if (!applyToInnermost(node))

822

823

824 auto dirSimd = findDirective(llvm::omp::Directive::OMPD_simd);

825 std::optional iterVar = helper.getLoopIterVar();

826 const auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(clause.t);

827

828

829

831

832 for (const ObjectTy &object : objects) {

833 last.push_back(object);

834 if (!dirSimd || !iterVar || object.id() != iterVar->id())

835 first.push_back(object);

836 }

837

838 if (!first.empty()) {

839 auto *firstp = makeClause(

840 llvm::omp::Clause::OMPC_firstprivate,

841 tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy>{first});

842 nodes.push_back(firstp);

843 }

844 if (last.empty()) {

845 auto *lastp =

846 makeClause(llvm::omp::Clause::OMPC_lastprivate,

847 tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>{

848 {std::nullopt, last}});

849 nodes.push_back(lastp);

850 }

851 return true;

852}

853

854

855

856

857

858

859

860

861

862template <typename C, typename H>

863bool ConstructDecompositionT<C, H>::applyClause(

864 const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,

865 const ClauseTy *node) {

866 if (!applyToOutermost(node))

868 return true;

869}

870

871

872template <typename C, typename H>

873bool ConstructDecompositionT<C, H>::applyClause(

874 const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,

875 const ClauseTy *node) {

876 if (!applyToAll(node))

878 return true;

879}

880

881

882template <typename C, typename H>

883bool ConstructDecompositionT<C, H>::applyClause(

884 const tomp::clause::OmpxBareT<TypeTy, IdTy, ExprTy> &clause,

885 const ClauseTy *node) {

886 if (!applyToOutermost(node))

888 return true;

889}

890

891

892

893

894

895

896

897

898template <typename C, typename H>

899bool ConstructDecompositionT<C, H>::applyClause(

900 const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,

901 const ClauseTy *node) {

902

903 if (!applyToAll(node))

905 return true;

906}

907

908

909

910

911

912

913

914

915

916template <typename C, typename H>

917bool ConstructDecompositionT<C, H>::applyClause(

918 const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,

919 const ClauseTy *node) {

920 if (!applyToInnermost(node))

922 return true;

923}

924

925

926

927

928

929

930

931

932

933

934

935

936

937

938

939

940

941

942

943

944

945

946

947

948

949

950

951template <typename C, typename H>

952bool ConstructDecompositionT<C, H>::applyClause(

953 const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,

954 const ClauseTy *node) {

955 using ReductionTy = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;

956

957

958 bool applyToParallel = true, applyToTeams = true;

959

960 auto dirParallel = findDirective(llvm::omp::Directive::OMPD_parallel);

961 if (dirParallel) {

964 llvm::omp::Directive::OMPD_loop,

965 llvm::omp::Directive::OMPD_sections,

966 llvm::omp::Directive::OMPD_taskloop,

967 });

968 auto present = [&](llvm::omp::Directive id) {

969 return findDirective(id) != nullptr;

970 };

971

973 applyToParallel = false;

974 }

975

976 auto dirTeams = findDirective(llvm::omp::Directive::OMPD_teams);

977 if (dirTeams) {

978

979 if (findDirective(llvm::omp::Directive::OMPD_loop))

980 applyToTeams = false;

981 }

982

983 using ReductionModifier = typename ReductionTy::ReductionModifier;

984 using ReductionIdentifiers = typename ReductionTy::ReductionIdentifiers;

985

986 auto &objects = std::get<tomp::ObjectListT<IdTy, ExprTy>>(clause.t);

987 auto &modifier = std::get<std::optional>(clause.t);

988

989

990

991

992 bool applied = false;

993

994

995 auto isValidModifier = [](llvm::omp::Directive dir, ReductionModifier mod,

996 bool alreadyApplied) {

997 switch (mod) {

998 case ReductionModifier::Inscan:

999

1000

1001 return dir == llvm::omp::Directive::OMPD_simd ||

1003 case ReductionModifier::Task:

1004 if (alreadyApplied)

1005 return false;

1006

1007

1008 return dir == llvm::omp::Directive::OMPD_parallel ||

1010 case ReductionModifier::Default:

1011 return true;

1012 }

1014 };

1015

1016 auto *unmodified = makeClause(

1017 llvm::omp::Clause::OMPC_reduction,

1018 ReductionTy{

1019 {std::nullopt,

1020 std::get(clause.t),

1021 objects}});

1022

1023 ReductionModifier effective = modifier.value_or(ReductionModifier::Default);

1024 bool modifierApplied = false;

1025 bool allowingLeaf = false;

1026

1027

1029 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, node->id, version))

1030 continue;

1031

1032

1033 allowingLeaf = true;

1034 if (!applyToParallel && &leaf == dirParallel)

1035 continue;

1036 if (!applyToTeams && &leaf == dirTeams)

1037 continue;

1038

1039 if (isValidModifier(leaf.id, effective, modifierApplied)) {

1040

1041 leaf.clauses.push_back(node);

1042 modifierApplied = true;

1043 } else {

1044

1045 leaf.clauses.push_back(unmodified);

1046 }

1047

1048 applied = modifierApplied;

1049 }

1050

1051 if (!allowingLeaf)

1053 if (!applied)

1055

1057 llvm::transform(objects, std::back_inserter(sharedObjects),

1058 [&](const ObjectTy &object) {

1059 auto maybeBase = helper.getBaseObject(object);

1060 return maybeBase ? *maybeBase : object;

1061 });

1062

1063

1064 if (!sharedObjects.empty()) {

1065 if (dirParallel && !applyToParallel) {

1066 auto *shared = makeClause(

1067 llvm::omp::Clause::OMPC_shared,

1068 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});

1069 dirParallel->clauses.push_back(shared);

1070 }

1071 if (dirTeams && !applyToTeams) {

1072 auto *shared = makeClause(

1073 llvm::omp::Clause::OMPC_shared,

1074 tomp::clause::SharedT<TypeTy, IdTy, ExprTy>{sharedObjects});

1075 dirTeams->clauses.push_back(shared);

1076 }

1077 }

1078

1079

1080 auto dirTarget = findDirective(llvm::omp::Directive::OMPD_target);

1081 if (dirTarget && leafs.size() > 1) {

1083 llvm::copy_if(objects, std::back_inserter(tofrom),

1084 [&](const ObjectTy &object) {

1085 if (auto maybeBase = helper.getBaseObject(object))

1086 return !mapBases.count(maybeBase->id());

1087 return !mapBases.count(object.id());

1088 });

1089 if (!tofrom.empty()) {

1090 using MapType =

1091 typename tomp::clause::MapT<TypeTy, IdTy, ExprTy>::MapType;

1092 auto *map = makeClause(

1093 llvm::omp::Clause::OMPC_map,

1094 tomp::clause::MapT<TypeTy, IdTy, ExprTy>{

1095 {MapType::Tofrom, std::nullopt,

1096 std::nullopt, std::nullopt,

1097 std::nullopt, std::nullopt,

1098 std::move(tofrom)}});

1099

1100 dirTarget->clauses.push_back(map);

1101 }

1102 }

1103

1104 return true;

1105}

1106

1107

1108

1109

1110

1111

1112

1113

1114template <typename C, typename H>

1115bool ConstructDecompositionT<C, H>::applyClause(

1116 const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,

1117 const ClauseTy *node) {

1118

1119 if (!applyToAll(node))

1121 return true;

1122}

1123

1124

1125

1126

1127

1128

1129

1130

1131template <typename C, typename H>

1132bool ConstructDecompositionT<C, H>::applyClause(

1133 const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,

1134 const ClauseTy *node) {

1135

1136 if (!applyToAll(node))

1138 return true;

1139}

1140

1141

1142

1143template <typename C, typename H> bool ConstructDecompositionT<C, H>::split() {

1145

1146 auto isImplicit = [this](const ClauseTy *node) {

1148 };

1149

1150 for (llvm::omp::Directive leaf :

1152 leafs.push_back(LeafReprInternal{leaf, {}});

1153

1154 for (const ClauseTy *node : nodes)

1155 addClauseSymsToMap(*node, node);

1156

1157

1158

1159

1160

1162 for (const ClauseTy *node : nodes) {

1163 if (node->id == llvm::omp::Clause::OMPC_linear)

1165 }

1166 for (const auto *node : linears) {

1168 applyClause(std::get<tomp::clause::LinearT<TypeTy, IdTy, ExprTy>>(

1169 node->u),

1170 node);

1171 }

1172

1173

1174

1175 auto skip = [](const ClauseTy *node) {

1176 switch (node->id) {

1177 case llvm::omp::Clause::OMPC_allocate:

1178 case llvm::omp::Clause::OMPC_linear:

1179 return true;

1180 default:

1181 return false;

1182 }

1183 };

1184

1185

1186 for (const ClauseTy *node : nodes) {

1187 if (skip(node))

1188 continue;

1189 bool result =

1190 std::visit([&](auto &&s) { return applyClause(s, node); }, node->u);

1191 if (!isImplicit(node))

1193 }

1194

1195

1196 for (const ClauseTy *node : nodes) {

1197 if (node->id != llvm::omp::Clause::OMPC_allocate)

1198 continue;

1201 std::visit([&](auto &&s) { return applyClause(s, node); }, node->u);

1202 }

1203

1205}

1206

1207}

1208

1209#endif

Unify divergent function exit nodes

static llvm::ArrayRef< llvm::omp::Directive > getWorksharing()

Definition ConstructDecompositionT.h:38

static llvm::ArrayRef< llvm::omp::Directive > getWorksharingLoop()

Definition ConstructDecompositionT.h:47

static bool shouldApply(Function &F, ProfileSummaryInfo &PSI)

static bool skip(DataExtractor &Data, uint64_t &Offset, bool SkippedRanges)

Skip an InlineInfo object in the specified data at the specified offset.

This file defines the SmallVector class.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

This provides a very simple, boring adaptor for a begin and end iterator into a range type.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

std::remove_reference_t< Container >::iterator find_unique(Container &&container, Predicate &&pred)

Definition ConstructDecompositionT.h:58

LLVM_ABI ArrayRef< Directive > getLeafConstructsOrSelf(Directive D)

auto find(R &&Range, const T &Val)

Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.

LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)

is always non-negative.

auto unique(Range &&R, Predicate P)

OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)

Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.

detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)

Returns a concatenated range across two or more ranges.

OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)

Wrapper function around std::transform to apply a function to a range and store the result elsewhere.

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

auto reverse(ContainerTy &&C)

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

LogicalResult success(bool IsSuccess=true)

Utility function to generate a LogicalResult.

llvm::SmallVector< T, 0 > ListT

ErrorCode

Definition ConstructDecompositionT.h:71

@ InvalidDirNameMod

Definition ConstructDecompositionT.h:74

@ NoLeafAllowing

Definition ConstructDecompositionT.h:72

@ NoLeafPrivatizing

Definition ConstructDecompositionT.h:73

@ RedModNotApplied

Definition ConstructDecompositionT.h:75

type::ObjectListT< I, E > ObjectListT

ConstructDecompositionT(uint32_t, HelperType &, llvm::omp::Directive, llvm::ArrayRef< ClauseType >) -> ConstructDecompositionT< ClauseType, HelperType >

type::ObjectT< I, E > ObjectT

typename ClauseTy::ExprTy ExprTy

Definition ConstructDecompositionT.h:94

llvm::SmallVector< std::pair< const ClauseType *, ErrorCode > > errors

Definition ConstructDecompositionT.h:124

std::unordered_set< const ClauseTy * > ClauseSet

Definition ConstructDecompositionT.h:98

typename ClauseTy::TypeTy TypeTy

Definition ConstructDecompositionT.h:92

ClauseType ClauseTy

Definition ConstructDecompositionT.h:90

typename ClauseTy::IdTy IdTy

Definition ConstructDecompositionT.h:93

tomp::ObjectT< IdTy, ExprTy > ObjectTy

Definition ConstructDecompositionT.h:96

ConstructDecompositionT(uint32_t ver, HelperType &helper, llvm::omp::Directive dir, llvm::ArrayRef< ClauseTy > clauses)

Definition ConstructDecompositionT.h:100

HelperType HelperTy

Definition ConstructDecompositionT.h:95

tomp::ListT< DirectiveWithClauses< ClauseType > > output

Definition ConstructDecompositionT.h:123

type::DirectiveName DirectiveNameModifier

std::tuple< OPT(MapType), OPT(MapTypeModifiers), OPT(AttachModifier), OPT(RefModifier), OPT(Mappers), OPT(Iterator), LocatorList > t