| Index: gcc/gcc/tree-loop-distribution.c
|
| diff --git a/gcc/gcc/tree-loop-distribution.c b/gcc/gcc/tree-loop-distribution.c
|
| index 219d17e70021f83f747278dc9e9361d70370d6b0..238024d44ce296b0382a9677d25bbb21b6463bd5 100644
|
| --- a/gcc/gcc/tree-loop-distribution.c
|
| +++ b/gcc/gcc/tree-loop-distribution.c
|
| @@ -1,20 +1,21 @@
|
| /* Loop distribution.
|
| - Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
| + Copyright (C) 2006, 2007, 2008, 2009, 2010
|
| + Free Software Foundation, Inc.
|
| Contributed by Georges-Andre Silber <Georges-Andre.Silber@ensmp.fr>
|
| and Sebastian Pop <sebastian.pop@amd.com>.
|
|
|
| This file is part of GCC.
|
| -
|
| +
|
| GCC is free software; you can redistribute it and/or modify it
|
| under the terms of the GNU General Public License as published by the
|
| Free Software Foundation; either version 3, or (at your option) any
|
| later version.
|
| -
|
| +
|
| GCC is distributed in the hope that it will be useful, but WITHOUT
|
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
| for more details.
|
| -
|
| +
|
| You should have received a copy of the GNU General Public License
|
| along with GCC; see the file COPYING3. If not see
|
| <http://www.gnu.org/licenses/>. */
|
| @@ -26,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
|
| | D(I) = A(I-1)*E
|
| |ENDDO
|
|
|
| - is transformed to
|
| + is transformed to
|
|
|
| |DOALL I = 2, N
|
| | A(I) = B(I) + C
|
| @@ -77,9 +78,6 @@ static bitmap remaining_stmts;
|
| predecessor a node that writes to memory. */
|
| static bitmap upstream_mem_writes;
|
|
|
| -/* TODOs we need to run after the pass. */
|
| -static unsigned int todo;
|
| -
|
| /* Update the PHI nodes of NEW_LOOP. NEW_LOOP is a duplicate of
|
| ORIG_LOOP. */
|
|
|
| @@ -100,17 +98,20 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
|
| gsi_next (&si_new), gsi_next (&si_orig))
|
| {
|
| tree def;
|
| + source_location locus;
|
| gimple phi_new = gsi_stmt (si_new);
|
| gimple phi_orig = gsi_stmt (si_orig);
|
|
|
| /* Add the first phi argument for the phi in NEW_LOOP (the one
|
| associated with the entry of NEW_LOOP) */
|
| def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
|
| - add_phi_arg (phi_new, def, new_loop_entry_e);
|
| + locus = gimple_phi_arg_location_from_edge (phi_orig, orig_entry_e);
|
| + add_phi_arg (phi_new, def, new_loop_entry_e, locus);
|
|
|
| /* Add the second phi argument for the phi in NEW_LOOP (the one
|
| associated with the latch of NEW_LOOP) */
|
| def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
|
| + locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
|
|
|
| if (TREE_CODE (def) == SSA_NAME)
|
| {
|
| @@ -118,14 +119,14 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
|
|
|
| if (!new_ssa_name)
|
| /* This only happens if there are no definitions inside the
|
| - loop. Use the phi_result in this case. */
|
| - new_ssa_name = PHI_RESULT (phi_new);
|
| + loop. Use the the invariant in the new loop as is. */
|
| + new_ssa_name = def;
|
| }
|
| else
|
| /* Could be an integer. */
|
| new_ssa_name = def;
|
|
|
| - add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
|
| + add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
|
| }
|
| }
|
|
|
| @@ -201,38 +202,51 @@ generate_loops_for_partition (struct loop *loop, bitmap partition, bool copy_p)
|
|
|
| for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi);)
|
| if (!bitmap_bit_p (partition, x++))
|
| - remove_phi_node (&bsi, true);
|
| + {
|
| + gimple phi = gsi_stmt (bsi);
|
| + if (!is_gimple_reg (gimple_phi_result (phi)))
|
| + mark_virtual_phi_result_for_renaming (phi);
|
| + remove_phi_node (&bsi, true);
|
| + }
|
| else
|
| gsi_next (&bsi);
|
|
|
| for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);)
|
| - if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL
|
| - && !bitmap_bit_p (partition, x++))
|
| - gsi_remove (&bsi, false);
|
| - else
|
| - gsi_next (&bsi);
|
| -
|
| - mark_virtual_ops_in_bb (bb);
|
| + {
|
| + gimple stmt = gsi_stmt (bsi);
|
| + if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL
|
| + && !bitmap_bit_p (partition, x++))
|
| + {
|
| + unlink_stmt_vdef (stmt);
|
| + gsi_remove (&bsi, true);
|
| + release_defs (stmt);
|
| + }
|
| + else
|
| + gsi_next (&bsi);
|
| + }
|
| }
|
|
|
| free (bbs);
|
| return true;
|
| }
|
|
|
| -/* Build size argument. */
|
| +/* Build the size argument for a memset call. */
|
|
|
| static inline tree
|
| -build_size_arg (tree nb_iter, tree op, gimple_seq* stmt_list)
|
| +build_size_arg_loc (location_t loc, tree nb_iter, tree op,
|
| + gimple_seq *stmt_list)
|
| {
|
| - tree nb_bytes;
|
| - gimple_seq stmts = NULL;
|
| + gimple_seq stmts;
|
| + tree x;
|
|
|
| - nb_bytes = fold_build2 (MULT_EXPR, TREE_TYPE (nb_iter),
|
| - nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op)));
|
| - nb_bytes = force_gimple_operand (nb_bytes, &stmts, true, NULL);
|
| - gimple_seq_add_seq (stmt_list, stmts);
|
| + x = fold_build2_loc (loc, MULT_EXPR, size_type_node,
|
| + fold_convert_loc (loc, size_type_node, nb_iter),
|
| + fold_convert_loc (loc, size_type_node,
|
| + TYPE_SIZE_UNIT (TREE_TYPE (op))));
|
| + x = force_gimple_operand (x, &stmts, true, NULL);
|
| + gimple_seq_add_seq (stmt_list, stmts);
|
|
|
| - return nb_bytes;
|
| + return x;
|
| }
|
|
|
| /* Generate a call to memset. Return true when the operation succeeded. */
|
| @@ -241,15 +255,13 @@ static bool
|
| generate_memset_zero (gimple stmt, tree op0, tree nb_iter,
|
| gimple_stmt_iterator bsi)
|
| {
|
| - tree t, addr_base;
|
| - tree nb_bytes = NULL;
|
| + tree addr_base, nb_bytes;
|
| bool res = false;
|
| - gimple_seq stmts = NULL, stmt_list = NULL;
|
| + gimple_seq stmt_list = NULL, stmts;
|
| gimple fn_call;
|
| - tree mem, fndecl, fntype, fn;
|
| - gimple_stmt_iterator i;
|
| - ssa_op_iter iter;
|
| + tree mem, fn;
|
| struct data_reference *dr = XCNEW (struct data_reference);
|
| + location_t loc = gimple_location (stmt);
|
|
|
| DR_STMT (dr) = stmt;
|
| DR_REF (dr) = op0;
|
| @@ -257,32 +269,37 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter,
|
| goto end;
|
|
|
| /* Test for a positive stride, iterating over every element. */
|
| - if (integer_zerop (fold_build2 (MINUS_EXPR, integer_type_node, DR_STEP (dr),
|
| - TYPE_SIZE_UNIT (TREE_TYPE (op0)))))
|
| + if (integer_zerop (size_binop (MINUS_EXPR,
|
| + fold_convert (sizetype, DR_STEP (dr)),
|
| + TYPE_SIZE_UNIT (TREE_TYPE (op0)))))
|
| {
|
| - tree offset = fold_convert (sizetype,
|
| - size_binop (PLUS_EXPR,
|
| - DR_OFFSET (dr),
|
| - DR_INIT (dr)));
|
| - addr_base = fold_build2 (POINTER_PLUS_EXPR,
|
| - TREE_TYPE (DR_BASE_ADDRESS (dr)),
|
| - DR_BASE_ADDRESS (dr), offset);
|
| + addr_base = fold_convert_loc (loc, sizetype,
|
| + size_binop_loc (loc, PLUS_EXPR,
|
| + DR_OFFSET (dr),
|
| + DR_INIT (dr)));
|
| + addr_base = fold_build2_loc (loc, POINTER_PLUS_EXPR,
|
| + TREE_TYPE (DR_BASE_ADDRESS (dr)),
|
| + DR_BASE_ADDRESS (dr), addr_base);
|
| +
|
| + nb_bytes = build_size_arg_loc (loc, nb_iter, op0, &stmt_list);
|
| }
|
|
|
| /* Test for a negative stride, iterating over every element. */
|
| - else if (integer_zerop (fold_build2 (PLUS_EXPR, integer_type_node,
|
| - TYPE_SIZE_UNIT (TREE_TYPE (op0)),
|
| - DR_STEP (dr))))
|
| + else if (integer_zerop (size_binop (PLUS_EXPR,
|
| + TYPE_SIZE_UNIT (TREE_TYPE (op0)),
|
| + fold_convert (sizetype, DR_STEP (dr)))))
|
| {
|
| - nb_bytes = build_size_arg (nb_iter, op0, &stmt_list);
|
| - addr_base = size_binop (PLUS_EXPR, DR_OFFSET (dr), DR_INIT (dr));
|
| - addr_base = fold_build2 (MINUS_EXPR, sizetype, addr_base, nb_bytes);
|
| - addr_base = force_gimple_operand (addr_base, &stmts, true, NULL);
|
| - gimple_seq_add_seq (&stmt_list, stmts);
|
| -
|
| - addr_base = fold_build2 (POINTER_PLUS_EXPR,
|
| - TREE_TYPE (DR_BASE_ADDRESS (dr)),
|
| - DR_BASE_ADDRESS (dr), addr_base);
|
| + nb_bytes = build_size_arg_loc (loc, nb_iter, op0, &stmt_list);
|
| +
|
| + addr_base = size_binop_loc (loc, PLUS_EXPR, DR_OFFSET (dr), DR_INIT (dr));
|
| + addr_base = fold_convert_loc (loc, sizetype, addr_base);
|
| + addr_base = size_binop_loc (loc, MINUS_EXPR, addr_base,
|
| + fold_convert_loc (loc, sizetype, nb_bytes));
|
| + addr_base = size_binop_loc (loc, PLUS_EXPR, addr_base,
|
| + TYPE_SIZE_UNIT (TREE_TYPE (op0)));
|
| + addr_base = fold_build2_loc (loc, POINTER_PLUS_EXPR,
|
| + TREE_TYPE (DR_BASE_ADDRESS (dr)),
|
| + DR_BASE_ADDRESS (dr), addr_base);
|
| }
|
| else
|
| goto end;
|
| @@ -290,52 +307,15 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter,
|
| mem = force_gimple_operand (addr_base, &stmts, true, NULL);
|
| gimple_seq_add_seq (&stmt_list, stmts);
|
|
|
| - fndecl = implicit_built_in_decls [BUILT_IN_MEMSET];
|
| - fntype = TREE_TYPE (fndecl);
|
| - fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
|
| -
|
| - if (!nb_bytes)
|
| - nb_bytes = build_size_arg (nb_iter, op0, &stmt_list);
|
| + fn = build_fold_addr_expr (implicit_built_in_decls [BUILT_IN_MEMSET]);
|
| fn_call = gimple_build_call (fn, 3, mem, integer_zero_node, nb_bytes);
|
| gimple_seq_add_stmt (&stmt_list, fn_call);
|
| -
|
| - for (i = gsi_start (stmt_list); !gsi_end_p (i); gsi_next (&i))
|
| - {
|
| - gimple s = gsi_stmt (i);
|
| - update_stmt_if_modified (s);
|
| -
|
| - FOR_EACH_SSA_TREE_OPERAND (t, s, iter, SSA_OP_VIRTUAL_DEFS)
|
| - {
|
| - if (TREE_CODE (t) == SSA_NAME)
|
| - t = SSA_NAME_VAR (t);
|
| - mark_sym_for_renaming (t);
|
| - }
|
| - }
|
| -
|
| - /* Mark also the uses of the VDEFS of STMT to be renamed. */
|
| - FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, SSA_OP_VIRTUAL_DEFS)
|
| - {
|
| - if (TREE_CODE (t) == SSA_NAME)
|
| - {
|
| - gimple s;
|
| - imm_use_iterator imm_iter;
|
| -
|
| - FOR_EACH_IMM_USE_STMT (s, imm_iter, t)
|
| - update_stmt (s);
|
| -
|
| - t = SSA_NAME_VAR (t);
|
| - }
|
| - mark_sym_for_renaming (t);
|
| - }
|
| -
|
| gsi_insert_seq_after (&bsi, stmt_list, GSI_CONTINUE_LINKING);
|
| res = true;
|
|
|
| if (dump_file && (dump_flags & TDF_DETAILS))
|
| fprintf (dump_file, "generated memset zero\n");
|
|
|
| - todo |= TODO_rebuild_alias;
|
| -
|
| end:
|
| free_data_ref (dr);
|
| return res;
|
| @@ -414,6 +394,8 @@ generate_builtin (struct loop *loop, bitmap partition, bool copy_p)
|
| goto end;
|
|
|
| write = stmt;
|
| + if (bb == loop->latch)
|
| + nb_iter = number_of_latch_executions (loop);
|
| }
|
| }
|
| }
|
| @@ -542,7 +524,6 @@ mark_nodes_having_upstream_mem_writes (struct graph *rdg)
|
| {
|
| unsigned i;
|
| VEC (int, heap) *nodes = VEC_alloc (int, heap, 3);
|
| - bool has_upstream_mem_write_p = false;
|
|
|
| graphds_dfs (rdg, &v, 1, &nodes, false, NULL);
|
|
|
| @@ -560,7 +541,6 @@ mark_nodes_having_upstream_mem_writes (struct graph *rdg)
|
| should be placed in the same partition. */
|
| || has_anti_dependence (&(rdg->vertices[x])))
|
| {
|
| - has_upstream_mem_write_p = true;
|
| bitmap_set_bit (upstream_mem_writes, x);
|
| }
|
| }
|
| @@ -606,7 +586,6 @@ static void
|
| rdg_flag_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
|
| bitmap processed, bool *part_has_writes)
|
| {
|
| - ssa_op_iter iter;
|
| use_operand_p use_p;
|
| struct vertex *x = &(rdg->vertices[u]);
|
| gimple stmt = RDGV_STMT (x);
|
| @@ -626,7 +605,7 @@ rdg_flag_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
|
|
|
| if (gimple_code (stmt) != GIMPLE_PHI)
|
| {
|
| - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES)
|
| + if ((use_p = gimple_vuse_op (stmt)) != NULL_USE_OPERAND_P)
|
| {
|
| tree use = USE_FROM_PTR (use_p);
|
|
|
| @@ -877,7 +856,7 @@ free_rdg_components (VEC (rdgc, heap) *components)
|
| of RDG in which the STARTING_VERTICES occur. */
|
|
|
| static void
|
| -rdg_build_components (struct graph *rdg, VEC (int, heap) *starting_vertices,
|
| +rdg_build_components (struct graph *rdg, VEC (int, heap) *starting_vertices,
|
| VEC (rdgc, heap) **components)
|
| {
|
| int i, v;
|
| @@ -932,10 +911,10 @@ rdg_build_partitions (struct graph *rdg, VEC (rdgc, heap) *components,
|
| bitmap np;
|
| bool part_has_writes = false;
|
| int v = VEC_index (int, x->vertices, 0);
|
| -
|
| +
|
| if (bitmap_bit_p (processed, v))
|
| continue;
|
| -
|
| +
|
| np = build_rdg_partition_for_component (rdg, x, &part_has_writes,
|
| other_stores);
|
| bitmap_ior_into (partition, np);
|
| @@ -1148,7 +1127,7 @@ ldist_gen (struct loop *loop, struct graph *rdg,
|
| static int
|
| distribute_loop (struct loop *loop, VEC (gimple, heap) *stmts)
|
| {
|
| - bool res = false;
|
| + int res = 0;
|
| struct graph *rdg;
|
| gimple s;
|
| unsigned i;
|
| @@ -1211,8 +1190,6 @@ tree_loop_distribution (void)
|
| loop_iterator li;
|
| int nb_generated_loops = 0;
|
|
|
| - todo = 0;
|
| -
|
| FOR_EACH_LOOP (li, loop, 0)
|
| {
|
| VEC (gimple, heap) *work_list = VEC_alloc (gimple, heap, 3);
|
| @@ -1244,7 +1221,7 @@ tree_loop_distribution (void)
|
| VEC_free (gimple, heap, work_list);
|
| }
|
|
|
| - return todo;
|
| + return 0;
|
| }
|
|
|
| static bool
|
|
|