[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