|
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