|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
9 | 9 | #include "flang/Optimizer/Analysis/AliasAnalysis.h"
|
| 10 | +#include "flang/Optimizer/CodeGen/CGOps.h" |
10 | 11 | #include "flang/Optimizer/Dialect/FIROps.h"
|
11 | 12 | #include "flang/Optimizer/Dialect/FIROpsSupport.h"
|
12 | 13 | #include "flang/Optimizer/Dialect/FIRType.h"
|
|
19 | 20 | #include "mlir/IR/BuiltinOps.h"
|
20 | 21 | #include "mlir/IR/Value.h"
|
21 | 22 | #include "mlir/Interfaces/SideEffectInterfaces.h"
|
22 |
| -#include "flang/Optimizer/CodeGen/CGOps.h" |
23 | 23 | #include "llvm/ADT/TypeSwitch.h"
|
24 | 24 | #include "llvm/Support/Casting.h"
|
25 | 25 | #include "llvm/Support/Debug.h"
|
@@ -579,13 +579,14 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
|
579 | 579 | followBoxData = true;
|
580 | 580 | approximateSource = true;
|
581 | 581 | })
|
582 |
| - .Case<fir::EmboxOp, fir::ReboxOp, fir::cg::XEmboxOp, fir::cg::XReboxOp>([&](auto op) { |
583 |
| - if (followBoxData) { |
584 |
| - v = op->getOperand(0); |
585 |
| - defOp = v.getDefiningOp(); |
586 |
| - } else |
587 |
| - breakFromLoop = true; |
588 |
| - }) |
| 582 | + .Case<fir::EmboxOp, fir::ReboxOp, fir::cg::XEmboxOp, fir::cg::XReboxOp>( |
| 583 | + [&](auto op) { |
| 584 | + if (followBoxData) { |
| 585 | + v = op->getOperand(0); |
| 586 | + defOp = v.getDefiningOp(); |
| 587 | + } else |
| 588 | + breakFromLoop = true; |
| 589 | + }) |
589 | 590 | .Case<fir::LoadOp>([&](auto op) {
|
590 | 591 | // If load is inside target and it points to mapped item,
|
591 | 592 | // continue tracking.
|
@@ -654,94 +655,99 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
|
654 | 655 | global = llvm::cast<fir::AddrOfOp>(op).getSymbol();
|
655 | 656 | breakFromLoop = true;
|
656 | 657 | })
|
657 |
| - .Case<hlfir::DeclareOp, fir::DeclareOp, fir::cg::XDeclareOp>([&](auto op) { |
658 |
| - bool isPrivateItem = false; |
659 |
| - if (omp::BlockArgOpenMPOpInterface argIface = |
660 |
| - dyn_cast<omp::BlockArgOpenMPOpInterface>(op->getParentOp())) { |
661 |
| - Value ompValArg; |
662 |
| - llvm::TypeSwitch<Operation *>(op->getParentOp()) |
663 |
| - .template Case<omp::TargetOp>([&](auto targetOp) { |
664 |
| - // If declare operation is inside omp target region, |
665 |
| - // continue alias analysis outside the target region |
666 |
| - for (auto [opArg, blockArg] : llvm::zip_equal( |
667 |
| - targetOp.getMapVars(), argIface.getMapBlockArgs())) { |
668 |
| - if (blockArg == op.getMemref()) { |
669 |
| - omp::MapInfoOp mapInfo = |
670 |
| - llvm::cast<omp::MapInfoOp>(opArg.getDefiningOp()); |
671 |
| - ompValArg = mapInfo.getVarPtr(); |
672 |
| - return; |
673 |
| - } |
674 |
| - } |
675 |
| - // If given operation does not reflect mapping item, |
676 |
| - // check private clause |
677 |
| - isPrivateItem = isPrivateArg(argIface, targetOp, op); |
678 |
| - }) |
679 |
| - .template Case<omp::DistributeOp, omp::ParallelOp, |
680 |
| - omp::SectionsOp, omp::SimdOp, omp::SingleOp, |
681 |
| - omp::TaskloopOp, omp::TaskOp, omp::WsloopOp>( |
682 |
| - [&](auto privateOp) { |
683 |
| - isPrivateItem = isPrivateArg(argIface, privateOp, op); |
684 |
| - }); |
685 |
| - if (ompValArg) { |
686 |
| - v = ompValArg; |
687 |
| - defOp = ompValArg.getDefiningOp(); |
688 |
| - return; |
689 |
| - } |
690 |
| - } |
691 |
| - auto varIf = llvm::dyn_cast<fir::FortranVariableOpInterface>(defOp); |
692 |
| - if(varIf){ |
693 |
| - // While going through a declare operation collect |
694 |
| - // the variable attributes from it. Right now, some |
695 |
| - // of the attributes are duplicated, e.g. a TARGET dummy |
696 |
| - // argument has the target attribute both on its declare |
697 |
| - // operation and on the entry block argument. |
698 |
| - // In case of host associated use, the declare operation |
699 |
| - // is the only carrier of the variable attributes, |
700 |
| - // so we have to collect them here. |
701 |
| - attributes |= getAttrsFromVariable(varIf); |
702 |
| - isCapturedInInternalProcedure |= |
703 |
| - varIf.isCapturedInInternalProcedure(); |
704 |
| - if (varIf.isHostAssoc()) { |
705 |
| - // Do not track past such DeclareOp, because it does not |
706 |
| - // currently provide any useful information. The host associated |
707 |
| - // access will end up dereferencing the host association tuple, |
708 |
| - // so we may as well stop right now. |
709 |
| - v = defOp->getResult(0); |
710 |
| - // TODO: if the host associated variable is a dummy argument |
711 |
| - // of the host, I think, we can treat it as SourceKind::Argument |
712 |
| - // for the purpose of alias analysis inside the internal procedure. |
713 |
| - type = SourceKind::HostAssoc; |
714 |
| - breakFromLoop = true; |
715 |
| - return; |
716 |
| - } |
717 |
| - } |
718 |
| - if (getLastInstantiationPoint) { |
719 |
| - // Fetch only the innermost instantiation point. |
720 |
| - if (!instantiationPoint) |
721 |
| - instantiationPoint = op; |
722 |
| - |
723 |
| - if (op.getDummyScope()) { |
724 |
| - // Do not track past DeclareOp that has the dummy_scope |
725 |
| - // operand. This DeclareOp is known to represent |
726 |
| - // a dummy argument for some runtime instantiation |
727 |
| - // of a procedure. |
728 |
| - type = SourceKind::Argument; |
729 |
| - breakFromLoop = true; |
730 |
| - return; |
731 |
| - } |
732 |
| - } else { |
733 |
| - instantiationPoint = op; |
734 |
| - } |
735 |
| - if (isPrivateItem) { |
736 |
| - type = SourceKind::Allocate; |
737 |
| - breakFromLoop = true; |
738 |
| - return; |
739 |
| - } |
740 |
| - // TODO: Look for the fortran attributes present on the operation |
741 |
| - // Track further through the operand |
742 |
| - v = op.getMemref(); |
743 |
| - defOp = v.getDefiningOp(); |
744 |
| - }) |
| 658 | + .Case<hlfir::DeclareOp, fir::DeclareOp, fir::cg::XDeclareOp>( |
| 659 | + [&](auto op) { |
| 660 | + bool isPrivateItem = false; |
| 661 | + if (omp::BlockArgOpenMPOpInterface argIface = |
| 662 | + dyn_cast<omp::BlockArgOpenMPOpInterface>( |
| 663 | + op->getParentOp())) { |
| 664 | + Value ompValArg; |
| 665 | + llvm::TypeSwitch<Operation *>(op->getParentOp()) |
| 666 | + .template Case<omp::TargetOp>([&](auto targetOp) { |
| 667 | + // If declare operation is inside omp target region, |
| 668 | + // continue alias analysis outside the target region |
| 669 | + for (auto [opArg, blockArg] : |
| 670 | + llvm::zip_equal(targetOp.getMapVars(), |
| 671 | + argIface.getMapBlockArgs())) { |
| 672 | + if (blockArg == op.getMemref()) { |
| 673 | + omp::MapInfoOp mapInfo = |
| 674 | + llvm::cast<omp::MapInfoOp>(opArg.getDefiningOp()); |
| 675 | + ompValArg = mapInfo.getVarPtr(); |
| 676 | + return; |
| 677 | + } |
| 678 | + } |
| 679 | + // If given operation does not reflect mapping item, |
| 680 | + // check private clause |
| 681 | + isPrivateItem = isPrivateArg(argIface, targetOp, op); |
| 682 | + }) |
| 683 | + .template Case<omp::DistributeOp, omp::ParallelOp, |
| 684 | + omp::SectionsOp, omp::SimdOp, omp::SingleOp, |
| 685 | + omp::TaskloopOp, omp::TaskOp, omp::WsloopOp>( |
| 686 | + [&](auto privateOp) { |
| 687 | + isPrivateItem = isPrivateArg(argIface, privateOp, op); |
| 688 | + }); |
| 689 | + if (ompValArg) { |
| 690 | + v = ompValArg; |
| 691 | + defOp = ompValArg.getDefiningOp(); |
| 692 | + return; |
| 693 | + } |
| 694 | + } |
| 695 | + auto varIf = |
| 696 | + llvm::dyn_cast<fir::FortranVariableOpInterface>(defOp); |
| 697 | + if (varIf) { |
| 698 | + // While going through a declare operation collect |
| 699 | + // the variable attributes from it. Right now, some |
| 700 | + // of the attributes are duplicated, e.g. a TARGET dummy |
| 701 | + // argument has the target attribute both on its declare |
| 702 | + // operation and on the entry block argument. |
| 703 | + // In case of host associated use, the declare operation |
| 704 | + // is the only carrier of the variable attributes, |
| 705 | + // so we have to collect them here. |
| 706 | + attributes |= getAttrsFromVariable(varIf); |
| 707 | + isCapturedInInternalProcedure |= |
| 708 | + varIf.isCapturedInInternalProcedure(); |
| 709 | + if (varIf.isHostAssoc()) { |
| 710 | + // Do not track past such DeclareOp, because it does not |
| 711 | + // currently provide any useful information. The host |
| 712 | + // associated access will end up dereferencing the host |
| 713 | + // association tuple, so we may as well stop right now. |
| 714 | + v = defOp->getResult(0); |
| 715 | + // TODO: if the host associated variable is a dummy argument |
| 716 | + // of the host, I think, we can treat it as |
| 717 | + // SourceKind::Argument for the purpose of alias analysis |
| 718 | + // inside the internal procedure. |
| 719 | + type = SourceKind::HostAssoc; |
| 720 | + breakFromLoop = true; |
| 721 | + return; |
| 722 | + } |
| 723 | + } |
| 724 | + if (getLastInstantiationPoint) { |
| 725 | + // Fetch only the innermost instantiation point. |
| 726 | + if (!instantiationPoint) |
| 727 | + instantiationPoint = op; |
| 728 | + |
| 729 | + if (op.getDummyScope()) { |
| 730 | + // Do not track past DeclareOp that has the dummy_scope |
| 731 | + // operand. This DeclareOp is known to represent |
| 732 | + // a dummy argument for some runtime instantiation |
| 733 | + // of a procedure. |
| 734 | + type = SourceKind::Argument; |
| 735 | + breakFromLoop = true; |
| 736 | + return; |
| 737 | + } |
| 738 | + } else { |
| 739 | + instantiationPoint = op; |
| 740 | + } |
| 741 | + if (isPrivateItem) { |
| 742 | + type = SourceKind::Allocate; |
| 743 | + breakFromLoop = true; |
| 744 | + return; |
| 745 | + } |
| 746 | + // TODO: Look for the fortran attributes present on the operation |
| 747 | + // Track further through the operand |
| 748 | + v = op.getMemref(); |
| 749 | + defOp = v.getDefiningOp(); |
| 750 | + }) |
745 | 751 | .Case<hlfir::DesignateOp>([&](auto op) {
|
746 | 752 | auto varIf = llvm::cast<fir::FortranVariableOpInterface>(defOp);
|
747 | 753 | attributes |= getAttrsFromVariable(varIf);
|
|
0 commit comments