diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2014-05-22 14:32:56 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2014-05-22 14:32:56 +0000 |
commit | 1f9c420b7baf7f11963d3a264b4db96f8a7072c1 (patch) | |
tree | 07d130da7dcd13846521f867398e508b7b88596c /gcc | |
parent | e3f0315f883341299b198872bf1289413e7515e7 (diff) | |
download | gcc-1f9c420b7baf7f11963d3a264b4db96f8a7072c1.zip gcc-1f9c420b7baf7f11963d3a264b4db96f8a7072c1.tar.gz gcc-1f9c420b7baf7f11963d3a264b4db96f8a7072c1.tar.bz2 |
tree-ssa-forwprop.c (associate_plusminus): Extend (T)(P + A) - (T)P -> (T)A transformation to integer types.
* tree-ssa-forwprop.c (associate_plusminus): Extend (T)(P + A) - (T)P
-> (T)A transformation to integer types.
From-SVN: r210807
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/opt37.adb | 42 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/opt37.ads | 18 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 54 |
5 files changed, 95 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d2dbcbd..307df9a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-05-22 Eric Botcazou <ebotcazou@adacore.com> + + * tree-ssa-forwprop.c (associate_plusminus): Extend (T)(P + A) - (T)P + -> (T)A transformation to integer types. + 2014-05-22 Teresa Johnson <tejohnson@google.com> * gcov-io.c (gcov_position): Use gcov_nonruntime_assert. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1b9c60a..4d81463 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-05-22 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/opt37.ad[sb]: New test. + 2014-05-21 Jonathan Wakely <jwakely@redhat.com> PR c/61271 diff --git a/gcc/testsuite/gnat.dg/opt37.adb b/gcc/testsuite/gnat.dg/opt37.adb new file mode 100644 index 0000000..fe37f90 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt37.adb @@ -0,0 +1,42 @@ +-- { dg-compile } +-- { dg-options "-O2 -gnato -fdump-tree-optimized" } + +package body Opt37 is + + function To_Unchecked (Bits : T_Bit_Array) return Unsigned32 is + Value : Unsigned32 := 0; + begin + for I in Bits'Range loop + Value := Value * 2 + Unsigned32 (Bits(I)); + end loop; + return Value; + end; + + function To_Scalar (Bits : T_Bit_Array) return Positive is + Tmp : Unsigned32; + Value : Positive; + begin + Tmp := To_Unchecked (Bits); + if Tmp in 0 .. Unsigned32 (Positive'last) then + Value := Positive (Tmp); + else + Value := -Positive (Unsigned32'last - Tmp); + if Value > Positive'first then + Value := Value - 1; + else + raise Program_Error; + end if; + end if; + return Value; + end; + + function Func (Bit_Array : T_Bit_Array; + Bit_Index : T_Bit_Index) return Positive is + begin + return To_Scalar (Bit_Array (Bit_Index .. Bit_Index + 1)); + end; + +end Opt37; + +-- { dg-final { scan-tree-dump-not "alloca" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/opt37.ads b/gcc/testsuite/gnat.dg/opt37.ads new file mode 100644 index 0000000..7507679 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt37.ads @@ -0,0 +1,18 @@ +package Opt37 is
+
+ type T_Bit is range 0 .. 1;
+ for T_Bit'Size use 1;
+
+ type Positive is range 0 .. (2 ** 31) - 1;
+ type Unsigned32 is mod 2 ** 32;
+
+ subtype T_Bit_Count is Positive;
+ subtype T_Bit_Index is T_Bit_Count range 1 .. T_Bit_Count'Last;
+
+ type T_Bit_Array is array (T_Bit_Count range <>) of T_Bit;
+ pragma Pack (T_Bit_Array);
+
+ function Func (Bit_Array : in T_Bit_Array;
+ Bit_Index : in T_Bit_Index) return Positive;
+
+end Opt37;
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 563abe0..e863567 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2642,49 +2642,47 @@ associate_plusminus (gimple_stmt_iterator *gsi) gimple_set_modified (stmt, true); } } - else if (CONVERT_EXPR_CODE_P (def_code) && code == MINUS_EXPR + else if (code == MINUS_EXPR + && CONVERT_EXPR_CODE_P (def_code) + && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME && TREE_CODE (rhs2) == SSA_NAME) { - /* (T)(ptr + adj) - (T)ptr -> (T)adj. */ + /* (T)(P + A) - (T)P -> (T)A. */ gimple def_stmt2 = SSA_NAME_DEF_STMT (rhs2); - if (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME - && is_gimple_assign (def_stmt2) + if (is_gimple_assign (def_stmt2) && can_propagate_from (def_stmt2) && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2)) && TREE_CODE (gimple_assign_rhs1 (def_stmt2)) == SSA_NAME) { - /* Now we have (T)A - (T)ptr. */ - tree ptr = gimple_assign_rhs1 (def_stmt2); + /* Now we have (T)X - (T)P. */ + tree p = gimple_assign_rhs1 (def_stmt2); def_stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt)); if (is_gimple_assign (def_stmt2) - && gimple_assign_rhs_code (def_stmt2) == POINTER_PLUS_EXPR - && gimple_assign_rhs1 (def_stmt2) == ptr) + && can_propagate_from (def_stmt2) + && (gimple_assign_rhs_code (def_stmt2) == POINTER_PLUS_EXPR + || gimple_assign_rhs_code (def_stmt2) == PLUS_EXPR) + && gimple_assign_rhs1 (def_stmt2) == p) { - /* And finally (T)(ptr + X) - (T)ptr. */ - tree adj = gimple_assign_rhs2 (def_stmt2); - /* If the conversion of the pointer adjustment to the - final type requires a sign- or zero-extension we - have to punt - it is not defined which one is - correct. */ - if (TYPE_PRECISION (TREE_TYPE (rhs1)) - <= TYPE_PRECISION (TREE_TYPE (adj)) - || (TREE_CODE (adj) == INTEGER_CST - && tree_int_cst_sign_bit (adj) == 0)) + /* And finally (T)(P + A) - (T)P. */ + tree a = gimple_assign_rhs2 (def_stmt2); + /* For pointer types, if the conversion of A to the final + type requires a sign- or zero-extension, then we have + to punt - it is not defined which one is correct. */ + if (!POINTER_TYPE_P (TREE_TYPE (rhs1)) + || TYPE_PRECISION (TREE_TYPE (rhs1)) + <= TYPE_PRECISION (TREE_TYPE (a)) + || (TREE_CODE (a) == INTEGER_CST + && tree_int_cst_sign_bit (a) == 0)) { if (useless_type_conversion_p (TREE_TYPE (rhs1), - TREE_TYPE (adj))) - { - code = TREE_CODE (adj); - rhs1 = adj; - } + TREE_TYPE (a))) + code = TREE_CODE (a); else - { - code = NOP_EXPR; - rhs1 = adj; - } + code = NOP_EXPR; + rhs1 = a; rhs2 = NULL_TREE; gimple_assign_set_rhs_with_ops (gsi, code, rhs1, - NULL_TREE); + rhs2); gcc_assert (gsi_stmt (*gsi) == stmt); gimple_set_modified (stmt, true); } |