|
16 | 16 | #include "Utils.h"
|
17 | 17 | #include "flang/Lower/ConvertVariable.h"
|
18 | 18 | #include "flang/Lower/PFTBuilder.h"
|
| 19 | +#include "flang/Lower/Support/Utils.h" |
19 | 20 | #include "flang/Lower/SymbolMap.h"
|
20 | 21 | #include "flang/Optimizer/Builder/BoxValue.h"
|
21 | 22 | #include "flang/Optimizer/Builder/HLFIRTools.h"
|
@@ -527,188 +528,48 @@ void DataSharingProcessor::copyLastPrivatize(mlir::Operation *op) {
|
527 | 528 | }
|
528 | 529 | }
|
529 | 530 |
|
530 |
| -template <typename OpType, typename OperandsStructType> |
531 | 531 | void DataSharingProcessor::privatizeSymbol(
|
532 |
| - const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps) { |
| 532 | + const semantics::Symbol *symToPrivatize, |
| 533 | + mlir::omp::PrivateClauseOps *clauseOps) { |
533 | 534 | if (!useDelayedPrivatization) {
|
534 | 535 | cloneSymbol(symToPrivatize);
|
535 | 536 | copyFirstPrivateSymbol(symToPrivatize);
|
536 | 537 | return;
|
537 | 538 | }
|
538 | 539 |
|
539 |
| - const semantics::Symbol *sym = symToPrivatize->HasLocalLocality() |
540 |
| - ? &symToPrivatize->GetUltimate() |
541 |
| - : symToPrivatize; |
542 |
| - lower::SymbolBox hsb = symToPrivatize->HasLocalLocality() |
543 |
| - ? converter.shallowLookupSymbol(*sym) |
544 |
| - : converter.lookupOneLevelUpSymbol(*sym); |
545 |
| - assert(hsb && "Host symbol box not found"); |
546 |
| - hlfir::Entity entity{hsb.getAddr()}; |
547 |
| - bool cannotHaveNonDefaultLowerBounds = !entity.mayHaveNonDefaultLowerBounds(); |
548 |
| - |
549 |
| - mlir::Location symLoc = hsb.getAddr().getLoc(); |
550 |
| - std::string privatizerName = sym->name().ToString() + ".privatizer"; |
551 |
| - bool isFirstPrivate = |
552 |
| - symToPrivatize->test(semantics::Symbol::Flag::OmpFirstPrivate) || |
553 |
| - symToPrivatize->test(semantics::Symbol::Flag::LocalityLocalInit); |
554 |
| - |
555 |
| - mlir::Value privVal = hsb.getAddr(); |
556 |
| - mlir::Type allocType = privVal.getType(); |
557 |
| - if (!mlir::isa<fir::PointerType>(privVal.getType())) |
558 |
| - allocType = fir::unwrapRefType(privVal.getType()); |
559 |
| - |
560 |
| - if (auto poly = mlir::dyn_cast<fir::ClassType>(allocType)) { |
561 |
| - if (!mlir::isa<fir::PointerType>(poly.getEleTy()) && isFirstPrivate) |
562 |
| - TODO(symLoc, "create polymorphic host associated copy"); |
563 |
| - } |
564 |
| - |
565 |
| - // fir.array<> cannot be converted to any single llvm type and fir helpers |
566 |
| - // are not available in openmp to llvmir translation so we cannot generate |
567 |
| - // an alloca for a fir.array type there. Get around this by boxing all |
568 |
| - // arrays. |
569 |
| - if (mlir::isa<fir::SequenceType>(allocType)) { |
570 |
| - entity = genVariableBox(symLoc, firOpBuilder, entity); |
571 |
| - privVal = entity.getBase(); |
572 |
| - allocType = privVal.getType(); |
573 |
| - } |
574 |
| - |
575 |
| - if (mlir::isa<fir::BaseBoxType>(privVal.getType())) { |
576 |
| - // Boxes should be passed by reference into nested regions: |
577 |
| - auto oldIP = firOpBuilder.saveInsertionPoint(); |
578 |
| - firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock()); |
579 |
| - auto alloca = firOpBuilder.create<fir::AllocaOp>(symLoc, privVal.getType()); |
580 |
| - firOpBuilder.restoreInsertionPoint(oldIP); |
581 |
| - firOpBuilder.create<fir::StoreOp>(symLoc, privVal, alloca); |
582 |
| - privVal = alloca; |
583 |
| - } |
584 |
| - |
585 |
| - mlir::Type argType = privVal.getType(); |
586 |
| - |
587 |
| - OpType privatizerOp = [&]() { |
588 |
| - auto moduleOp = firOpBuilder.getModule(); |
589 |
| - auto uniquePrivatizerName = fir::getTypeAsString( |
590 |
| - allocType, converter.getKindMap(), |
591 |
| - converter.mangleName(*sym) + |
592 |
| - (isFirstPrivate ? "_firstprivate" : "_private")); |
593 |
| - |
594 |
| - if (auto existingPrivatizer = |
595 |
| - moduleOp.lookupSymbol<OpType>(uniquePrivatizerName)) |
596 |
| - return existingPrivatizer; |
597 |
| - |
598 |
| - mlir::OpBuilder::InsertionGuard guard(firOpBuilder); |
599 |
| - firOpBuilder.setInsertionPointToStart(moduleOp.getBody()); |
600 |
| - OpType result; |
601 |
| - |
602 |
| - if constexpr (std::is_same_v<OpType, mlir::omp::PrivateClauseOp>) { |
603 |
| - result = firOpBuilder.create<OpType>( |
604 |
| - symLoc, uniquePrivatizerName, allocType, |
605 |
| - isFirstPrivate ? mlir::omp::DataSharingClauseType::FirstPrivate |
606 |
| - : mlir::omp::DataSharingClauseType::Private); |
607 |
| - } else { |
608 |
| - result = firOpBuilder.create<OpType>( |
609 |
| - symLoc, uniquePrivatizerName, allocType, |
610 |
| - isFirstPrivate ? fir::LocalitySpecifierType::LocalInit |
611 |
| - : fir::LocalitySpecifierType::Local); |
612 |
| - } |
613 |
| - |
614 |
| - fir::ExtendedValue symExV = converter.getSymbolExtendedValue(*sym); |
615 |
| - lower::SymMapScope outerScope(symTable); |
616 |
| - |
617 |
| - // Populate the `init` region. |
618 |
| - // We need to initialize in the following cases: |
619 |
| - // 1. The allocation was for a derived type which requires initialization |
620 |
| - // (this can be skipped if it will be initialized anyway by the copy |
621 |
| - // region, unless the derived type has allocatable components) |
622 |
| - // 2. The allocation was for any kind of box |
623 |
| - // 3. The allocation was for a boxed character |
624 |
| - const bool needsInitialization = |
625 |
| - (Fortran::lower::hasDefaultInitialization(sym->GetUltimate()) && |
626 |
| - (!isFirstPrivate || hlfir::mayHaveAllocatableComponent(allocType))) || |
627 |
| - mlir::isa<fir::BaseBoxType>(allocType) || |
628 |
| - mlir::isa<fir::BoxCharType>(allocType); |
629 |
| - if (needsInitialization) { |
630 |
| - mlir::Region &initRegion = result.getInitRegion(); |
631 |
| - mlir::Block *initBlock = firOpBuilder.createBlock( |
632 |
| - &initRegion, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc}); |
633 |
| - |
634 |
| - populateByRefInitAndCleanupRegions( |
635 |
| - converter, symLoc, argType, /*scalarInitValue=*/nullptr, initBlock, |
636 |
| - result.getInitPrivateArg(), result.getInitMoldArg(), |
637 |
| - result.getDeallocRegion(), |
638 |
| - isFirstPrivate ? DeclOperationKind::FirstPrivate |
639 |
| - : DeclOperationKind::Private, |
640 |
| - sym, cannotHaveNonDefaultLowerBounds); |
641 |
| - // TODO: currently there are false positives from dead uses of the mold |
642 |
| - // arg |
643 |
| - if (result.initReadsFromMold()) |
644 |
| - mightHaveReadHostSym.insert(sym); |
645 |
| - } |
646 |
| - |
647 |
| - // Populate the `copy` region if this is a `firstprivate`. |
648 |
| - if (isFirstPrivate) { |
649 |
| - mlir::Region ©Region = result.getCopyRegion(); |
650 |
| - // First block argument corresponding to the original/host value while |
651 |
| - // second block argument corresponding to the privatized value. |
652 |
| - mlir::Block *copyEntryBlock = firOpBuilder.createBlock( |
653 |
| - ©Region, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc}); |
654 |
| - firOpBuilder.setInsertionPointToEnd(copyEntryBlock); |
655 |
| - |
656 |
| - auto addSymbol = [&](unsigned argIdx, const semantics::Symbol *symToMap, |
657 |
| - bool force = false) { |
658 |
| - symExV.match( |
659 |
| - [&](const fir::MutableBoxValue &box) { |
660 |
| - symTable.addSymbol( |
661 |
| - *symToMap, |
662 |
| - fir::substBase(box, copyRegion.getArgument(argIdx)), force); |
663 |
| - }, |
664 |
| - [&](const auto &box) { |
665 |
| - symTable.addSymbol(*symToMap, copyRegion.getArgument(argIdx), |
666 |
| - force); |
667 |
| - }); |
668 |
| - }; |
669 |
| - |
670 |
| - addSymbol(0, sym, true); |
671 |
| - lower::SymMapScope innerScope(symTable); |
672 |
| - addSymbol(1, symToPrivatize); |
673 |
| - |
674 |
| - auto ip = firOpBuilder.saveInsertionPoint(); |
675 |
| - copyFirstPrivateSymbol(symToPrivatize, &ip); |
676 |
| - |
677 |
| - if constexpr (std::is_same_v<OpType, mlir::omp::PrivateClauseOp>) { |
678 |
| - firOpBuilder.create<mlir::omp::YieldOp>( |
679 |
| - hsb.getAddr().getLoc(), |
680 |
| - symTable.shallowLookupSymbol(*symToPrivatize).getAddr()); |
681 |
| - } else { |
682 |
| - firOpBuilder.create<fir::YieldOp>( |
683 |
| - hsb.getAddr().getLoc(), |
684 |
| - symTable.shallowLookupSymbol(*symToPrivatize).getAddr()); |
685 |
| - } |
686 |
| - } |
687 |
| - |
688 |
| - return result; |
689 |
| - }(); |
690 |
| - |
691 |
| - if (clauseOps) { |
692 |
| - clauseOps->privateSyms.push_back(mlir::SymbolRefAttr::get(privatizerOp)); |
693 |
| - clauseOps->privateVars.push_back(privVal); |
694 |
| - } |
| 540 | + auto initGen = [&](mlir::omp::PrivateClauseOp result, mlir::Type argType) { |
| 541 | + lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*symToPrivatize); |
| 542 | + assert(hsb && "Host symbol box not found"); |
| 543 | + hlfir::Entity entity{hsb.getAddr()}; |
| 544 | + bool cannotHaveNonDefaultLowerBounds = |
| 545 | + !entity.mayHaveNonDefaultLowerBounds(); |
| 546 | + |
| 547 | + mlir::Region &initRegion = result.getInitRegion(); |
| 548 | + mlir::Location symLoc = hsb.getAddr().getLoc(); |
| 549 | + mlir::Block *initBlock = firOpBuilder.createBlock( |
| 550 | + &initRegion, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc}); |
| 551 | + |
| 552 | + bool emitCopyRegion = |
| 553 | + symToPrivatize->test(semantics::Symbol::Flag::OmpFirstPrivate); |
| 554 | + |
| 555 | + populateByRefInitAndCleanupRegions( |
| 556 | + converter, symLoc, argType, /*scalarInitValue=*/nullptr, initBlock, |
| 557 | + result.getInitPrivateArg(), result.getInitMoldArg(), |
| 558 | + result.getDeallocRegion(), |
| 559 | + emitCopyRegion ? omp::DeclOperationKind::FirstPrivate |
| 560 | + : omp::DeclOperationKind::Private, |
| 561 | + symToPrivatize, cannotHaveNonDefaultLowerBounds); |
| 562 | + // TODO: currently there are false positives from dead uses of the mold |
| 563 | + // arg |
| 564 | + if (result.initReadsFromMold()) |
| 565 | + mightHaveReadHostSym.insert(symToPrivatize); |
| 566 | + }; |
695 | 567 |
|
696 |
| - if (symToPrivatize->HasLocalLocality()) |
697 |
| - allPrivatizedSymbols.insert(symToPrivatize); |
| 568 | + Fortran::lower::privatizeSymbol<mlir::omp::PrivateClauseOp, |
| 569 | + mlir::omp::PrivateClauseOps>( |
| 570 | + converter, firOpBuilder, symTable, initGen, allPrivatizedSymbols, |
| 571 | + symToPrivatize, clauseOps); |
698 | 572 | }
|
699 |
| - |
700 |
| -template void |
701 |
| -DataSharingProcessor::privatizeSymbol<mlir::omp::PrivateClauseOp, |
702 |
| - mlir::omp::PrivateClauseOps>( |
703 |
| - const semantics::Symbol *symToPrivatize, |
704 |
| - mlir::omp::PrivateClauseOps *clauseOps); |
705 |
| - |
706 |
| -template void |
707 |
| -DataSharingProcessor::privatizeSymbol<fir::LocalitySpecifierOp, |
708 |
| - fir::LocalitySpecifierOperands>( |
709 |
| - const semantics::Symbol *symToPrivatize, |
710 |
| - fir::LocalitySpecifierOperands *clauseOps); |
711 |
| - |
712 | 573 | } // namespace omp
|
713 | 574 | } // namespace lower
|
714 | 575 | } // namespace Fortran
|
0 commit comments