Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Flang][AliasAnalysis] Alias analysis for tmp arrays #111972

Merged
merged 1 commit into from
Oct 14, 2024

Conversation

DominikAdamski
Copy link
Contributor

This patch extends the alias analysis for temporary arrays in Flang. With this extension, Flang can now determine that the temporary array [a, b, c] does not alias with arrayD in Fortran code:

  integer :: a, b, c
  integer :: arrayD(3)
  arrayD = [ a, b, c ]

This patch extends the alias analysis for temporary arrays
in Flang. With this extension, Flang can now determine that
the temporary array [a, b, c] does not alias with arrayD
in Fortran code:

    integer :: a, b, c
    integer :: arrayD(3)
    arrayD = [ a, b, c ]
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Oct 11, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 11, 2024

@llvm/pr-subscribers-flang-fir-hlfir

Author: Dominik Adamski (DominikAdamski)

Changes

This patch extends the alias analysis for temporary arrays in Flang. With this extension, Flang can now determine that the temporary array [a, b, c] does not alias with arrayD in Fortran code:

  integer :: a, b, c
  integer :: arrayD(3)
  arrayD = [ a, b, c ]

Full diff: https://github.com/llvm/llvm-project/pull/111972.diff

2 Files Affected:

  • (modified) flang/lib/Optimizer/Analysis/AliasAnalysis.cpp (+4)
  • (added) flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir (+48)
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index e88da5a8ebae19..a9f1aef2f7d655 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -255,6 +255,10 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
   while (defOp && !breakFromLoop) {
     ty = defOp->getResultTypes()[0];
     llvm::TypeSwitch<Operation *>(defOp)
+        .Case<hlfir::AsExprOp>([&](auto op) {
+          v = op.getVar();
+          defOp = v.getDefiningOp();
+        })
         .Case<fir::AllocaOp, fir::AllocMemOp>([&](auto op) {
           // Unique memory allocation.
           type = SourceKind::Allocate;
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir
new file mode 100644
index 00000000000000..91616a414676f9
--- /dev/null
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir
@@ -0,0 +1,48 @@
+// Use --mlir-disable-threading so that the AA queries are serialized
+// as well as its diagnostic output.
+// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+// Fortran source code:
+// program TestTmpArrayAssignment
+//   integer :: a, b, c
+//   integer :: arrayD(3)
+//
+//   arrayD = [ a, b, c ]
+// end program TestTmpArrayAssignment
+
+// CHECK-LABEL: Testing : "_QPTestTmpArrayAssignment"
+// CHECK-DAG: ArrayD#0 <-> tmp_array#0: NoAlias
+func.func @_QPTestTmpArrayAssignment() attributes {fir.bindc_name = "testtmparrayassignment"} {
+  %0 = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFEa"}
+  %1:2 = hlfir.declare %0 {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %c3 = arith.constant 3 : index
+  %2 = fir.alloca !fir.array<3xi32> {bindc_name = "arrayd", uniq_name = "_QFEarrayd", test.ptr = "ArrayD" }
+  %3 = fir.shape %c3 : (index) -> !fir.shape<1>
+  %4:2 = hlfir.declare %2(%3) {uniq_name = "_QFEarrayd"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xi32>>, !fir.ref<!fir.array<3xi32>>)
+  %5 = fir.alloca i32 {bindc_name = "b", uniq_name = "_QFEb"}
+  %6:2 = hlfir.declare %5 {uniq_name = "_QFEb"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %7 = fir.alloca i32 {bindc_name = "c", uniq_name = "_QFEc"}
+  %8:2 = hlfir.declare %7 {uniq_name = "_QFEc"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %c3_0 = arith.constant 3 : index
+  %c1 = arith.constant 1 : index
+  %c1_1 = arith.constant 1 : index
+  %9 = fir.allocmem !fir.array<3xi32> {bindc_name = ".tmp.arrayctor", uniq_name = ""}
+  %10 = fir.shape %c3_0 : (index) -> !fir.shape<1>
+  %11:2 = hlfir.declare %9(%10) {uniq_name = ".tmp.arrayctor"} : (!fir.heap<!fir.array<3xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<3xi32>>, !fir.heap<!fir.array<3xi32>>)
+  %12 = fir.load %1#0 : !fir.ref<i32>
+  %13 = arith.addi %c1, %c1_1 : index
+  %14 = hlfir.designate %11#0 (%c1)  : (!fir.heap<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+  hlfir.assign %12 to %14 : i32, !fir.ref<i32>
+  %15 = fir.load %6#0 : !fir.ref<i32>
+  %16 = arith.addi %13, %c1_1 : index
+  %17 = hlfir.designate %11#0 (%13)  : (!fir.heap<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+  hlfir.assign %15 to %17 : i32, !fir.ref<i32>
+  %18 = fir.load %8#0 : !fir.ref<i32>
+  %19 = hlfir.designate %11#0 (%16)  : (!fir.heap<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+  hlfir.assign %18 to %19 : i32, !fir.ref<i32>
+  %true = arith.constant true
+  %20 = hlfir.as_expr %11#0 move %true {test.ptr = "tmp_array"}: (!fir.heap<!fir.array<3xi32>>, i1) -> !hlfir.expr<3xi32>
+  hlfir.assign %20 to %4#0 : !hlfir.expr<3xi32>, !fir.ref<!fir.array<3xi32>>
+  hlfir.destroy %20 : !hlfir.expr<3xi32>
+  return
+}

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for this!

@DominikAdamski DominikAdamski merged commit 102f76b into llvm:main Oct 14, 2024
11 checks passed
@jeanPerier
Copy link
Contributor

Something is weird here, AsExpr produces a value as far as SSA is concerned (hlfir.expr), so it does not make sense to call mayAlias on it to start with. So while I understand the goal, it does not feel right. The fix was probably in the OptimizedBufferization pass.

@DominikAdamski
Copy link
Contributor Author

Hi @jeanPerier ,
OptimizedBufferization pass requires output of alias analysis to modify the MLIR code: https://github.com/llvm/llvm-project/blob/main/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp#L634 . Without my change OptimizedBufferization pass cannot perform any changes.

DanielCChen pushed a commit to DanielCChen/llvm-project that referenced this pull request Oct 16, 2024
This patch extends the alias analysis for temporary arrays in Flang.
With this extension, Flang can now determine that the temporary array
[a, b, c] does not alias with arrayD in Fortran code:
```
  integer :: a, b, c
  integer :: arrayD(3)
  arrayD = [ a, b, c ]
```
bricknerb pushed a commit to bricknerb/llvm-project that referenced this pull request Oct 17, 2024
This patch extends the alias analysis for temporary arrays in Flang.
With this extension, Flang can now determine that the temporary array
[a, b, c] does not alias with arrayD in Fortran code:
```
  integer :: a, b, c
  integer :: arrayD(3)
  arrayD = [ a, b, c ]
```
EricWF pushed a commit to efcs/llvm-project that referenced this pull request Oct 22, 2024
This patch extends the alias analysis for temporary arrays in Flang.
With this extension, Flang can now determine that the temporary array
[a, b, c] does not alias with arrayD in Fortran code:
```
  integer :: a, b, c
  integer :: arrayD(3)
  arrayD = [ a, b, c ]
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants