Skip to content

Commit

Permalink
#1960 change loop bounds to use U/LBOUND
Browse files Browse the repository at this point in the history
  • Loading branch information
arporter committed Jan 18, 2024
1 parent 5e5a241 commit 138b6be
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
32 changes: 21 additions & 11 deletions src/psyclone/psyir/frontend/fparser2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3825,13 +3825,6 @@ def _contains_intrinsic_reduction(pnodes):
annotations=annotations)
# Point to the original WHERE statement in the parse tree.
loop.ast = node
# Add loop lower bound
loop.addchild(Literal("1", integer_type))
# Add loop upper bound - we use the SIZE operator to query the
# extent of the current array dimension
size_node = IntrinsicCall(IntrinsicCall.Intrinsic.SIZE,
parent=loop)
loop.addchild(size_node)

# Create the first argument to the SIZE operator
if isinstance(first_array, Member):
Expand All @@ -3848,12 +3841,29 @@ def _contains_intrinsic_reduction(pnodes):
else:
# The array access is to a symbol of ArrayType
symbol = _find_or_create_unresolved_symbol(
size_node, first_array.name, symbol_type=DataSymbol,
loop, first_array.name, symbol_type=DataSymbol,
datatype=DeferredType())
new_ref = Reference(symbol)
size_node.addchild(new_ref)
size_node.addchild(Literal(str(idx), integer_type,
parent=size_node))

# Add loop lower bound
#loop.addchild(Literal("1", integer_type))
loop.addchild(
IntrinsicCall.create(IntrinsicCall.Intrinsic.LBOUND,
[new_ref,
Literal(str(idx), integer_type)]))
# Add loop upper bound - we use the SIZE operator to query the
# extent of the current array dimension
#size_node = IntrinsicCall(IntrinsicCall.Intrinsic.SIZE,
# parent=loop)
#loop.addchild(size_node)
loop.addchild(
IntrinsicCall.create(IntrinsicCall.Intrinsic.UBOUND,
[new_ref.copy(),
Literal(str(idx), integer_type)]))

#size_node.addchild(new_ref)
#size_node.addchild(Literal(str(idx), integer_type,
# parent=size_node))
# Add loop increment
loop.addchild(Literal("1", integer_type))
# Fourth child of a Loop must be a Schedule
Expand Down
8 changes: 4 additions & 4 deletions src/psyclone/psyir/nodes/intrinsic_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,10 @@ class Intrinsic(IAttr, Enum):
ArgDesc(1, 1, (DataNode)), {})
LBOUND = IAttr(
'LBOUND', True, False, True,
ArgDesc(1, 1, (DataNode)), {"dim": DataNode, "kind": DataNode})
ArgDesc(1, 3, (DataNode)), {"dim": DataNode, "kind": DataNode})
LCOBOUND = IAttr(
'LCOBOUND', True, False, True,
ArgDesc(1, 1, (DataNode)), {"dim": DataNode, "kind": DataNode})
ArgDesc(1, 3, (DataNode)), {"dim": DataNode, "kind": DataNode})
LEADZ = IAttr(
'LEADZ', True, True, False,
ArgDesc(1, 1, (DataNode)), {})
Expand Down Expand Up @@ -727,10 +727,10 @@ class Intrinsic(IAttr, Enum):
ArgDesc(1, 1, DataNode), {})
UBOUND = IAttr(
'UBOUND', True, False, True,
ArgDesc(1, 1, DataNode), {"dim": DataNode, "kind": DataNode})
ArgDesc(1, 3, DataNode), {"dim": DataNode, "kind": DataNode})
UCOBOUND = IAttr(
'UCOBOUND', True, False, True,
ArgDesc(1, 1, DataNode), {"dim": DataNode, "kind": DataNode})
ArgDesc(1, 3, DataNode), {"dim": DataNode, "kind": DataNode})
UNPACK = IAttr(
'UNPACK', True, False, False,
ArgDesc(3, 3, DataNode), {})
Expand Down
14 changes: 11 additions & 3 deletions src/psyclone/tests/psyir/frontend/fparser2_where_handler_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,14 @@ def test_where_within_loop(fortran_reader):
assign = where_loop.loop_body[0].if_body[0]
assert isinstance(assign, Assignment)
assert [idx.name for idx in assign.lhs.indices] == ["widx1", "jl"]
assert isinstance(where_loop.start_expr, IntrinsicCall)
assert where_loop.start_expr.intrinsic == IntrinsicCall.Intrinsic.LBOUND
assert where_loop.start_expr.children[0].symbol.name == "var"
assert where_loop.start_expr.children[1].value == "1"
assert isinstance(where_loop.stop_expr, IntrinsicCall)
assert where_loop.stop_expr.intrinsic == IntrinsicCall.Intrinsic.UBOUND
assert where_loop.stop_expr.children[0].symbol.name == "var"
assert where_loop.stop_expr.children[1].value == "1"


@pytest.mark.usefixtures("parser")
Expand All @@ -347,9 +355,9 @@ def test_basic_where():
assert "was_where" in loop.annotations
assert isinstance(loop.ast, Fortran2003.Where_Construct)

assert isinstance(loops[0].children[0], Literal)
assert isinstance(loops[0].children[0], IntrinsicCall)
assert isinstance(loops[0].children[1], IntrinsicCall)
assert loops[0].children[1].intrinsic == IntrinsicCall.Intrinsic.SIZE
assert loops[0].children[1].intrinsic == IntrinsicCall.Intrinsic.UBOUND
assert str(loops[0].children[1].children[0]) == "Reference[name:'dry']"

ifblock = loops[2].loop_body[0]
Expand Down Expand Up @@ -692,7 +700,7 @@ def test_where_derived_type(fortran_reader, fortran_writer, code, size_arg):
loops = psyir.walk(Loop)
assert len(loops) == 2
assert isinstance(loops[1].stop_expr, IntrinsicCall)
assert loops[1].stop_expr.intrinsic == IntrinsicCall.Intrinsic.SIZE
assert loops[1].stop_expr.intrinsic == IntrinsicCall.Intrinsic.UBOUND
assert isinstance(loops[1].stop_expr.children[0], StructureReference)
assert fortran_writer(loops[1].stop_expr.children[0]) == size_arg
assert isinstance(loops[1].loop_body[0], IfBlock)
Expand Down

0 comments on commit 138b6be

Please sign in to comment.