Re: [patch] Enhance conditional store sinking
On Thu, Mar 24, 2011 at 11:03 AM, H.J. Lu hjl.to...@gmail.com wrote: On Tue, Mar 22, 2011 at 6:28 AM, Ira Rosen ira.ro...@linaro.org wrote: On 17 March 2011 16:48, Richard Guenther richard.guent...@gmail.com wrote: + then_datarefs = VEC_alloc (data_reference_p, heap, 1); + else_datarefs = VEC_alloc (data_reference_p, heap, 1); + then_ddrs = VEC_alloc (ddr_p, heap, 1); + else_ddrs = VEC_alloc (ddr_p, heap, 1); + if (!compute_data_dependences_for_bb (then_bb, false, then_datarefs, + then_ddrs) Can we avoid computing dependencies if the other BB would have no data-refs? Thus, split collecting datarefs and computing dependences? Done. + || !compute_data_dependences_for_bb (else_bb, false, else_datarefs, + else_ddrs) + || !VEC_length (data_reference_p, then_datarefs) + || !VEC_length (data_reference_p, else_datarefs)) + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + + /* Check that there are no read-after-write or write-after-write dependencies + in THEN_BB. */ + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + ((DR_IS_READ (dra) DR_IS_WRITE (drb) + gimple_uid (DR_STMT (dra)) gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) DR_IS_WRITE (dra) + gimple_uid (DR_STMT (drb)) gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) DR_IS_WRITE (drb The gimple_uids are not initialized here, you need to make sure to call renumber_gimple_stmt_uids () before starting. Note that phiopt incrementally changes the IL, so I'm not sure those uids will stay valid as stmts are moved across blocks. I added a call to renumber_gimple_stmt_uids_in_blocks() before data dependence checks, and there are no code changes between that and the checks, so, I think, it should be OK. + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Check that there are no read-after-write or write-after-write dependencies + in ELSE_BB. */ + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + ((DR_IS_READ (dra) DR_IS_WRITE (drb) + gimple_uid (DR_STMT (dra)) gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) DR_IS_WRITE (dra) + gimple_uid (DR_STMT (drb)) gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) DR_IS_WRITE (drb + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Found pairs of stores with equal LHS. */ + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) + { + if (DR_IS_READ (then_dr)) + continue; + + then_store = DR_STMT (then_dr); + then_lhs = gimple_assign_lhs (then_store); + found = false; + + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) + { + if (DR_IS_READ (else_dr)) + continue; + + else_store = DR_STMT (else_dr); + else_lhs = gimple_assign_lhs (else_store); + + if (operand_equal_p (then_lhs, else_lhs, 0)) + { + found = true; + break; + } + } + + if (!found) + continue; + + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, + then_store, else_store); So you are executing if-else store replacement for common data reference pairs only. I think it's cheaper to collect those pairs before computing dependences and only if there is at least one pair perform the optimization. OK, I changed the order. You basically perform store sinking, creating a PHI node for each store you sink (that's then probably if-converted by if-conversion later, eventually redundant with -ftree-loop-if-convert-stores?) I am concerned that having no bound on the number of stores sunk will increase register pressure and does not allow scheduling of the stores in an optimal way. Consider two BBs similar to t = a + b; *p = t; t = c + d; *q = t; where the transformation undoes
Re: [patch] Enhance conditional store sinking
On Thu, Mar 24, 2011 at 1:39 PM, Richard Guenther richard.guent...@gmail.com wrote: On Thu, Mar 24, 2011 at 11:03 AM, H.J. Lu hjl.to...@gmail.com wrote: On Tue, Mar 22, 2011 at 6:28 AM, Ira Rosen ira.ro...@linaro.org wrote: On 17 March 2011 16:48, Richard Guenther richard.guent...@gmail.com wrote: + then_datarefs = VEC_alloc (data_reference_p, heap, 1); + else_datarefs = VEC_alloc (data_reference_p, heap, 1); + then_ddrs = VEC_alloc (ddr_p, heap, 1); + else_ddrs = VEC_alloc (ddr_p, heap, 1); + if (!compute_data_dependences_for_bb (then_bb, false, then_datarefs, + then_ddrs) Can we avoid computing dependencies if the other BB would have no data-refs? Thus, split collecting datarefs and computing dependences? Done. + || !compute_data_dependences_for_bb (else_bb, false, else_datarefs, + else_ddrs) + || !VEC_length (data_reference_p, then_datarefs) + || !VEC_length (data_reference_p, else_datarefs)) + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + + /* Check that there are no read-after-write or write-after-write dependencies + in THEN_BB. */ + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + ((DR_IS_READ (dra) DR_IS_WRITE (drb) + gimple_uid (DR_STMT (dra)) gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) DR_IS_WRITE (dra) + gimple_uid (DR_STMT (drb)) gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) DR_IS_WRITE (drb The gimple_uids are not initialized here, you need to make sure to call renumber_gimple_stmt_uids () before starting. Note that phiopt incrementally changes the IL, so I'm not sure those uids will stay valid as stmts are moved across blocks. I added a call to renumber_gimple_stmt_uids_in_blocks() before data dependence checks, and there are no code changes between that and the checks, so, I think, it should be OK. + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Check that there are no read-after-write or write-after-write dependencies + in ELSE_BB. */ + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + ((DR_IS_READ (dra) DR_IS_WRITE (drb) + gimple_uid (DR_STMT (dra)) gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) DR_IS_WRITE (dra) + gimple_uid (DR_STMT (drb)) gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) DR_IS_WRITE (drb + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Found pairs of stores with equal LHS. */ + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) + { + if (DR_IS_READ (then_dr)) + continue; + + then_store = DR_STMT (then_dr); + then_lhs = gimple_assign_lhs (then_store); + found = false; + + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) + { + if (DR_IS_READ (else_dr)) + continue; + + else_store = DR_STMT (else_dr); + else_lhs = gimple_assign_lhs (else_store); + + if (operand_equal_p (then_lhs, else_lhs, 0)) + { + found = true; + break; + } + } + + if (!found) + continue; + + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, + then_store, else_store); So you are executing if-else store replacement for common data reference pairs only. I think it's cheaper to collect those pairs before computing dependences and only if there is at least one pair perform the optimization. OK, I changed the order. You basically perform store sinking, creating a PHI node for each store you sink (that's then probably if-converted by if-conversion later, eventually redundant with -ftree-loop-if-convert-stores?) I am concerned that having no bound on the number of stores sunk will increase register pressure and does not allow scheduling of the stores in an optimal way. Consider two BBs
Re: [patch] Enhance conditional store sinking
On Tue, Mar 22, 2011 at 2:28 PM, Ira Rosen ira.ro...@linaro.org wrote: On 17 March 2011 16:48, Richard Guenther richard.guent...@gmail.com wrote: + then_datarefs = VEC_alloc (data_reference_p, heap, 1); + else_datarefs = VEC_alloc (data_reference_p, heap, 1); + then_ddrs = VEC_alloc (ddr_p, heap, 1); + else_ddrs = VEC_alloc (ddr_p, heap, 1); + if (!compute_data_dependences_for_bb (then_bb, false, then_datarefs, + then_ddrs) Can we avoid computing dependencies if the other BB would have no data-refs? Thus, split collecting datarefs and computing dependences? Done. + || !compute_data_dependences_for_bb (else_bb, false, else_datarefs, + else_ddrs) + || !VEC_length (data_reference_p, then_datarefs) + || !VEC_length (data_reference_p, else_datarefs)) + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + + /* Check that there are no read-after-write or write-after-write dependencies + in THEN_BB. */ + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + ((DR_IS_READ (dra) DR_IS_WRITE (drb) + gimple_uid (DR_STMT (dra)) gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) DR_IS_WRITE (dra) + gimple_uid (DR_STMT (drb)) gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) DR_IS_WRITE (drb The gimple_uids are not initialized here, you need to make sure to call renumber_gimple_stmt_uids () before starting. Note that phiopt incrementally changes the IL, so I'm not sure those uids will stay valid as stmts are moved across blocks. I added a call to renumber_gimple_stmt_uids_in_blocks() before data dependence checks, and there are no code changes between that and the checks, so, I think, it should be OK. + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Check that there are no read-after-write or write-after-write dependencies + in ELSE_BB. */ + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + ((DR_IS_READ (dra) DR_IS_WRITE (drb) + gimple_uid (DR_STMT (dra)) gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) DR_IS_WRITE (dra) + gimple_uid (DR_STMT (drb)) gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) DR_IS_WRITE (drb + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Found pairs of stores with equal LHS. */ + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) + { + if (DR_IS_READ (then_dr)) + continue; + + then_store = DR_STMT (then_dr); + then_lhs = gimple_assign_lhs (then_store); + found = false; + + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) + { + if (DR_IS_READ (else_dr)) + continue; + + else_store = DR_STMT (else_dr); + else_lhs = gimple_assign_lhs (else_store); + + if (operand_equal_p (then_lhs, else_lhs, 0)) + { + found = true; + break; + } + } + + if (!found) + continue; + + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, + then_store, else_store); So you are executing if-else store replacement for common data reference pairs only. I think it's cheaper to collect those pairs before computing dependences and only if there is at least one pair perform the optimization. OK, I changed the order. You basically perform store sinking, creating a PHI node for each store you sink (that's then probably if-converted by if-conversion later, eventually redundant with -ftree-loop-if-convert-stores?) I am concerned that having no bound on the number of stores sunk will increase register pressure and does not allow scheduling of the stores in an optimal way. Consider two BBs similar to t = a + b; *p = t; t = c + d; *q = t; where the transformation undoes a good schedule and makes fixing it impossible if the remaining
Re: [patch] Enhance conditional store sinking
On Wed, Mar 16, 2011 at 12:47 PM, Ira Rosen ira.ro...@linaro.org wrote: On 16 March 2011 12:29, Richard Guenther richard.guent...@gmail.com wrote: On Wed, Mar 16, 2011 at 7:49 AM, Ira Rosen ira.ro...@linaro.org wrote: Hi, This patch adds a support of conditional store sinking for cases with multiple data references in then and else basic blocks. The correctness of the transformation is checked by verifying that there are no read-after-write and write-after-write dependencies. Bootstrapped and tested on powerpc64-suse-linux. OK for trunk? I will look at the patch later, but can you add a testcase that we don't sink if (..) { *a = i; *b = j; } else { *b = j; *a = i; } if *a and *b may alias? Done. Comments inline Thanks, Ira ChangeLog: * tree-data-ref.c (dr_equal_offsets_p1): Moved and renamed from tree-vect-data-refs.c vect_equal_offsets. (dr_equal_offsets_p): New function. * tree-data-ref.h (dr_equal_offsets_p): Declare. * tree-vect-data-refs.c (vect_equal_offsets): Move to tree-data-ref.c. (vect_drs_dependent_in_basic_block): Update calls to vect_equal_offsets. (vect_check_interleaving): Likewise. * tree-ssa-phiopt.c: Include cfgloop.h and tree-data-ref.h. (cond_if_else_store_replacement): Rename to... (cond_if_else_store_replacement_1): ... this. Change arguments and documentation. (cond_if_else_store_replacement): New function. * Makefile.in (tree-ssa-phiopt.o): Adjust dependencies. testsuite/ChangeLog: * gcc.dg/vect/vect-cselim-1.c: New test. * gcc.dg/vect/vect-cselim-2.c: New test. Index: tree-data-ref.c === --- tree-data-ref.c (revision 170712) +++ tree-data-ref.c (working copy) @@ -991,6 +991,48 @@ create_data_ref (loop_p nest, loop_p loop, tree me return dr; } +/* Check if OFFSET1 and OFFSET2 (DR_OFFSETs of some data-refs) are identical + expressions. */ +static bool +dr_equal_offsets_p1 (tree offset1, tree offset2) +{ + bool res; + + STRIP_NOPS (offset1); + STRIP_NOPS (offset2); + + if (offset1 == offset2) + return true; + + if (TREE_CODE (offset1) != TREE_CODE (offset2) + || (!BINARY_CLASS_P (offset1) !UNARY_CLASS_P (offset1))) + return false; + + res = dr_equal_offsets_p1 (TREE_OPERAND (offset1, 0), + TREE_OPERAND (offset2, 0)); + + if (!res || !BINARY_CLASS_P (offset1)) + return res; + + res = dr_equal_offsets_p1 (TREE_OPERAND (offset1, 1), + TREE_OPERAND (offset2, 1)); + + return res; +} + +/* Check if DRA and DRB have equal offsets. */ +bool +dr_equal_offsets_p (struct data_reference *dra, + struct data_reference *drb) +{ + tree offset1, offset2; + + offset1 = DR_OFFSET (dra); + offset2 = DR_OFFSET (drb); + + return dr_equal_offsets_p1 (offset1, offset2); +} + /* Returns true if FNA == FNB. */ static bool Index: tree-data-ref.h === --- tree-data-ref.h (revision 170712) +++ tree-data-ref.h (working copy) @@ -430,6 +430,8 @@ extern void compute_all_dependences (VEC (data_ref extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *); extern bool dr_may_alias_p (const struct data_reference *, const struct data_reference *); +extern bool dr_equal_offsets_p (struct data_reference *, + struct data_reference *); /* Return true when the base objects of data references A and B are Index: tree-vect-data-refs.c === --- tree-vect-data-refs.c (revision 170712) +++ tree-vect-data-refs.c (working copy) @@ -289,39 +289,6 @@ vect_update_interleaving_chain (struct data_refere } } - -/* Function vect_equal_offsets. - - Check if OFFSET1 and OFFSET2 are identical expressions. */ - -static bool -vect_equal_offsets (tree offset1, tree offset2) -{ - bool res; - - STRIP_NOPS (offset1); - STRIP_NOPS (offset2); - - if (offset1 == offset2) - return true; - - if (TREE_CODE (offset1) != TREE_CODE (offset2) - || (!BINARY_CLASS_P (offset1) !UNARY_CLASS_P (offset1))) - return false; - - res = vect_equal_offsets (TREE_OPERAND (offset1, 0), - TREE_OPERAND (offset2, 0)); - - if (!res || !BINARY_CLASS_P (offset1)) - return res; - - res = vect_equal_offsets (TREE_OPERAND (offset1, 1), - TREE_OPERAND (offset2, 1)); - - return res; -} - - /* Check dependence between DRA and DRB for basic block vectorization. If the accesses share same bases and offsets, we can compare their initial constant offsets to decide whether they differ or not. In case of a read- @@ -352,7 +319,7 @@
Re: [patch] Enhance conditional store sinking
On Thu, Mar 17, 2011 at 3:53 PM, Jeff Law l...@redhat.com wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 03/17/11 08:48, Richard Guenther wrote: The gimple_uids are not initialized here, you need to make sure to call renumber_gimple_stmt_uids () before starting. Note that phiopt incrementally changes the IL, so I'm not sure those uids will stay valid as stmts are moved across blocks. BTW, it's probably worth noting that renumber_gimple_stmt_uids doesn't assign UIDs for PHI nodes. Worse yet, someone might have called renumber_gimple_stmt_uids_in_blocks which *does* assign UIDs to PHIs. The net result is you can have a PHI with a UID that conflicts with a statement's UID or a PHI with no UID. It may not matter for this code, but having been recently bitten by this, I thought I'd mention it. Yep ;) It's worth fixing this inconsistency btw. Richard. jeff -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJNgiBoAAoJEBRtltQi2kC7dLMH+QEhaTqTxoqDnOeMFTb0OLLi 31BT3yDcSD0gEkFCZQB5qWo7RBBaepnRMtDpOxmGKcY8VlCvWdRDz6aFLlzDphzC XWD/M4i01Of0tjIlCJqDVsUZklD2dvPOz0pwQpX5fteoGNedNGp5Xwq72Wq5YRKW IcgpsRN/xbFA4HDk8ZfW5dkb+eQQptGHz5zj9KUz0pQbjqGS6e0oFIHCygwVW7u/ zhGuD16OhtNS6Z5gkVs9j1POZOSAb7GawB0p5W0lJigzqRfLPIYLuOjtgZrLdgXQ 3oK6uMX4WwZJK3PBT7Lo8MNTTnxjJZc4iL0SLArtd+U11QnxnsSIqKX9FBtX25A= =d7Vy -END PGP SIGNATURE-
Re: [patch] Enhance conditional store sinking
On 16 March 2011 12:29, Richard Guenther richard.guent...@gmail.com wrote: On Wed, Mar 16, 2011 at 7:49 AM, Ira Rosen ira.ro...@linaro.org wrote: Hi, This patch adds a support of conditional store sinking for cases with multiple data references in then and else basic blocks. The correctness of the transformation is checked by verifying that there are no read-after-write and write-after-write dependencies. Bootstrapped and tested on powerpc64-suse-linux. OK for trunk? I will look at the patch later, but can you add a testcase that we don't sink if (..) { *a = i; *b = j; } else { *b = j; *a = i; } if *a and *b may alias? Done. Thanks, Ira ChangeLog: * tree-data-ref.c (dr_equal_offsets_p1): Moved and renamed from tree-vect-data-refs.c vect_equal_offsets. (dr_equal_offsets_p): New function. * tree-data-ref.h (dr_equal_offsets_p): Declare. * tree-vect-data-refs.c (vect_equal_offsets): Move to tree-data-ref.c. (vect_drs_dependent_in_basic_block): Update calls to vect_equal_offsets. (vect_check_interleaving): Likewise. * tree-ssa-phiopt.c: Include cfgloop.h and tree-data-ref.h. (cond_if_else_store_replacement): Rename to... (cond_if_else_store_replacement_1): ... this. Change arguments and documentation. (cond_if_else_store_replacement): New function. * Makefile.in (tree-ssa-phiopt.o): Adjust dependencies. testsuite/ChangeLog: * gcc.dg/vect/vect-cselim-1.c: New test. * gcc.dg/vect/vect-cselim-2.c: New test. Index: tree-data-ref.c === --- tree-data-ref.c (revision 170712) +++ tree-data-ref.c (working copy) @@ -991,6 +991,48 @@ create_data_ref (loop_p nest, loop_p loop, tree me return dr; } +/* Check if OFFSET1 and OFFSET2 (DR_OFFSETs of some data-refs) are identical + expressions. */ +static bool +dr_equal_offsets_p1 (tree offset1, tree offset2) +{ + bool res; + + STRIP_NOPS (offset1); + STRIP_NOPS (offset2); + + if (offset1 == offset2) +return true; + + if (TREE_CODE (offset1) != TREE_CODE (offset2) + || (!BINARY_CLASS_P (offset1) !UNARY_CLASS_P (offset1))) +return false; + + res = dr_equal_offsets_p1 (TREE_OPERAND (offset1, 0), + TREE_OPERAND (offset2, 0)); + + if (!res || !BINARY_CLASS_P (offset1)) +return res; + + res = dr_equal_offsets_p1 (TREE_OPERAND (offset1, 1), + TREE_OPERAND (offset2, 1)); + + return res; +} + +/* Check if DRA and DRB have equal offsets. */ +bool +dr_equal_offsets_p (struct data_reference *dra, +struct data_reference *drb) +{ + tree offset1, offset2; + + offset1 = DR_OFFSET (dra); + offset2 = DR_OFFSET (drb); + + return dr_equal_offsets_p1 (offset1, offset2); +} + /* Returns true if FNA == FNB. */ static bool Index: tree-data-ref.h === --- tree-data-ref.h (revision 170712) +++ tree-data-ref.h (working copy) @@ -430,6 +430,8 @@ extern void compute_all_dependences (VEC (data_ref extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *); extern bool dr_may_alias_p (const struct data_reference *, const struct data_reference *); +extern bool dr_equal_offsets_p (struct data_reference *, +struct data_reference *); /* Return true when the base objects of data references A and B are Index: tree-vect-data-refs.c === --- tree-vect-data-refs.c (revision 170712) +++ tree-vect-data-refs.c (working copy) @@ -289,39 +289,6 @@ vect_update_interleaving_chain (struct data_refere } } - -/* Function vect_equal_offsets. - - Check if OFFSET1 and OFFSET2 are identical expressions. */ - -static bool -vect_equal_offsets (tree offset1, tree offset2) -{ - bool res; - - STRIP_NOPS (offset1); - STRIP_NOPS (offset2); - - if (offset1 == offset2) -return true; - - if (TREE_CODE (offset1) != TREE_CODE (offset2) - || (!BINARY_CLASS_P (offset1) !UNARY_CLASS_P (offset1))) -return false; - - res = vect_equal_offsets (TREE_OPERAND (offset1, 0), - TREE_OPERAND (offset2, 0)); - - if (!res || !BINARY_CLASS_P (offset1)) -return res; - - res = vect_equal_offsets (TREE_OPERAND (offset1, 1), - TREE_OPERAND (offset2, 1)); - - return res; -} - - /* Check dependence between DRA and DRB for basic block vectorization. If the accesses share same bases and offsets, we can compare their initial constant offsets to decide whether they differ or not. In case of a read- @@ -352,7 +319,7 @@ vect_drs_dependent_in_basic_block (struct data_ref || TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR || TREE_OPERAND (DR_BASE_ADDRESS (dra), 0) != TREE_OPERAND (DR_BASE_ADDRESS (drb),0))) -