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

59 auto first = std::find_if(container.begin(), container.end(), pred);

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

71

72

73

74

75

76

77

78

79

80

81

82template <typename ClauseType, typename HelperType>

85

86 using TypeTy = typename ClauseTy::TypeTy;

87 using IdTy = typename ClauseTy::IdTy;

88 using ExprTy = typename ClauseTy::ExprTy;

91

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

93

95 llvm::omp::Directive dir,

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

99 nodes.push_back(&clause);

100

101 bool success = split();

102 if (!success)

103 return;

104

105

106

107

108

109 for (auto &leaf : leafs) {

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

111 auto &out = output.back();

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

113 out.clauses.push_back(*c);

114 }

115 }

116

118

119private:

120 bool split();

121

122 struct LeafReprInternal {

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

125 };

126

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

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

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

131 }

132

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

135 return &found->second;

136 return nullptr;

137 }

138

139 template

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

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

142 return &implicit.back();

143 }

144

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

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

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

152

153 template

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

155 template

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

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

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

160 template

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

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

163

164 template

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

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

167

168 template

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

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

171

172 template

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

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

175

176 template

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

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

179

180 template

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

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

183

184

185

186

187 bool applyToUnique(const ClauseTy *node);

188

189

190

191 template

193

194

195

196 bool applyToInnermost(const ClauseTy *node);

197

198

199

200 bool applyToOutermost(const ClauseTy *node);

201

202 template

204

205 bool applyToAll(const ClauseTy *node);

206

207 template

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

209

214 bool

217 bool

224 bool

239 bool

244

246 llvm::omp::Directive construct;

247 HelperType &helper;

248 ListT leafs;

250 std::list implicit;

251

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

253 std::unordered_set mapBases;

254};

255

256

257template <typename ClauseType, typename HelperType>

261

262template <typename C, typename H>

264 const ClauseTy *node) {

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

266}

267

268template <typename C, typename H>

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

271 for (auto &object : objects)

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

273}

274

275template <typename C, typename H>

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

277 const ClauseTy *node) {

278

279}

280

281template <typename C, typename H>

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

283 const ClauseTy *node) {

284

285}

286

287template <typename C, typename H>

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

290 const ClauseTy *node) {

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

292 addClauseSymsToMap(objects, node);

293 for (auto &object : objects) {

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

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

296 }

297}

298

299template <typename C, typename H>

300template

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

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

303 if (item)

304 addClauseSymsToMap(*item, node);

305}

306

307template <typename C, typename H>

308template

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

311 for (auto &s : item)

312 addClauseSymsToMap(s, node);

313}

314

315template <typename C, typename H>

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

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

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

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

320 (void)node;

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

322}

323

324template <typename C, typename H>

325template

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

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

328 const ClauseTy *node) {

329

330}

331

332template <typename C, typename H>

333template

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

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

336 const ClauseTy *node) {

337

338}

339

340template <typename C, typename H>

341template

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

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

344 const ClauseTy *node) {

345

346}

347

348template <typename C, typename H>

349template

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

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

352 const ClauseTy *node) {

353 addClauseSymsToMap(item.v, node);

354}

355

356template <typename C, typename H>

357template

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

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

360 const ClauseTy *node) {

361 constexpr size_t tuple_size =

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

364}

365

366template <typename C, typename H>

367template

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

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

370 const ClauseTy *node) {

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

372}

373

374

375

376

377template <typename C, typename H>

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

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

381 });

382

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

384 unique->clauses.push_back(node);

385 return true;

386 }

387 return false;

388}

389

390

391

392template <typename C, typename H>

393template

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

396 if (range.empty())

397 return false;

398

399 for (auto &leaf : range) {

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

401 continue;

402 leaf.clauses.push_back(node);

403 return true;

404 }

405 return false;

406}

407

408

409

410template <typename C, typename H>

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

413}

414

415

416

417template <typename C, typename H>

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

420}

421

422template <typename C, typename H>

423template

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

426 bool applied = false;

427 for (auto &leaf : leafs) {

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

429 continue;

431 continue;

432 leaf.clauses.push_back(node);

433 applied = true;

434 }

