From 21f3b874243ab518956b94177ec22fc7d24162e8 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Tue, 30 Jan 2024 23:04:59 +0000 Subject: [PATCH] #1960 tidying for review and simplifying tenerated expressions where poss. [skip ci] --- src/psyclone/psyir/frontend/fparser2.py | 20 +++++++++++++------ src/psyclone/psyir/nodes/array_mixin.py | 19 +++++++++++++++--- .../frontend/fparser2_where_handler_test.py | 16 +++++++-------- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/psyclone/psyir/frontend/fparser2.py b/src/psyclone/psyir/frontend/fparser2.py index b4fe0322e2..7428d78ca9 100644 --- a/src/psyclone/psyir/frontend/fparser2.py +++ b/src/psyclone/psyir/frontend/fparser2.py @@ -3673,11 +3673,19 @@ def _array_syntax_to_indexed(self, parent, loop_vars): ("dim", Literal(str(idx+1), INTEGER_TYPE))]) else: lbound = shape[range_idx].lower.copy() - # Create the index expression: - # idx-expr = array-lower-bound + loop-idx - 1 - expr = BinaryOperation.create( - add_op, lbound, Reference(symbol)) - expr2 = BinaryOperation.create(sub_op, expr, one.copy()) + # Create the index expression. + if isinstance(lbound, Literal) and lbound.value == "1": + # Lower bound is just unity so we can use the loop-idx + # directly. + expr2 = Reference(symbol) + else: + # We don't know what the lower bound is so have to + # have an expression: + # idx-expr = array-lower-bound + loop-idx - 1 + expr = BinaryOperation.create( + add_op, lbound, Reference(symbol)) + expr2 = BinaryOperation.create(sub_op, expr, + one.copy()) array.children[idx] = expr2 range_idx += 1 @@ -3850,7 +3858,7 @@ def _contains_intrinsic_reduction(pnodes): # Point to the original WHERE statement in the parse tree. loop.ast = node - # This loop is over the shape of the mask and thus starts + # This loop is over the *shape* of the mask and thus starts # at unity. Each individual array access is then adjusted # according to the lower bound of that array. loop.addchild(Literal("1", integer_type)) diff --git a/src/psyclone/psyir/nodes/array_mixin.py b/src/psyclone/psyir/nodes/array_mixin.py index eaec20b55b..864941e9ea 100644 --- a/src/psyclone/psyir/nodes/array_mixin.py +++ b/src/psyclone/psyir/nodes/array_mixin.py @@ -546,10 +546,23 @@ def _num_elements(expr): start = expr.lower stop = expr.upper step = Literal("1", INTEGER_TYPE) - minus = BinaryOperation.create(BinaryOperation.Operator.SUB, - stop.copy(), start.copy()) + if (isinstance(start, IntrinsicCall) and + start.intrinsic == IntrinsicCall.Intrinsic.LBOUND and + isinstance(stop, IntrinsicCall) and + stop.intrinsic == IntrinsicCall.Intrinsic.UBOUND and + isinstance(start.children[0], Reference) and + isinstance(stop.children[0], Reference) and + start.children[0].symbol is stop.children[0].symbol and + start.children[1] == stop.children[1]): + extent = IntrinsicCall.create( + IntrinsicCall.Intrinsic.SIZE, + [stop.children[0].copy(), + ("dim", stop.children[1].copy())]) + else: + extent = BinaryOperation.create(BinaryOperation.Operator.SUB, + stop.copy(), start.copy()) div = BinaryOperation.create(BinaryOperation.Operator.DIV, - minus, step.copy()) + extent, step.copy()) plus = BinaryOperation.create(BinaryOperation.Operator.ADD, div, Literal("1", INTEGER_TYPE)) return plus diff --git a/src/psyclone/tests/psyir/frontend/fparser2_where_handler_test.py b/src/psyclone/tests/psyir/frontend/fparser2_where_handler_test.py index 5a73ec4cf9..a6d6814e25 100644 --- a/src/psyclone/tests/psyir/frontend/fparser2_where_handler_test.py +++ b/src/psyclone/tests/psyir/frontend/fparser2_where_handler_test.py @@ -327,7 +327,7 @@ def test_where_within_loop(fortran_reader): assert isinstance(where_loop.loop_body[0], IfBlock) assign = where_loop.loop_body[0].if_body[0] assert isinstance(assign, Assignment) - assert assign.lhs.indices[0].debug_string() == "1 + widx1 - 1" + assert assign.lhs.indices[0].debug_string() == "widx1" assert assign.lhs.indices[1].debug_string() == "jl" assert where_loop.start_expr.value == "1" assert (where_loop.stop_expr.debug_string() == @@ -359,7 +359,7 @@ def test_basic_where(): assert isinstance(ifblock, IfBlock) assert "was_where" in ifblock.annotations assert (ifblock.condition.debug_string() == - "dry(1 + widx1 - 1,1 + widx2 - 1,1 + widx3 - 1)") + "dry(widx1,widx2,widx3)") @pytest.mark.usefixtures("parser") @@ -384,9 +384,9 @@ def test_where_array_subsections(): # Check that the array reference is indexed correctly assign = ifblock.if_body[0] assert isinstance(assign, Assignment) - assert isinstance(assign.lhs.children[0], BinaryOperation) - assert assign.lhs.children[0].debug_string() == "1 + widx1 - 1" - assert assign.lhs.children[2].debug_string() == "1 + widx2 - 1" + assert isinstance(assign.lhs.children[0], Reference) + assert assign.lhs.children[0].debug_string() == "widx1" + assert assign.lhs.children[2].debug_string() == "widx2" def test_where_body_containing_sum_with_dim(fortran_reader, fortran_writer): @@ -539,7 +539,7 @@ def test_elsewhere(): assert isinstance(ifblock.condition, BinaryOperation) assert ifblock.condition.operator == BinaryOperation.Operator.GT assert (ifblock.condition.debug_string() == - "ptsu(1 + widx1 - 1,1 + widx2 - 1,1 + widx3 - 1) > 10._wp") + "ptsu(widx1,widx2,widx3) > 10._wp") # Check that this IF block has an else body which contains another IF assert ifblock.else_body is not None ifblock2 = ifblock.else_body[0] @@ -548,7 +548,7 @@ def test_elsewhere(): assert isinstance(ifblock2.condition, BinaryOperation) assert ifblock2.condition.operator == BinaryOperation.Operator.LT assert (ifblock2.condition.debug_string() == - "ptsu(1 + widx1 - 1,1 + widx2 - 1,1 + widx3 - 1) < 0.0_wp") + "ptsu(widx1,widx2,widx3) < 0.0_wp") # Check that this IF block too has an else body assert isinstance(ifblock2.else_body[0], Assignment) # Check that we have three assignments of the correct form and with the @@ -560,7 +560,7 @@ def test_elsewhere(): refs = assign.lhs.walk(Reference) assert len(refs) == 4 assert (assign.lhs.debug_string() == - "z1_st(1 + widx1 - 1,1 + widx2 - 1,1 + widx3 - 1)") + "z1_st(widx1,widx2,widx3)") assert isinstance(assign.parent.parent, IfBlock) assert isinstance(assigns[0].rhs, BinaryOperation)