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

Array shadowing bugfix for inliner #202

Merged
merged 6 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions loki/transform/transform_inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
from loki.logging import warning, error
from loki.pragma_utils import pragmas_attached, is_loki_pragma

from loki.transform.transform_utilities import single_variable_declaration

from loki.transform.transform_utilities import (
single_variable_declaration,
recursive_expression_map_update
)

__all__ = [
'inline_constant_parameters', 'inline_elemental_functions',
Expand Down Expand Up @@ -208,9 +210,6 @@ def map_call_to_procedure_body(call, caller):
Procedure (scope) into which the callee's body gets mapped
"""

# pylint: disable=import-outside-toplevel,cyclic-import
from loki.transform import recursive_expression_map_update

def _map_unbound_dims(var, val):
"""
Maps all unbound dimension ranges in the passed array value
Expand Down Expand Up @@ -339,6 +338,7 @@ def inline_subroutine_calls(routine, calls, callee, allowed_aliases=None):
for v in FindVariables(unique=False).visit(callee.body):
if v.name.lower() in duplicate_names:
var_map[v] = v.clone(name=f'{callee.name}_{v.name}')
var_map = recursive_expression_map_update(var_map)
callee.body = SubstituteExpressions(var_map).visit(callee.body)

# Separate allowed aliases from other variables to ensure clean hoisting
Expand Down
35 changes: 35 additions & 0 deletions tests/test_transform_inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,41 @@ def test_inline_internal_routines_aliasing_declaration(frontend):
assert assigns[3].lhs == 'jg' and assigns[3].rhs == '2'
assert assigns[4].lhs == 'z' and assigns[4].rhs == 'jlon + jg'

@pytest.mark.parametrize('frontend', available_frontends())
def test_inline_member_routines_indexing_of_shadowed_array(frontend):
"""
Test special case of inlining of member subroutines when inlined routine contains
shadowed array and array indices.
In particular, this test checks that also the variables indexing
the array in the inlined result get renamed correctly.
"""
fcode = """
subroutine outer(klon)
integer :: jg, jlon
integer :: arr(3, 3)

jg = 70000
call inner2()

contains

subroutine inner2()
integer :: jlon, jg
integer :: arr(3, 3)
do jg=1,3
do jlon=1,3
arr(jlon, jg) = 11
end do
end do
end subroutine inner2

end subroutine outer
"""
routine = Subroutine.from_source(fcode, frontend=frontend)
inline_member_procedures(routine)
innerloop = FindNodes(Loop).visit(routine.body)[1]
innerloopvars = FindVariables().visit(innerloop)
assert 'inner2_arr(inner2_jlon,inner2_jg)' in innerloopvars

@pytest.mark.parametrize('frontend', available_frontends())
def test_inline_member_routines_sequence_assoc(frontend):
Expand Down
Loading