435

436 return applied;

437}

438

439template <typename C, typename H>

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

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

442}

443

444template <typename C, typename H>

445template

448

449

450

451

452

453

454

455 if (applyToUnique(node))

456 return true;

457

458 return false;

459}

460

461

462

463

464

465

466

467

468template <typename C, typename H>

471 const ClauseTy *node) {

472

473

474 if (!leafs.empty()) {

475 auto &last = leafs.back();

476

477 if (llvm::omp::isAllowedClauseForDirective(last.id, node->id, version)) {

478 last.clauses.push_back(node);

479 return true;

480 }

481 }

482

483 return false;

484}

485

486

487

488

489

490

491

492

493

494template <typename C, typename H>

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

497 const ClauseTy *node) {

498 return applyToInnermost(node);

499}

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531template <typename C, typename H>

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

534 const ClauseTy *node) {

535 bool applied = false;

536

537

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

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

540 if (dirDistribute != nullptr) {

541 dirDistribute->clauses.push_back(node);

542 applied = true;

543

544 if (dirTeams != nullptr) {

545 auto *shared = makeClause(

546 llvm::omp::Clause::OMPC_shared,

548 dirTeams->clauses.push_back(shared);

549 }

550 } else if (dirTeams != nullptr) {

551 dirTeams->clauses.push_back(node);

552 applied = true;

553 }

554

555

556 auto findWorksharing = [&]() {

558 for (auto &leaf : leafs) {

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

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

561 return &leaf;

562 }

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

564 };

565

566 auto dirWorksharing = findWorksharing();

567 if (dirWorksharing != nullptr) {

568 dirWorksharing->clauses.push_back(node);

569 applied = true;

570 }

571

572

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

574 if (dirTaskloop != nullptr) {

575 dirTaskloop->clauses.push_back(node);

576 applied = true;

577 }

578

579

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

581 if (dirParallel != nullptr) {

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

583 dirParallel->clauses.push_back(node);

584 applied = true;

585 } else {

586

587 auto *shared = makeClause(

588 llvm::omp::Clause::OMPC_shared,

590 dirParallel->clauses.push_back(shared);

591 }

592 }

593

594

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

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

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

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

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

600 }

601 return false;

602 };

603

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

605 if (dirTarget != nullptr) {

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

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

610 });

611 if (!objects.empty()) {

612 auto *firstp = makeClause(

613 llvm::omp::Clause::OMPC_firstprivate,

615 dirTarget->clauses.push_back(firstp);

616 applied = true;

617 }

618 }

619

620

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

622 dirTask->clauses.push_back(node);

623 applied = true;

624 }

625

626 return applied;

627}

628

629

630

631

632

633

634

635

636

637

638

639

640

641

642

643

644

645

646

647

648template <typename C, typename H>

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

651 const ClauseTy *node) {

652 bool applied = false;

653

654

655 applied = applyToAll(node);

656 if (!applied)

657 return false;

658

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

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

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

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

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

664 }

665 return false;

666 };

667

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

669

670

673 objects, std::back_inserter(sharedObjects),

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

675

676 if (!sharedObjects.empty()) {

677

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

679 auto *shared = makeClause(

680 llvm::omp::Clause::OMPC_shared,

682 dirParallel->clauses.push_back(shared);

683 applied = true;

684 }

685

686

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

688 auto *shared = makeClause(

689 llvm::omp::Clause::OMPC_shared,

691 dirTeams->clauses.push_back(shared);

692 applied = true;

693 }

694 }

695

696

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

700 objects, std::back_inserter(tofrom),

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

702

703 if (!tofrom.empty()) {

704 using MapType =

706 auto *map =

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

709 {MapType::Tofrom,

710 std::nullopt,

711 std::nullopt, std::nullopt,

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

713 dirTarget->clauses.push_back(map);

714 applied = true;

715 }

716 }

717

718 return applied;

719}

720

721

722

723

724

725

726

727

728template <typename C, typename H>

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

