diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp index 436f7a1154c7c..70fa18ad65b9b 100644 --- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp +++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #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" @@ -62,17 +61,13 @@ getOriginalDef(mlir::Value v, mlir::Type ty = defOp->getResultTypes()[0]; llvm::TypeSwitch(defOp) .Case([&](fir::ConvertOp op) { v = op.getValue(); }) - .Case( - [&](auto op) { - v = op.getMemref(); - auto varIf = - llvm::dyn_cast(defOp); - if (varIf) { - attributes |= getAttrsFromVariable(varIf); - isCapturedInInternalProcedure |= - varIf.isCapturedInInternalProcedure(); - } - }) + .Case([&](auto op) { + v = op.getMemref(); + auto varIf = llvm::cast(defOp); + attributes |= getAttrsFromVariable(varIf); + isCapturedInInternalProcedure |= + varIf.isCapturedInInternalProcedure(); + }) .Case([&](auto op) { if (fir::AliasAnalysis::isPointerReference(ty)) attributes.set(fir::AliasAnalysis::Attribute::Pointer); @@ -596,21 +591,19 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v, followBoxData = true; approximateSource = true; }) - .Case( - [&](auto op) { - if (followBoxData) { - v = op->getOperand(0); - defOp = v.getDefiningOp(); - } else - breakFromLoop = true; - }) + .Case([&](auto op) { + if (followBoxData) { + v = op->getOperand(0); + defOp = v.getDefiningOp(); + } else + breakFromLoop = true; + }) .Case([&](auto op) { // If load is inside target and it points to mapped item, // continue tracking. Operation *loadMemrefOp = op.getMemref().getDefiningOp(); bool isDeclareOp = llvm::isa_and_present(loadMemrefOp) || - llvm::isa_and_present(loadMemrefOp) || llvm::isa_and_present(loadMemrefOp); if (isDeclareOp && llvm::isa(loadMemrefOp->getParentOp())) { @@ -673,8 +666,7 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v, global = llvm::cast(op).getSymbol(); breakFromLoop = true; }) - .Case([&](auto op) { + .Case([&](auto op) { bool isPrivateItem = false; if (omp::BlockArgOpenMPOpInterface argIface = dyn_cast(op->getParentOp())) { @@ -708,33 +700,30 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v, return; } } - auto varIf = llvm::dyn_cast(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; - } + auto varIf = llvm::cast(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; } if (getLastInstantiationPoint) { // Fetch only the innermost instantiation point. diff --git a/flang/lib/Optimizer/Analysis/CMakeLists.txt b/flang/lib/Optimizer/Analysis/CMakeLists.txt index 3249f8a76ae3e..4d4ad882c27d3 100644 --- a/flang/lib/Optimizer/Analysis/CMakeLists.txt +++ b/flang/lib/Optimizer/Analysis/CMakeLists.txt @@ -6,14 +6,12 @@ add_flang_library(FIRAnalysis FIRDialect FIRSupport HLFIRDialect - FIRCodeGen LINK_LIBS FIRBuilder FIRDialect FIRSupport HLFIRDialect - FIRCodeGen MLIR_DEPS MLIRIR diff --git a/flang/test/Analysis/AliasAnalysis/fircg-as-sources.fir b/flang/test/Analysis/AliasAnalysis/fircg-as-sources.fir deleted file mode 100644 index edb3b1dadb8cd..0000000000000 --- a/flang/test/Analysis/AliasAnalysis/fircg-as-sources.fir +++ /dev/null @@ -1,108 +0,0 @@ -// Check aliasing with the address *in* (not *of*) a local (fir.alloca) pointer -// variable. -// -// Throughout this test, the ".fir" suffix on symbols indicates a version of the -// MLIR after convert-hlfir-to-fir. We would like alias analysis results to be -// the same in both versions. - -// RUN: fir-opt %s -split-input-file -o /dev/null --mlir-disable-threading \ -// RUN: -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' \ -// RUN: 2>&1 | FileCheck -match-full-lines %s - -// subroutine test(p1, arr, t_arr, alloc, t_alloc, t, v) -// real, pointer :: p1 -// real :: arr(:) -// real, target :: t_arr(:) -// real, allocatable :: alloc -// real, allocatable, target :: t_alloc -// real, target :: t -// real :: v -// real, pointer :: p0 -// end subroutine test - -// check when fircg.ext_rebox and fircg.ext_declare are in the path of tracing the source -// CHECK-LABEL: Testing : "_QPtest.fir" -// CHECK-DAG: p0.tgt.fir#0 <-> arr(1).fir#0: NoAlias -// CHECK-DAG: p0.tgt.fir#0 <-> t_arr(1).fir#0: MayAlias -// CHECK-DAG: p0.tgt.fir#0 <-> alloc.tgt.fir#0: NoAlias -// CHECK-DAG: p0.tgt.fir#0 <-> t_alloc.tgt.fir#0: MayAlias -// CHECK-DAG: alloc.fir#0 <-> alloc.tgt.fir#0: NoAlias - -func.func @_QPtest.fir(%arg0: !fir.ref>> {fir.bindc_name = "p1"}, %arg1: !fir.box> {fir.bindc_name = "arr"}, %arg2: !fir.box> {fir.bindc_name = "t_arr", fir.target}, %arg3: !fir.ref>> {fir.bindc_name = "alloc"}, %arg4: !fir.ref>> {fir.bindc_name = "t_alloc", fir.target}, %arg5: !fir.ref {fir.bindc_name = "t", fir.target}, %arg6: !fir.ref {fir.bindc_name = "v"}) { - %0 = fir.dummy_scope : !fir.dscope - %1 = fircg.ext_declare %arg3 dummy_scope %0 {test.ptr = "alloc.fir", fortran_attrs = #fir.var_attrs, uniq_name = "_QFtestEalloc"} : (!fir.ref>>, !fir.dscope) -> !fir.ref>> - %2 = fir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEarr"} : (!fir.box>, !fir.dscope) -> !fir.box> - %3 = fircg.ext_rebox %2 : (!fir.box>) -> !fir.box> - %4 = fir.alloca !fir.box> {bindc_name = "p0", uniq_name = "_QFtestEp0"} - %5 = fircg.ext_declare %4 {test.ptr = "p0.fir", fortran_attrs = #fir.var_attrs, uniq_name = "_QFtestEp0"} : (!fir.ref>>) -> !fir.ref>> - %6 = fir.declare %arg0 dummy_scope %0 {test.ptr = "p1.fir", fortran_attrs = #fir.var_attrs, uniq_name = "_QFtestEp1"} : (!fir.ref>>, !fir.dscope) -> !fir.ref>> - %7 = fir.declare %arg5 dummy_scope %0 {test.ptr = "t.fir", fortran_attrs = #fir.var_attrs, uniq_name = "_QFtestEt"} : (!fir.ref, !fir.dscope) -> !fir.ref - %8 = fir.declare %arg4 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtestEt_alloc"} : (!fir.ref>>, !fir.dscope) -> !fir.ref>> - %9 = fir.declare %arg2 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtestEt_arr"} : (!fir.box>, !fir.dscope) -> !fir.box> - %10 = fircg.ext_rebox %9 : (!fir.box>) -> !fir.box> - %11 = fir.declare %arg6 dummy_scope %0 {test.ptr = "v.fir", uniq_name = "_QFtestEv"} : (!fir.ref, !fir.dscope) -> !fir.ref - %12 = fir.load %5 : !fir.ref>> - %13 = fir.box_addr %12 {test.ptr = "p0.tgt.fir"} : (!fir.box>) -> !fir.ptr - %14 = fir.load %6 : !fir.ref>> - %15 = fir.box_addr %14 {test.ptr = "p1.tgt.fir"} : (!fir.box>) -> !fir.ptr - %c1 = arith.constant 1 : index - %16 = fir.array_coor %3 %c1 {test.ptr="arr(1).fir"} : (!fir.box>, index) -> !fir.ref - %c1_0 = arith.constant 1 : index - %17 = fir.array_coor %10 %c1_0 {test.ptr="t_arr(1).fir"} : (!fir.box>, index) -> !fir.ref - %18 = fir.load %1 : !fir.ref>> - %19 = fir.box_addr %18 {test.ptr = "alloc.tgt.fir"} : (!fir.box>) -> !fir.heap - %20 = fir.load %8 : !fir.ref>> - %21 = fir.box_addr %20 {test.ptr = "t_alloc.tgt.fir"} : (!fir.box>) -> !fir.heap - return -} - -// ----- -// CHECK-LABEL: Testing : "_QFPtest3" - -// module pointers -// real, pointer :: p -// end module -// -// program main -// use pointers -// real, target :: var1 = 1, var2 =2 -// p => var1 -// -// call test3(p) -// -// contains -// subroutine test3(p1) -// real, pointer :: p1 -// p1 => var2 -// print *, p -// end subroutine -// end - -// check when there are fircg.ext_embox in the paths -// CHECK-DAG: p#0 <-> box.addr#0: NoAlias -// CHECK-DAG: box.addr#0 <-> func.region0#0: NoAlias -// CHECK-DAG: var2#0 <-> p#0: NoAlias -// CHECK-DAG: var2#0 <-> box.addr#0: MustAlias -// CHECK-DAG: var2#0 <-> func.region0#1: NoAlias -// CHECK-DAG: box.addr#0 <-> func.region0#1: NoAlias - -fir.global @_QMpointersEp : !fir.box> { - %0 = fir.zero_bits !fir.ptr - %1 = fircg.ext_embox %0 : (!fir.ptr) -> !fir.box> - fir.has_value %1 : !fir.box> -} - -fir.global internal @_QFEvar2 target : f32 { - %cst = arith.constant 2.000000e+00 : f32 - fir.has_value %cst : f32 -} - -func.func @_QFPtest3(%arg0: !fir.ref>> {fir.bindc_name = "p1"}, %arg1: !fir.ref) attributes {test.ptr = "func"} { - %3 = fir.load %arg0 {test.ptr = "arg0.load"}: !fir.ref>> - %4 = fir.address_of(@_QFEvar2) {test.ptr = "var2"} : !fir.ref - %5 = fir.address_of(@_QMpointersEp) {test.ptr = "p"} : !fir.ref>> - %6 = fircg.ext_embox %4 : (!fir.ref) -> !fir.box> - %13 = fir.box_addr %6 {test.ptr = "box.addr"} : (!fir.box>) -> !fir.ptr - return -} -