From: spop Date: Mon, 3 Nov 2008 16:35:13 +0000 (+0000) Subject: 2008-11-03 Sebastian Pop X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=577982d87ba0f4f257fc25479992e1ada6d6fbc1;hp=2c3933b87b056dce86c72fc95813f10d528e1a50 2008-11-03 Sebastian Pop PR tree-optimization/36908 * testsuite/gcc.dg/tree-ssa/pr36908.c: New. * tree-loop-distribution.c (number_of_rw_in_rdg): New. (number_of_rw_in_partition): New. (partition_contains_all_rw): New. (ldist_gen): Do not distribute when one of the partitions contains all the memory operations. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141550 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d9bfaa71bb..4ecb1e12998 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2008-11-03 Sebastian Pop + PR tree-optimization/36908 + * testsuite/gcc.dg/tree-ssa/pr36908.c: New. + * tree-loop-distribution.c (number_of_rw_in_rdg): New. + (number_of_rw_in_partition): New. + (partition_contains_all_rw): New. + (ldist_gen): Do not distribute when one of the partitions + contains all the memory operations. + +2008-11-03 Sebastian Pop + * cfghooks.c (split_block): Set BB_IRREDUCIBLE_LOOP and EDGE_IRREDUCIBLE_LOOP. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr36908.c b/gcc/testsuite/gcc.dg/tree-ssa/pr36908.c new file mode 100644 index 00000000000..a135bcff238 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr36908.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-distribution" } */ +#define NULL ((void *)0) + +typedef unsigned int size_t; +extern void *foo(size_t nelem, size_t elsize); +extern void bar (char*, ...); + +typedef struct alt_state *alt_state_t; +typedef struct state *state_t; + +struct alt_state +{ + alt_state_t next_alt_state; +}; + +static alt_state_t first_free_alt_state = NULL; + +static void +free_alt_state (alt_state_t alt_state) +{ + if (alt_state == NULL) + return; + alt_state->next_alt_state = first_free_alt_state; + first_free_alt_state = alt_state; +} + +/* The function frees list started with node ALT_STATE_LIST. */ +static void +free_alt_states (alt_state_t alt_states_list) +{ + alt_state_t curr_alt_state; + alt_state_t next_alt_state; + + for (curr_alt_state = alt_states_list; + curr_alt_state != NULL; + curr_alt_state = next_alt_state) + { + next_alt_state = curr_alt_state->next_alt_state; + free_alt_state (curr_alt_state); + } +} + +int +main (void) +{ + int i; + alt_state_t state, act_state; + + act_state = state = foo (1, sizeof (struct alt_state)); + for (i = 0; i < 2; i ++) + { + act_state->next_alt_state = foo (1, sizeof (struct alt_state)); + act_state = act_state->next_alt_state; + } + + free_alt_states (state); + + for (act_state = first_free_alt_state; + act_state != NULL; + act_state = act_state->next_alt_state) + bar ("going from %p to %p\n", act_state, act_state->next_alt_state); + + return 0; +} diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index ed54cf32730..bd6a9322500 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -945,6 +945,64 @@ debug_rdg_partitions (VEC (bitmap, heap) *partitions) dump_rdg_partitions (stderr, partitions); } +/* Returns the number of read and write operations in the RDG. */ + +static int +number_of_rw_in_rdg (struct graph *rdg) +{ + int i, res = 0; + + for (i = 0; i < rdg->n_vertices; i++) + { + if (RDG_MEM_WRITE_STMT (rdg, i)) + ++res; + + if (RDG_MEM_READS_STMT (rdg, i)) + ++res; + } + + return res; +} + +/* Returns the number of read and write operations in a PARTITION of + the RDG. */ + +static int +number_of_rw_in_partition (struct graph *rdg, bitmap partition) +{ + int res = 0; + unsigned i; + bitmap_iterator ii; + + EXECUTE_IF_SET_IN_BITMAP (partition, 0, i, ii) + { + if (RDG_MEM_WRITE_STMT (rdg, i)) + ++res; + + if (RDG_MEM_READS_STMT (rdg, i)) + ++res; + } + + return res; +} + +/* Returns true when one of the PARTITIONS contains all the read or + write operations of RDG. */ + +static bool +partition_contains_all_rw (struct graph *rdg, VEC (bitmap, heap) *partitions) +{ + int i; + bitmap partition; + int nrw = number_of_rw_in_rdg (rdg); + + for (i = 0; VEC_iterate (bitmap, partitions, i, partition); i++) + if (nrw == number_of_rw_in_partition (rdg, partition)) + return true; + + return false; +} + /* Generate code from STARTING_VERTICES in RDG. Returns the number of distributed loops. */ @@ -992,7 +1050,8 @@ ldist_gen (struct loop *loop, struct graph *rdg, BITMAP_FREE (processed); nbp = VEC_length (bitmap, partitions); - if (nbp <= 1) + if (nbp <= 1 + || partition_contains_all_rw (rdg, partitions)) goto ldist_done; if (dump_file && (dump_flags & TDF_DETAILS))