731 const ClauseTy *node) {

732

733 return applyToAll(node);

734}

735

736

737

738

739

740

741

742

743template <typename C, typename H>

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

746 const ClauseTy *node) {

747

748 return applyToAll(node);

749}

750

751

752

753

754

755

756

757

758template <typename C, typename H>

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

761 const ClauseTy *node) {

762

763 return applyToAll(node);

764}

765

766

767

768

769

770

771

772

773template <typename C, typename H>

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

776 const ClauseTy *node) {

777

778 return applyToAll(node);

779}

780

781

782

783

784

785

786

787

788

789

790template <typename C, typename H>

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

793 const ClauseTy *node) {

794

795

796

797

798 auto canMakePrivateCopy = [](llvm::omp::Clause id) {

799 switch (id) {

800

801 case llvm::omp::Clause::OMPC_firstprivate:

802 case llvm::omp::Clause::OMPC_in_reduction:

803 case llvm::omp::Clause::OMPC_lastprivate:

804 case llvm::omp::Clause::OMPC_linear:

805 case llvm::omp::Clause::OMPC_private:

806 case llvm::omp::Clause::OMPC_reduction:

807 case llvm::omp::Clause::OMPC_task_reduction:

808 return true;

809 default:

810 return false;

811 }

812 };

813

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

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

816 return canMakePrivateCopy(n->id);

817 });

818 });

819

820 return applied;

821}

822

823

824

825

826

827

828

829

830

831

832

833

834

835

836

837

838

839

840

841

842

843

844

845

846

847

848

849template <typename C, typename H>

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

852 const ClauseTy *node) {

854

855

856 bool applyToParallel = true, applyToTeams = true;

857

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

859 if (dirParallel) {

860 auto exclusions = llvm::concat(

862 llvm::omp::Directive::OMPD_loop,

863 llvm::omp::Directive::OMPD_sections,

864 llvm::omp::Directive::OMPD_taskloop,

865 });

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

867 return findDirective(id) != nullptr;

868 };

869

871 applyToParallel = false;

872 }

873

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

875 if (dirTeams) {

876

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

878 applyToTeams = false;

879 }

880

881 using ReductionModifier = typename ReductionTy::ReductionModifier;

882 using ReductionIdentifiers = typename ReductionTy::ReductionIdentifiers;

883

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

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

886

887

888

889

890 bool applied = false;

891

892

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

894 bool alreadyApplied) {

895 switch (mod) {

896 case ReductionModifier::Inscan:

897

898

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

901 case ReductionModifier::Task:

902 if (alreadyApplied)

903 return false;

904

905

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

908 case ReductionModifier::Default:

909 return true;

910 }

912 };

913

914 auto *unmodified = makeClause(

915 llvm::omp::Clause::OMPC_reduction,

916 ReductionTy{

917 {std::nullopt,

918 std::get(clause.t),

919 objects}});

920

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

922 bool effectiveApplied = false;

923

924

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

927 continue;

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

929 continue;

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

931 continue;

932

933 if (isValidModifier(leaf.id, effective, effectiveApplied)) {

934

935 leaf.clauses.push_back(node);

936 effectiveApplied = true;

937 } else {

938

939 leaf.clauses.push_back(unmodified);

940 }

941

942 applied = effectiveApplied;

943 }

944

945 if (!applied)

946 return false;

947

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

950 [&](const ObjectTy &object) {

951 auto maybeBase = helper.getBaseObject(object);

952 return maybeBase ? *maybeBase : object;

953 });

954

955

