diff options
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/Makefile.in | 4 | ||||
-rw-r--r-- | gcc/cfgloop.c | 17 | ||||
-rw-r--r-- | gcc/cfgloop.h | 4 | ||||
-rw-r--r-- | gcc/lto-streamer-in.c | 54 | ||||
-rw-r--r-- | gcc/lto-streamer-out.c | 45 |
6 files changed, 125 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e283c3d..0015337 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2013-04-26 Richard Biener <rguenther@suse.de> + + * Makefile.in (lto-streamer-in.o): Add $(CFGLOOP_H) dependency. + (lto-streamer-out.o): Likewise. + * cfgloop.c (init_loops_structure): Export, add struct function + argument and adjust. + (flow_loops_find): Adjust. + * cfgloop.h (enum loop_estimation): Add EST_LAST. + (init_loops_structure): Declare. + * lto-streamer-in.c: Include cfgloop.h. + (input_cfg): Input the loop tree. + * lto-streamer-out.c: Include cfgloop.h. + (output_cfg): Output the loop tree. + (output_struct_function_base): Do not drop PROP_loops. + 2013-03-26 Richard Biener <rguenther@suse.de> * tree-cfg.c (execute_build_cfg): Build the loop tree. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 36b0062..8dda925 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2173,11 +2173,11 @@ lto-streamer-in.o: lto-streamer-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) \ input.h $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) $(EXCEPT_H) debug.h \ - $(IPA_UTILS_H) $(LTO_STREAMER_H) toplev.h \ + $(IPA_UTILS_H) $(LTO_STREAMER_H) toplev.h $(CFGLOOP_H) \ $(DATA_STREAMER_H) $(GIMPLE_STREAMER_H) $(TREE_STREAMER_H) lto-streamer-out.o : lto-streamer-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(DIAGNOSTIC_CORE_H) $(TREE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \ - $(HASHTAB_H) $(BASIC_BLOCK_H) tree-iterator.h \ + $(HASHTAB_H) $(BASIC_BLOCK_H) tree-iterator.h $(CFGLOOP_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) \ $(DIAGNOSTIC_CORE_H) $(EXCEPT_H) $(LTO_STREAMER_H) $(DIAGNOSTIC_CORE_H) \ $(DATA_STREAMER_H) $(STREAMER_HOOKS_H) $(GIMPLE_STREAMER_H) \ diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 568b7a2..28b63ae 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -339,8 +339,9 @@ alloc_loop (void) /* Initializes loops structure LOOPS, reserving place for NUM_LOOPS loops (including the root of the loop tree). */ -static void -init_loops_structure (struct loops *loops, unsigned num_loops) +void +init_loops_structure (struct function *fn, + struct loops *loops, unsigned num_loops) { struct loop *root; @@ -349,11 +350,11 @@ init_loops_structure (struct loops *loops, unsigned num_loops) /* Dummy loop containing whole function. */ root = alloc_loop (); - root->num_nodes = n_basic_blocks; - root->latch = EXIT_BLOCK_PTR; - root->header = ENTRY_BLOCK_PTR; - ENTRY_BLOCK_PTR->loop_father = root; - EXIT_BLOCK_PTR->loop_father = root; + root->num_nodes = n_basic_blocks_for_function (fn); + root->latch = EXIT_BLOCK_PTR_FOR_FUNCTION (fn); + root->header = ENTRY_BLOCK_PTR_FOR_FUNCTION (fn); + ENTRY_BLOCK_PTR_FOR_FUNCTION (fn)->loop_father = root; + EXIT_BLOCK_PTR_FOR_FUNCTION (fn)->loop_father = root; loops->larray->quick_push (root); loops->tree_root = root; @@ -411,7 +412,7 @@ flow_loops_find (struct loops *loops) if (!loops) { loops = ggc_alloc_cleared_loops (); - init_loops_structure (loops, 1); + init_loops_structure (cfun, loops, 1); } /* Ensure that loop exits were released. */ diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 948e805..5c38599 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -97,7 +97,8 @@ enum loop_estimation /* Estimate was not computed yet. */ EST_NOT_COMPUTED, /* Estimate is ready. */ - EST_AVAILABLE + EST_AVAILABLE, + EST_LAST }; /* Structure to hold information for each natural loop. */ @@ -213,6 +214,7 @@ struct GTY (()) loops { /* Loop recognition. */ bool bb_loop_header_p (basic_block); +void init_loops_structure (struct function *, struct loops *, unsigned); extern struct loops *flow_loops_find (struct loops *); extern void disambiguate_loops_with_multiple_latches (void); extern void flow_loops_free (struct loops *); diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index c4daa30..f5789c0 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -48,6 +48,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-streamer.h" #include "tree-pass.h" #include "streamer-hooks.h" +#include "cfgloop.h" + struct freeing_string_slot_hasher : string_slot_hasher { @@ -660,6 +662,58 @@ input_cfg (struct lto_input_block *ib, struct function *fn, p_bb = bb; index = streamer_read_hwi (ib); } + + /* ??? The cfgloop interface is tied to cfun. */ + gcc_assert (cfun == fn); + + /* Input the loop tree. */ + unsigned n_loops = streamer_read_uhwi (ib); + if (n_loops == 0) + return; + + struct loops *loops = ggc_alloc_cleared_loops (); + init_loops_structure (fn, loops, n_loops); + + /* Input each loop and associate it with its loop header so + flow_loops_find can rebuild the loop tree. */ + for (unsigned i = 1; i < n_loops; ++i) + { + int header_index = streamer_read_hwi (ib); + if (header_index == -1) + { + loops->larray->quick_push (NULL); + continue; + } + + struct loop *loop = alloc_loop (); + loop->num = loops->larray->length (); + loop->header = BASIC_BLOCK_FOR_FUNCTION (fn, header_index); + loop->header->loop_father = loop; + + /* Read everything copy_loop_info copies. */ + loop->estimate_state = streamer_read_enum (ib, loop_estimation, EST_LAST); + loop->any_upper_bound = streamer_read_hwi (ib); + if (loop->any_upper_bound) + { + loop->nb_iterations_upper_bound.low = streamer_read_uhwi (ib); + loop->nb_iterations_upper_bound.high = streamer_read_hwi (ib); + } + loop->any_estimate = streamer_read_hwi (ib); + if (loop->any_estimate) + { + loop->nb_iterations_estimate.low = streamer_read_uhwi (ib); + loop->nb_iterations_estimate.high = streamer_read_hwi (ib); + } + + loops->larray->quick_push (loop); + + /* flow_loops_find doesn't like loops not in the tree, hook them + all as siblings of the tree root temporarily. */ + flow_loop_tree_node_add (loops->tree_root, loop); + } + + /* Rebuild the loop tree. */ + fn->x_current_loops = flow_loops_find (loops); } diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index afb73f2..110cc3e 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-streamer.h" #include "tree-streamer.h" #include "streamer-hooks.h" +#include "cfgloop.h" /* Clear the line info stored in DATA_IN. */ @@ -659,6 +660,45 @@ output_cfg (struct output_block *ob, struct function *fn) streamer_write_hwi (ob, -1); + /* ??? The cfgloop interface is tied to cfun. */ + gcc_assert (cfun == fn); + + /* Output the number of loops. */ + streamer_write_uhwi (ob, number_of_loops ()); + + /* Output each loop, skipping the tree root which has number zero. */ + for (unsigned i = 1; i < number_of_loops (); ++i) + { + struct loop *loop = get_loop (i); + + /* Write the index of the loop header. That's enough to rebuild + the loop tree on the reader side. Stream -1 for an unused + loop entry. */ + if (!loop) + { + streamer_write_hwi (ob, -1); + continue; + } + else + streamer_write_hwi (ob, loop->header->index); + + /* Write everything copy_loop_info copies. */ + streamer_write_enum (ob->main_stream, + loop_estimation, EST_LAST, loop->estimate_state); + streamer_write_hwi (ob, loop->any_upper_bound); + if (loop->any_upper_bound) + { + streamer_write_uhwi (ob, loop->nb_iterations_upper_bound.low); + streamer_write_hwi (ob, loop->nb_iterations_upper_bound.high); + } + streamer_write_hwi (ob, loop->any_estimate); + if (loop->any_estimate) + { + streamer_write_uhwi (ob, loop->nb_iterations_estimate.low); + streamer_write_hwi (ob, loop->nb_iterations_estimate.high); + } + } + ob->main_stream = tmp_stream; } @@ -733,9 +773,8 @@ output_struct_function_base (struct output_block *ob, struct function *fn) FOR_EACH_VEC_SAFE_ELT (fn->local_decls, i, t) stream_write_tree (ob, t, true); - /* Output current IL state of the function. - ??? We don't stream loops. */ - streamer_write_uhwi (ob, fn->curr_properties & ~PROP_loops); + /* Output current IL state of the function. */ + streamer_write_uhwi (ob, fn->curr_properties); /* Write all the attributes for FN. */ bp = bitpack_create (ob->main_stream); |