[flang-commits] [flang] [flang] Add support to fir::cg in alias analysis (PR #127827)
Susan Tan ス-ザン タン via flang-commits
flang-commits at lists.llvm.org
Wed Feb 19 08:57:02 PST 2025
https://github.com/SusanTan updated https://github.com/llvm/llvm-project/pull/127827
>From 1b86576d1ecfd94386e50fa441912ff006ad7a36 Mon Sep 17 00:00:00 2001
From: Susan Tan <zujunt at nvidia.com>
Date: Fri, 14 Feb 2025 13:10:24 -0800
Subject: [PATCH 1/2] add support to fir::cg
---
.../lib/Optimizer/Analysis/AliasAnalysis.cpp | 56 ++++++++++---------
1 file changed, 30 insertions(+), 26 deletions(-)
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 873758487ddd0..f95a66ed066da 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -19,6 +19,7 @@
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Value.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "flang/Optimizer/CodeGen/CGOps.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
@@ -578,7 +579,7 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
followBoxData = true;
approximateSource = true;
})
- .Case<fir::EmboxOp, fir::ReboxOp>([&](auto op) {
+ .Case<fir::EmboxOp, fir::ReboxOp, fir::cg::XEmboxOp, fir::cg::XReboxOp>([&](auto op) {
if (followBoxData) {
v = op->getOperand(0);
defOp = v.getDefiningOp();
@@ -591,6 +592,7 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
Operation *loadMemrefOp = op.getMemref().getDefiningOp();
bool isDeclareOp =
llvm::isa_and_present<fir::DeclareOp>(loadMemrefOp) ||
+ llvm::isa_and_present<fir::cg::XDeclareOp>(loadMemrefOp) ||
llvm::isa_and_present<hlfir::DeclareOp>(loadMemrefOp);
if (isDeclareOp &&
llvm::isa<omp::TargetOp>(loadMemrefOp->getParentOp())) {
@@ -652,7 +654,7 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
global = llvm::cast<fir::AddrOfOp>(op).getSymbol();
breakFromLoop = true;
})
- .Case<hlfir::DeclareOp, fir::DeclareOp>([&](auto op) {
+ .Case<hlfir::DeclareOp, fir::DeclareOp, fir::cg::XDeclareOp>([&](auto op) {
bool isPrivateItem = false;
if (omp::BlockArgOpenMPOpInterface argIface =
dyn_cast<omp::BlockArgOpenMPOpInterface>(op->getParentOp())) {
@@ -686,30 +688,32 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
return;
}
}
- auto varIf = llvm::cast<fir::FortranVariableOpInterface>(defOp);
- // While going through a declare operation collect
- // the variable attributes from it. Right now, some
- // of the attributes are duplicated, e.g. a TARGET dummy
- // argument has the target attribute both on its declare
- // operation and on the entry block argument.
- // In case of host associated use, the declare operation
- // is the only carrier of the variable attributes,
- // so we have to collect them here.
- attributes |= getAttrsFromVariable(varIf);
- isCapturedInInternalProcedure |=
- varIf.isCapturedInInternalProcedure();
- if (varIf.isHostAssoc()) {
- // Do not track past such DeclareOp, because it does not
- // currently provide any useful information. The host associated
- // access will end up dereferencing the host association tuple,
- // so we may as well stop right now.
- v = defOp->getResult(0);
- // TODO: if the host associated variable is a dummy argument
- // of the host, I think, we can treat it as SourceKind::Argument
- // for the purpose of alias analysis inside the internal procedure.
- type = SourceKind::HostAssoc;
- breakFromLoop = true;
- return;
+ auto varIf = llvm::dyn_cast<fir::FortranVariableOpInterface>(defOp);
+ if(varIf){
+ // While going through a declare operation collect
+ // the variable attributes from it. Right now, some
+ // of the attributes are duplicated, e.g. a TARGET dummy
+ // argument has the target attribute both on its declare
+ // operation and on the entry block argument.
+ // In case of host associated use, the declare operation
+ // is the only carrier of the variable attributes,
+ // so we have to collect them here.
+ attributes |= getAttrsFromVariable(varIf);
+ isCapturedInInternalProcedure |=
+ varIf.isCapturedInInternalProcedure();
+ if (varIf.isHostAssoc()) {
+ // Do not track past such DeclareOp, because it does not
+ // currently provide any useful information. The host associated
+ // access will end up dereferencing the host association tuple,
+ // so we may as well stop right now.
+ v = defOp->getResult(0);
+ // TODO: if the host associated variable is a dummy argument
+ // of the host, I think, we can treat it as SourceKind::Argument
+ // for the purpose of alias analysis inside the internal procedure.
+ type = SourceKind::HostAssoc;
+ breakFromLoop = true;
+ return;
+ }
}
if (getLastInstantiationPoint) {
// Fetch only the innermost instantiation point.
>From b031c9bb556b6082d33cf651d545c291a92ca721 Mon Sep 17 00:00:00 2001
From: Susan Tan <zujunt at nvidia.com>
Date: Wed, 19 Feb 2025 08:56:17 -0800
Subject: [PATCH 2/2] format
---
.../lib/Optimizer/Analysis/AliasAnalysis.cpp | 198 +++++++++---------
1 file changed, 102 insertions(+), 96 deletions(-)
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index f95a66ed066da..911a013e9efc6 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Analysis/AliasAnalysis.h"
+#include "flang/Optimizer/CodeGen/CGOps.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -19,7 +20,6 @@
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Value.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
-#include "flang/Optimizer/CodeGen/CGOps.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
@@ -579,13 +579,14 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
followBoxData = true;
approximateSource = true;
})
- .Case<fir::EmboxOp, fir::ReboxOp, fir::cg::XEmboxOp, fir::cg::XReboxOp>([&](auto op) {
- if (followBoxData) {
- v = op->getOperand(0);
- defOp = v.getDefiningOp();
- } else
- breakFromLoop = true;
- })
+ .Case<fir::EmboxOp, fir::ReboxOp, fir::cg::XEmboxOp, fir::cg::XReboxOp>(
+ [&](auto op) {
+ if (followBoxData) {
+ v = op->getOperand(0);
+ defOp = v.getDefiningOp();
+ } else
+ breakFromLoop = true;
+ })
.Case<fir::LoadOp>([&](auto op) {
// If load is inside target and it points to mapped item,
// continue tracking.
@@ -654,94 +655,99 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
global = llvm::cast<fir::AddrOfOp>(op).getSymbol();
breakFromLoop = true;
})
- .Case<hlfir::DeclareOp, fir::DeclareOp, fir::cg::XDeclareOp>([&](auto op) {
- bool isPrivateItem = false;
- if (omp::BlockArgOpenMPOpInterface argIface =
- dyn_cast<omp::BlockArgOpenMPOpInterface>(op->getParentOp())) {
- Value ompValArg;
- llvm::TypeSwitch<Operation *>(op->getParentOp())
- .template Case<omp::TargetOp>([&](auto targetOp) {
- // If declare operation is inside omp target region,
- // continue alias analysis outside the target region
- for (auto [opArg, blockArg] : llvm::zip_equal(
- targetOp.getMapVars(), argIface.getMapBlockArgs())) {
- if (blockArg == op.getMemref()) {
- omp::MapInfoOp mapInfo =
- llvm::cast<omp::MapInfoOp>(opArg.getDefiningOp());
- ompValArg = mapInfo.getVarPtr();
- return;
- }
- }
- // If given operation does not reflect mapping item,
- // check private clause
- isPrivateItem = isPrivateArg(argIface, targetOp, op);
- })
- .template Case<omp::DistributeOp, omp::ParallelOp,
- omp::SectionsOp, omp::SimdOp, omp::SingleOp,
- omp::TaskloopOp, omp::TaskOp, omp::WsloopOp>(
- [&](auto privateOp) {
- isPrivateItem = isPrivateArg(argIface, privateOp, op);
- });
- if (ompValArg) {
- v = ompValArg;
- defOp = ompValArg.getDefiningOp();
- return;
- }
- }
- auto varIf = llvm::dyn_cast<fir::FortranVariableOpInterface>(defOp);
- if(varIf){
- // While going through a declare operation collect
- // the variable attributes from it. Right now, some
- // of the attributes are duplicated, e.g. a TARGET dummy
- // argument has the target attribute both on its declare
- // operation and on the entry block argument.
- // In case of host associated use, the declare operation
- // is the only carrier of the variable attributes,
- // so we have to collect them here.
- attributes |= getAttrsFromVariable(varIf);
- isCapturedInInternalProcedure |=
- varIf.isCapturedInInternalProcedure();
- if (varIf.isHostAssoc()) {
- // Do not track past such DeclareOp, because it does not
- // currently provide any useful information. The host associated
- // access will end up dereferencing the host association tuple,
- // so we may as well stop right now.
- v = defOp->getResult(0);
- // TODO: if the host associated variable is a dummy argument
- // of the host, I think, we can treat it as SourceKind::Argument
- // for the purpose of alias analysis inside the internal procedure.
- type = SourceKind::HostAssoc;
- breakFromLoop = true;
- return;
- }
- }
- if (getLastInstantiationPoint) {
- // Fetch only the innermost instantiation point.
- if (!instantiationPoint)
- instantiationPoint = op;
-
- if (op.getDummyScope()) {
- // Do not track past DeclareOp that has the dummy_scope
- // operand. This DeclareOp is known to represent
- // a dummy argument for some runtime instantiation
- // of a procedure.
- type = SourceKind::Argument;
- breakFromLoop = true;
- return;
- }
- } else {
- instantiationPoint = op;
- }
- if (isPrivateItem) {
- type = SourceKind::Allocate;
- breakFromLoop = true;
- return;
- }
- // TODO: Look for the fortran attributes present on the operation
- // Track further through the operand
- v = op.getMemref();
- defOp = v.getDefiningOp();
- })
+ .Case<hlfir::DeclareOp, fir::DeclareOp, fir::cg::XDeclareOp>(
+ [&](auto op) {
+ bool isPrivateItem = false;
+ if (omp::BlockArgOpenMPOpInterface argIface =
+ dyn_cast<omp::BlockArgOpenMPOpInterface>(
+ op->getParentOp())) {
+ Value ompValArg;
+ llvm::TypeSwitch<Operation *>(op->getParentOp())
+ .template Case<omp::TargetOp>([&](auto targetOp) {
+ // If declare operation is inside omp target region,
+ // continue alias analysis outside the target region
+ for (auto [opArg, blockArg] :
+ llvm::zip_equal(targetOp.getMapVars(),
+ argIface.getMapBlockArgs())) {
+ if (blockArg == op.getMemref()) {
+ omp::MapInfoOp mapInfo =
+ llvm::cast<omp::MapInfoOp>(opArg.getDefiningOp());
+ ompValArg = mapInfo.getVarPtr();
+ return;
+ }
+ }
+ // If given operation does not reflect mapping item,
+ // check private clause
+ isPrivateItem = isPrivateArg(argIface, targetOp, op);
+ })
+ .template Case<omp::DistributeOp, omp::ParallelOp,
+ omp::SectionsOp, omp::SimdOp, omp::SingleOp,
+ omp::TaskloopOp, omp::TaskOp, omp::WsloopOp>(
+ [&](auto privateOp) {
+ isPrivateItem = isPrivateArg(argIface, privateOp, op);
+ });
+ if (ompValArg) {
+ v = ompValArg;
+ defOp = ompValArg.getDefiningOp();
+ return;
+ }
+ }
+ auto varIf =
+ llvm::dyn_cast<fir::FortranVariableOpInterface>(defOp);
+ if (varIf) {
+ // While going through a declare operation collect
+ // the variable attributes from it. Right now, some
+ // of the attributes are duplicated, e.g. a TARGET dummy
+ // argument has the target attribute both on its declare
+ // operation and on the entry block argument.
+ // In case of host associated use, the declare operation
+ // is the only carrier of the variable attributes,
+ // so we have to collect them here.
+ attributes |= getAttrsFromVariable(varIf);
+ isCapturedInInternalProcedure |=
+ varIf.isCapturedInInternalProcedure();
+ if (varIf.isHostAssoc()) {
+ // Do not track past such DeclareOp, because it does not
+ // currently provide any useful information. The host
+ // associated access will end up dereferencing the host
+ // association tuple, so we may as well stop right now.
+ v = defOp->getResult(0);
+ // TODO: if the host associated variable is a dummy argument
+ // of the host, I think, we can treat it as
+ // SourceKind::Argument for the purpose of alias analysis
+ // inside the internal procedure.
+ type = SourceKind::HostAssoc;
+ breakFromLoop = true;
+ return;
+ }
+ }
+ if (getLastInstantiationPoint) {
+ // Fetch only the innermost instantiation point.
+ if (!instantiationPoint)
+ instantiationPoint = op;
+
+ if (op.getDummyScope()) {
+ // Do not track past DeclareOp that has the dummy_scope
+ // operand. This DeclareOp is known to represent
+ // a dummy argument for some runtime instantiation
+ // of a procedure.
+ type = SourceKind::Argument;
+ breakFromLoop = true;
+ return;
+ }
+ } else {
+ instantiationPoint = op;
+ }
+ if (isPrivateItem) {
+ type = SourceKind::Allocate;
+ breakFromLoop = true;
+ return;
+ }
+ // TODO: Look for the fortran attributes present on the operation
+ // Track further through the operand
+ v = op.getMemref();
+ defOp = v.getDefiningOp();
+ })
.Case<hlfir::DesignateOp>([&](auto op) {
auto varIf = llvm::cast<fir::FortranVariableOpInterface>(defOp);
attributes |= getAttrsFromVariable(varIf);
More information about the flang-commits
mailing list