diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-11-09 09:50:02 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-11-09 09:50:02 +0000 |
commit | 82d3b03a3baf4681f3d4139fbc37c7e6cc92847f (patch) | |
tree | 702b82345e4f0709fa08788c1592629bc7f831e2 /gcc/ada/gcc-interface | |
parent | 52013b9baae8e58e75461d3ded8f806a4734c82f (diff) | |
download | gcc-82d3b03a3baf4681f3d4139fbc37c7e6cc92847f.zip gcc-82d3b03a3baf4681f3d4139fbc37c7e6cc92847f.tar.gz gcc-82d3b03a3baf4681f3d4139fbc37c7e6cc92847f.tar.bz2 |
ada-tree.def (PLUS_NOMOD_EXPR): New tree code.
* gcc-interface/ada-tree.def (PLUS_NOMOD_EXPR): New tree code.
(MINUS_NOMOD_EXPR): Likewise.
* gcc-interface/utils2.c (build_binary_op) <PREINCREMENT_EXPR>: Make
unreachable.
<PLUS_NOMOD_EXPR>: New case.
<MINUS_NOMOD_EXPR>: Likewise.
* gcc-interface/trans.c (Loop_Statement_to_gnu): Build increment-and-
assignment statement instead of using an increment operator.
From-SVN: r141714
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/ada-tree.def | 8 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 38 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.c | 30 |
3 files changed, 49 insertions, 27 deletions
diff --git a/gcc/ada/gcc-interface/ada-tree.def b/gcc/ada/gcc-interface/ada-tree.def index 0a1949f..c046229 100644 --- a/gcc/ada/gcc-interface/ada-tree.def +++ b/gcc/ada/gcc-interface/ada-tree.def @@ -41,6 +41,14 @@ DEFTREECODE (UNCONSTRAINED_ARRAY_REF, "unconstrained_array_ref", is an expression to be evaluated for side effects only. */ DEFTREECODE (NULL_EXPR, "null_expr", tcc_expression, 1) +/* Same as PLUS_EXPR, except that no modulo reduction is applied. + This is used for loops and never shows up in the tree. */ +DEFTREECODE (PLUS_NOMOD_EXPR, "plus_nomod_expr", tcc_binary, 2) + +/* Same as MINUS_EXPR, except that no modulo reduction is applied. + This is used for loops and never shows up in the tree. */ +DEFTREECODE (MINUS_NOMOD_EXPR, "minus_nomod_expr", tcc_binary, 2) + /* Same as ADDR_EXPR, except that if the operand represents a bit field, return the address of the byte containing the bit. This is used for the 'Address attribute and never shows up in the tree. */ diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 4324c92..8ededaa 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -1714,13 +1714,28 @@ Loop_Statement_to_gnu (Node_Id gnat_node) tree gnu_type = get_unpadded_type (gnat_type); tree gnu_low = TYPE_MIN_VALUE (gnu_type); tree gnu_high = TYPE_MAX_VALUE (gnu_type); - bool reversep = Reverse_Present (gnat_loop_spec); - tree gnu_first = reversep ? gnu_high : gnu_low; - tree gnu_last = reversep ? gnu_low : gnu_high; - enum tree_code end_code = reversep ? GE_EXPR : LE_EXPR; + tree gnu_first, gnu_last, gnu_limit; + enum tree_code update_code, end_code; tree gnu_base_type = get_base_type (gnu_type); - tree gnu_limit = (reversep ? TYPE_MIN_VALUE (gnu_base_type) - : TYPE_MAX_VALUE (gnu_base_type)); + + /* We must disable modulo reduction for the loop variable, if any, + in order for the loop comparison to be effective. */ + if (Reverse_Present (gnat_loop_spec)) + { + gnu_first = gnu_high; + gnu_last = gnu_low; + update_code = MINUS_NOMOD_EXPR; + end_code = GE_EXPR; + gnu_limit = TYPE_MIN_VALUE (gnu_base_type); + } + else + { + gnu_first = gnu_low; + gnu_last = gnu_high; + update_code = PLUS_NOMOD_EXPR; + end_code = LE_EXPR; + gnu_limit = TYPE_MAX_VALUE (gnu_base_type); + } /* We know the loop variable will not overflow if GNU_LAST is a constant and is not equal to GNU_LIMIT. If it might overflow, we have to move @@ -1764,12 +1779,13 @@ Loop_Statement_to_gnu (Node_Id gnat_node) gnu_loop_var, gnu_last); LOOP_STMT_UPDATE (gnu_loop_stmt) - = build_binary_op (reversep ? PREDECREMENT_EXPR - : PREINCREMENT_EXPR, - TREE_TYPE (gnu_loop_var), + = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_loop_var, - convert (TREE_TYPE (gnu_loop_var), - integer_one_node)); + build_binary_op (update_code, + TREE_TYPE (gnu_loop_var), + gnu_loop_var, + convert (TREE_TYPE (gnu_loop_var), + integer_one_node))); set_expr_location_from_node (LOOP_STMT_UPDATE (gnu_loop_stmt), gnat_iter_scheme); } diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index 5077e64..77a0389 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -943,21 +943,8 @@ build_binary_op (enum tree_code op_code, tree result_type, case PREDECREMENT_EXPR: case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: - /* In these, the result type and the left operand type should be the - same. Do the operation in the base type of those and convert the - right operand (which is an integer) to that type. - - Note that these operations are only used in loop control where - we guarantee that no overflow can occur. So nothing special need - be done for modular types. */ - - gcc_assert (left_type == result_type); - operation_type = get_base_type (result_type); - left_operand = convert (operation_type, left_operand); - right_operand = convert (operation_type, right_operand); - has_side_effects = true; - modulus = NULL_TREE; - break; + /* These operations are not used anymore. */ + gcc_unreachable (); case LSHIFT_EXPR: case RSHIFT_EXPR: @@ -1011,6 +998,16 @@ build_binary_op (enum tree_code op_code, tree result_type, right_operand = convert (sizetype, right_operand); break; + case PLUS_NOMOD_EXPR: + case MINUS_NOMOD_EXPR: + if (op_code == PLUS_NOMOD_EXPR) + op_code = PLUS_EXPR; + else + op_code = MINUS_EXPR; + modulus = NULL_TREE; + + /* ... fall through ... */ + case PLUS_EXPR: case MINUS_EXPR: /* Avoid doing arithmetics in BOOLEAN_TYPE like the other compilers. @@ -1018,7 +1015,8 @@ build_binary_op (enum tree_code op_code, tree result_type, but we can generate addition or subtraction for 'Succ and 'Pred. */ if (operation_type && TREE_CODE (operation_type) == BOOLEAN_TYPE) operation_type = left_base_type = right_base_type = integer_type_node; - goto common; + + /* ... fall through ... */ default: common: |