Skip to content

Commit

Permalink
[flang][hlfir] Do not emit extra declare for dummy used in BLOCK (#69184
Browse files Browse the repository at this point in the history
)

When a variable is used in a specification expression in a scope, it is
added to the list of variables that must be instantiated when lowering
the scope. When lowering a BLOCK, this caused instantiateVar to be
called again on all the host block variables appearing in block variable
specification expressions. This caused an extra declare to be emitted
for dummy inside block (for non dummy, instantiateVar is a no-op if the
symbol is already mapped).

Only call instantiateVar if the symbol is not mapped when lowering BLOCK
variables.
  • Loading branch information
jeanPerier committed Oct 17, 2023
1 parent 77ab08e commit bfcd053
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
8 changes: 6 additions & 2 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2610,8 +2610,12 @@ class FirConverter : public Fortran::lower::AbstractConverter {
scopeBlockIdMap.try_emplace(&scope, ++blockId);
Fortran::lower::AggregateStoreMap storeMap;
for (const Fortran::lower::pft::Variable &var :
Fortran::lower::pft::getScopeVariableList(scope))
instantiateVar(var, storeMap);
Fortran::lower::pft::getScopeVariableList(scope)) {
// Do no instantiate again variables from the block host
// that appears in specification of block variables.
if (!var.hasSymbol() || !lookupSymbol(var.getSymbol()))
instantiateVar(var, storeMap);
}
} else if (e.getIf<Fortran::parser::EndBlockStmt>()) {
if (eval.lowerAsUnstructured())
maybeStartBlock(e.block);
Expand Down
25 changes: 25 additions & 0 deletions flang/test/Lower/HLFIR/convert-variable-block.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
! Test that hlfir.declare is not created again for dummy arguments
! used in specifications of BLOCK variables.
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s

subroutine test(n)
integer(8) :: n
call before_block()
block
real :: x(n)
call foo(x)
end block
end subroutine
! CHECK-LABEL: func.func @_QPtest(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i64> {fir.bindc_name = "n"}) {
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtestEn"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
! CHECK: fir.call @_QPbefore_block() {{.*}}: () -> ()
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<i64>
! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i64) -> index
! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_6:.*]] = arith.cmpi sgt, %[[VAL_4]], %[[VAL_5]] : index
! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_6]], %[[VAL_4]], %[[VAL_5]] : index
! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.array<?xf32>, %[[VAL_7]] {bindc_name = "x", uniq_name = "_QFtestB1Ex"}
! CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) {uniq_name = "_QFtestB1Ex"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)
! CHECK: fir.call @_QPfoo(%[[VAL_10]]#1) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()

0 comments on commit bfcd053

Please sign in to comment.