956 if (!sharedObjects.empty()) {

957 if (dirParallel && !applyToParallel) {

958 auto *shared = makeClause(

959 llvm::omp::Clause::OMPC_shared,

961 dirParallel->clauses.push_back(shared);

962 }

963 if (dirTeams && !applyToTeams) {

964 auto *shared = makeClause(

965 llvm::omp::Clause::OMPC_shared,

967 dirTeams->clauses.push_back(shared);

968 }

969 }

970

971

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

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

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

976 [&](const ObjectTy &object) {

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

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

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

980 });

981 if (!tofrom.empty()) {

982 using MapType =

984 auto *map = makeClause(

985 llvm::omp::Clause::OMPC_map,

987 {MapType::Tofrom, std::nullopt,

988 std::nullopt, std::nullopt,

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

990

991 dirTarget->clauses.push_back(map);

992 applied = true;

993 }

994 }

995

996 return applied;

997}

998

999

1000

1001

1002

1003

1004

1005

1006

1007

1008

1009

1010template <typename C, typename H>

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

1013 const ClauseTy *node) {

1014 using DirectiveNameModifier =

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

1018

1019 if (modifier) {

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

1021 auto *unmodified =

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

1024 {std::nullopt,

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

1026

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

1028 hasDir->clauses.push_back(unmodified);

1029 return true;

1030 }

1031 return false;

1032 }

1033

1034 return applyToAll(node);

1035}

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051

1052

1053

1054template <typename C, typename H>

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

1057 const ClauseTy *node) {

1058

1059 if (!applyToInnermost(node))

1060 return false;

1061

1062

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

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

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

1066

1067

1068

1070

1071 for (const ObjectTy &object : objects) {

1072 last.push_back(object);

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

1074 first.push_back(object);

1075 }

1076

1077 if (!first.empty()) {

1078 auto *firstp = makeClause(

1079 llvm::omp::Clause::OMPC_firstprivate,

1081 nodes.push_back(firstp);

1082 }

1083 if (last.empty()) {

1084 auto *lastp =

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

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

1088 nodes.push_back(lastp);

1089 }

1090 return true;

1091}

1092

1093

1094

1095

1096

1097

1098

1099

1100

1101template <typename C, typename H>

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

1104 const ClauseTy *node) {

1105 return applyToOutermost(node);

1106}

1107

1108template <typename C, typename H>

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

1111 const ClauseTy *node) {

1112 return applyToOutermost(node);

1113}

1114

1115template <typename C, typename H>

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

1118 const ClauseTy *node) {

1119 return applyToAll(node);

1120}

1121

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

1124

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

1127 implicit, [node](const ClauseTy &clause) { return &clause == node; });

1128 };

1129

1130 for (llvm::omp::Directive leaf :

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

1133

1134 for (const ClauseTy *node : nodes)

1135 addClauseSymsToMap(*node, node);

1136

1137

1138

1139

1140

1142 for (const ClauseTy *node : nodes) {

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

1145 }

1146 for (const auto *node : linears) {

1149 node->u),

1150 node);

1151 }

1152

1153

1154

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

1156 switch (node->id) {

1157 case llvm::omp::Clause::OMPC_allocate:

1158 case llvm::omp::Clause::OMPC_linear:

1159 return true;

1160 default:

1161 return false;

1162 }

1163 };

1164

1165

1166 for (const ClauseTy *node : nodes) {

1167 if (skip(node))

1168 continue;

1169 bool result =

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

1171 if (!isImplicit(node))

1172 success = success && result;

1173 }

1174

1175

1176 for (const ClauseTy *node : nodes) {

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

1178 continue;

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

1182 }

1183

1185}

1186

1187}

1188

1189#endif

Unify divergent function exit nodes

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

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

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)

A range adaptor for a pair of iterators.

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)

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.

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)

typename llvm::remove_cvref< T >::type remove_cvref_t

auto find_if(R &&Range, UnaryPredicate P)

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

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.

typename ClauseTy::ExprTy ExprTy

std::unordered_set< const ClauseTy * > ClauseSet

typename ClauseTy::TypeTy TypeTy

typename ClauseTy::IdTy IdTy

tomp::ObjectT< IdTy, ExprTy > ObjectTy

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

tomp::ListT< DirectiveWithClauses< ClauseType > > output

std::tuple< OPT(DirectiveNameModifier), IfExpression > t

type::DirectiveName DirectiveNameModifier

std::tuple< OPT(LastprivateModifier), List > t

std::tuple< OPT(StepComplexModifier), OPT(LinearModifier), List > t

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

std::tuple< OPT(ReductionModifier), ReductionIdentifiers, List > t