diff mbox

The remainder of tree-flow.h refactored.

Message ID 524EF235.5080803@redhat.com
State New
Headers show

Commit Message

Andrew MacLeod Oct. 4, 2013, 4:52 p.m. UTC
This patch clears the rest of the improperly located prototypes out of 
tree-flow.h.  A bit larger than the last few, but I was pushing to clear 
this up, and its not quite as bad as it seems :-)

Of interest:

* tree-flow.h now contains *only* prototypes for tree-cfg.c now. Next 
week I'll rename it to tree-cfg.h when I  visit all the .c files which 
include tree-flow.h to see who the true consumers are now.

* tree-ssa-address.c only had one client for get_address_description, 
and that required exposing struct mem_address in tree-flow.h.  Since 
that call was followed by a call to  addr_for_mem_ref with the 
structure, i figured it was better to create a new funciton which 
combined that functionality. NOw the struct is internal only.

* ipa_pure_const.c has only a single export... warn_function_noreturn() 
which was only used in one place, tree-cfg.c to implement the 
warn_function_noreturn pass.  Although the name of the file is not 
really appropriate, I moved the pass structural stuff into 
ipa_pure_const.c and now there are no exports.  I looked at numerous 
other options, and in the end, this one is cleanest.  There is no other 
good home for the bits an pieces that can be shuffled.   maybe 
ipa-func-attr.c would be a better file name :-P but that is a miniscule 
issue :_)

* tree-cfg.c had the warn_function_noreturn pass removed from it, but I 
relocated the execute_fixup_cfg routine/pass from tree-optimize.c here. 
It makes more sense here and that was the only routines being exported 
from tree-optimize.c, and tree-cfg was the only consumer.

* tree-dump.h was explicitly prototyping dump_function_to_file() from 
tree-cfg.c, presumably to avoid including all of tree-flow.h. I removed 
that and include tree-flow.h from tree-dump.c.   Seems like a backwards 
step until one realizes that tree-flow.h is now the header file for 
tree-cfg.c.

* tree-ssa-dom.c::tree_ssa_dominator_optimize()  was calling 
ssa_name_values.release() from tree-ssa-threadedge.c, and was the only 
consumer.  The call immediately before is to 
threadedge_finalize_values() which performs that operation, I deleted 
the use from tree-ssa-dom.c.   I would like to have made the vec<tree> 
ssa_name_values static within the file too, but then the SSA_NAME_VALUE 
macro to access it would have to make a call into a function in the .c 
file to access it, and I don't know what the performance hit would be... 
I expect it would be un-noticable to abstract that out... but I left it 
for the moment.

* There was a bit of a mess between gimplify.c, gimple.c, and tree.c. In 
the end, I
     - relocated the tree copying and unsharing routines from gimplify.c 
to tree.c. The uses were sporadic throughout the compiler, and weren't 
always used by things that should be gimple aware.  They were pure tree 
routines, so that seemed like an appropriate place for them.  Maybe 
something like tree-share.[ch] would be better...  that could be dealt 
with during a tree.[ch] examination.
     -  force_gimple_operand_gsi_1and force_gimple_operand_gsi were the 
only routines in gimplify.c that operated with gimple statement 
iterators from gimple.c.  The include files had this chicken and egg 
problem where I couldn't resolve the ordering very well.  IN the end, I 
decided to relocate those 2 routines into gimple.c where there is a good 
understanding of gimple-iterators.  I expect the gimple iterators will 
be split from gimple.[ch] when I process gimple.h, so they may be 
relocatable again later.
     -  gimple.h declared some typedefs and enums that were 
gimplification specific, so I moved those to the new gimplfy.h as well.


This boostraps on x86_64-unknown-linux-gnu and has no new regressions.  OK?

Andrew

Comments

Richard Biener Oct. 8, 2013, 10:22 a.m. UTC | #1
On Fri, Oct 4, 2013 at 6:52 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
> This patch clears the rest of the improperly located prototypes out of
> tree-flow.h.  A bit larger than the last few, but I was pushing to clear
> this up, and its not quite as bad as it seems :-)
>
> Of interest:
>
> * tree-flow.h now contains *only* prototypes for tree-cfg.c now. Next week
> I'll rename it to tree-cfg.h when I  visit all the .c files which include
> tree-flow.h to see who the true consumers are now.
>
> * tree-ssa-address.c only had one client for get_address_description, and
> that required exposing struct mem_address in tree-flow.h.  Since that call
> was followed by a call to  addr_for_mem_ref with the structure, i figured it
> was better to create a new funciton which combined that functionality. NOw
> the struct is internal only.
>
> * ipa_pure_const.c has only a single export... warn_function_noreturn()
> which was only used in one place, tree-cfg.c to implement the
> warn_function_noreturn pass.  Although the name of the file is not really
> appropriate, I moved the pass structural stuff into ipa_pure_const.c and now
> there are no exports.  I looked at numerous other options, and in the end,
> this one is cleanest.  There is no other good home for the bits an pieces
> that can be shuffled.   maybe ipa-func-attr.c would be a better file name
> :-P but that is a miniscule issue :_)
>
> * tree-cfg.c had the warn_function_noreturn pass removed from it, but I
> relocated the execute_fixup_cfg routine/pass from tree-optimize.c here. It
> makes more sense here and that was the only routines being exported from
> tree-optimize.c, and tree-cfg was the only consumer.
>
> * tree-dump.h was explicitly prototyping dump_function_to_file() from
> tree-cfg.c, presumably to avoid including all of tree-flow.h. I removed that
> and include tree-flow.h from tree-dump.c.   Seems like a backwards step
> until one realizes that tree-flow.h is now the header file for tree-cfg.c.
>
> * tree-ssa-dom.c::tree_ssa_dominator_optimize()  was calling
> ssa_name_values.release() from tree-ssa-threadedge.c, and was the only
> consumer.  The call immediately before is to threadedge_finalize_values()
> which performs that operation, I deleted the use from tree-ssa-dom.c.   I
> would like to have made the vec<tree> ssa_name_values static within the file
> too, but then the SSA_NAME_VALUE macro to access it would have to make a
> call into a function in the .c file to access it, and I don't know what the
> performance hit would be... I expect it would be un-noticable to abstract
> that out... but I left it for the moment.
>
> * There was a bit of a mess between gimplify.c, gimple.c, and tree.c. In the
> end, I
>     - relocated the tree copying and unsharing routines from gimplify.c to
> tree.c. The uses were sporadic throughout the compiler, and weren't always
> used by things that should be gimple aware.  They were pure tree routines,
> so that seemed like an appropriate place for them.  Maybe something like
> tree-share.[ch] would be better...  that could be dealt with during a
> tree.[ch] examination.
>     -  force_gimple_operand_gsi_1and force_gimple_operand_gsi were the only
> routines in gimplify.c that operated with gimple statement iterators from
> gimple.c.  The include files had this chicken and egg problem where I
> couldn't resolve the ordering very well.  IN the end, I decided to relocate
> those 2 routines into gimple.c where there is a good understanding of
> gimple-iterators.  I expect the gimple iterators will be split from
> gimple.[ch] when I process gimple.h, so they may be relocatable again later.
>     -  gimple.h declared some typedefs and enums that were gimplification
> specific, so I moved those to the new gimplfy.h as well.
>
>
> This boostraps on x86_64-unknown-linux-gnu and has no new regressions.  OK?

graphite.h should be unnecessary with moving the pass struct like you
did for other loop opts.  Likewise tree-parloops.h (well, ok, maybe
you need parallelized_function_p, even though it's implementation is
gross ;)).  Likewise tree-predcom.h.

unvisit_body isn't generic enough to warrant moving out of gimplify.c
(the only user).

The force_gimple_operand_gsi... routines are in gimplify.c because they ...
gimplify!  And you moved them but not force_gimple_operand[_1]!?

The rest looks reasonable (though the patch is big and I only had
a quick look).

Thanks,
Richard.



> Andrew
>
>
>
Andrew MacLeod Oct. 8, 2013, 11:44 a.m. UTC | #2
On 10/08/2013 06:22 AM, Richard Biener wrote:
> On Fri, Oct 4, 2013 at 6:52 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
>> This patch clears the rest of the improperly located prototypes out of
>> tree-flow.h.  A bit larger than the last few, but I was pushing to clear
>> this up, and its not quite as bad as it seems :-)
>>
>> Of interest:
>>
>> * tree-flow.h now contains *only* prototypes for tree-cfg.c now. Next week
>> I'll rename it to tree-cfg.h when I  visit all the .c files which include
>> tree-flow.h to see who the true consumers are now.
>>
>> * tree-ssa-address.c only had one client for get_address_description, and
>> that required exposing struct mem_address in tree-flow.h.  Since that call
>> was followed by a call to  addr_for_mem_ref with the structure, i figured it
>> was better to create a new funciton which combined that functionality. NOw
>> the struct is internal only.
>>
>> * ipa_pure_const.c has only a single export... warn_function_noreturn()
>> which was only used in one place, tree-cfg.c to implement the
>> warn_function_noreturn pass.  Although the name of the file is not really
>> appropriate, I moved the pass structural stuff into ipa_pure_const.c and now
>> there are no exports.  I looked at numerous other options, and in the end,
>> this one is cleanest.  There is no other good home for the bits an pieces
>> that can be shuffled.   maybe ipa-func-attr.c would be a better file name
>> :-P but that is a miniscule issue :_)
>>
>> * tree-cfg.c had the warn_function_noreturn pass removed from it, but I
>> relocated the execute_fixup_cfg routine/pass from tree-optimize.c here. It
>> makes more sense here and that was the only routines being exported from
>> tree-optimize.c, and tree-cfg was the only consumer.
>>
>> * tree-dump.h was explicitly prototyping dump_function_to_file() from
>> tree-cfg.c, presumably to avoid including all of tree-flow.h. I removed that
>> and include tree-flow.h from tree-dump.c.   Seems like a backwards step
>> until one realizes that tree-flow.h is now the header file for tree-cfg.c.
>>
>> * tree-ssa-dom.c::tree_ssa_dominator_optimize()  was calling
>> ssa_name_values.release() from tree-ssa-threadedge.c, and was the only
>> consumer.  The call immediately before is to threadedge_finalize_values()
>> which performs that operation, I deleted the use from tree-ssa-dom.c.   I
>> would like to have made the vec<tree> ssa_name_values static within the file
>> too, but then the SSA_NAME_VALUE macro to access it would have to make a
>> call into a function in the .c file to access it, and I don't know what the
>> performance hit would be... I expect it would be un-noticable to abstract
>> that out... but I left it for the moment.
>>
>> * There was a bit of a mess between gimplify.c, gimple.c, and tree.c. In the
>> end, I
>>      - relocated the tree copying and unsharing routines from gimplify.c to
>> tree.c. The uses were sporadic throughout the compiler, and weren't always
>> used by things that should be gimple aware.  They were pure tree routines,
>> so that seemed like an appropriate place for them.  Maybe something like
>> tree-share.[ch] would be better...  that could be dealt with during a
>> tree.[ch] examination.
>>      -  force_gimple_operand_gsi_1and force_gimple_operand_gsi were the only
>> routines in gimplify.c that operated with gimple statement iterators from
>> gimple.c.  The include files had this chicken and egg problem where I
>> couldn't resolve the ordering very well.  IN the end, I decided to relocate
>> those 2 routines into gimple.c where there is a good understanding of
>> gimple-iterators.  I expect the gimple iterators will be split from
>> gimple.[ch] when I process gimple.h, so they may be relocatable again later.
>>      -  gimple.h declared some typedefs and enums that were gimplification
>> specific, so I moved those to the new gimplfy.h as well.
>>
>>
>> This boostraps on x86_64-unknown-linux-gnu and has no new regressions.  OK?
> graphite.h should be unnecessary with moving the pass struct like you
> did for other loop opts.  Likewise tree-parloops.h (well, ok, maybe
> you need parallelized_function_p, even though it's implementation is
> gross ;)).  Likewise tree-predcom.h.

fair enough.  Yes, I've already seen a few things that madfe my skin 
crawl  and I had to resist going down a  rathole for :-)
>
> unvisit_body isn't generic enough to warrant moving out of gimplify.c
> (the only user).
>
> The force_gimple_operand_gsi... routines are in gimplify.c because they ...
> gimplify!  And you moved them but not force_gimple_operand[_1]!?

OK, let me make the above adjustments, and I'll recreate a patch without 
the gimple/gimplfy parts, and re-address that separately.  I forget the 
details of my include issues there at the moment.

thanks
Andrew
diff mbox

Patch


	* tree-flow.h: Remove all remaining prototypes, enums and structs that
	are not related to tree-cfg.c.
	* tree-ssa-address.h: New file.  Relocate prototypes.
	* tree-ssa-address.c: (struct mem_address): Relocate from tree-flow.h.
	(addr_for_mem_ref): New.  Combine call to get_address_description and
	return addr_for_mem_ref.
	* expr.c (expand_expr_real_1): Use new addr_for_mem_ref routine.
	* tree-ssa-live.h: Adjust prototypes.
	* passes.c: Include tree-ssa-live.h.
	* gimple-pretty-print.h (gimple_dump_bb): Add prototype.
	* graphite.h: New File.  Add prototypes.
	* graphite.c: Include graphite.h.
	* ipa-pure-const.c (warn_function_noreturn): Make static.
	(execute_warn_function_noreturn, gate_warn_function_noreturn,
	class pass_warn_function_noreturn, make_pass_warn_function_noreturn):
	Relocate from tree-cfg.c
	* tree-cfg.c (tree_node_can_be_shared, gimple_empty_block_p): Make
	static.
	(execute_warn_function_noreturn, gate_warn_function_noreturn,
	class pass_warn_function_noreturn, make_pass_warn_function_noreturn):
	Move to ipa-pure-const.c.
	(execute_fixup_cfg, class pass_fixup_cfg, make_pass_fixup_cfg): Relocate
	from tree-optimize.c.
	* tree-optimize.c (execute_fixup_cfg, class pass_fixup_cfg,
	make_pass_fixup_cfg): Move to tree-cfg.c.
	* tree-chrec.h: (enum ev_direction): Relocate here from tree-flow.h.
	Relocate some prototypes.
	* tree-data-ref.h (tree_check_data_deps) Add prototype.
	* tree-dump.c (dump_function_to_file): Remove prototype.
	Add tree-flow.h to the include file.
	* tree-dump.h: Remove prototype.
	* tree-parloops.h: New File.  Add prototypes.
	* tree-parloops.c: Include tree-parloops.h.
	* tree-predcom.h: New File.  Add prototypes.
	* tree-predcom.c: Include tree-predcom.h.
	* tree-ssa-dom.c (tree_ssa_dominator_optimize) Don't call 
	ssa_name_values.release ().
	* tree-ssa-threadedge.h: New File.  Relocate prototypes here.
	(ssa_name_values): Relocate from tree-flow.h.
	* tree-ssa.h: Include tree-ssa-threadedge.h and tree-ssa-address.h.
	* tree-ssa-loop.c: Include a few extra header files.
	* tree-vectorizer.h (lpeel_tree_duplicate_loop_to_edge_cfg): Prototype
	moved here.
	* tree.h: Adjust prototypes.
	* tree.c (mostly_copy_tree_r, copy_if_shared_r, copy_if_shared,
	unshare_body, unmark_visited_r, unmark_visited, unvisit_body, 
	unshare_expr, prune_expr_location, unshare_expr_without_location): 
	Relocate from gimplify.c.
	* gimple.c: (force_gimple_operand_gsi_1, force_gimple_operand_gsi):
	Relocate from gimplify.c.
	* gimple.h: Adjust prototypes.  Include gimplfy.h.
	(enum fallback, enum gimplify_status): Move to gimplify.h.
	* gimplify.h: New file.  Add prototypes.
	(enum fallback, enum gimplify_status): Relocate here.
	* gimplify.c (mostly_copy_tree_r, copy_if_shared_r, copy_if_shared,
	unshare_body, unmark_visited_r, unmark_visited, unvisit_body, 
	unshare_expr, prune_expr_location, unshare_expr_without_location): 
	Move to tree.c.
	(force_labels_r, rhs_predicate_for): Make static.

*** D/tree-flow.h	2013-10-03 13:14:02.939474204 -0400
--- tree-flow.h	2013-10-04 07:22:54.023641015 -0400
*************** extern void free_omp_regions (void);
*** 87,247 ****
  void omp_expand_local (basic_block);
  tree copy_var_decl (tree, tree, tree);
  
- /*---------------------------------------------------------------------------
- 			      Function prototypes
- ---------------------------------------------------------------------------*/
- /* In tree-cfg.c  */
- 
  /* Location to track pending stmt for edge insertion.  */
  #define PENDING_STMT(e)	((e)->insns.g)
  
! extern void delete_tree_cfg_annotations (void);
! extern bool stmt_ends_bb_p (gimple);
! extern bool is_ctrl_stmt (gimple);
! extern bool is_ctrl_altering_stmt (gimple);
! extern bool simple_goto_p (gimple);
! extern bool stmt_can_make_abnormal_goto (gimple);
  extern basic_block single_noncomplex_succ (basic_block bb);
! extern void gimple_dump_bb (FILE *, basic_block, int, int);
  extern void gimple_debug_bb (basic_block);
  extern basic_block gimple_debug_bb_n (int);
- extern void gimple_dump_cfg (FILE *, int);
  extern void gimple_debug_cfg (int);
  extern void dump_cfg_stats (FILE *);
- extern void dot_cfg (void);
  extern void debug_cfg_stats (void);
! extern void debug_loops (int);
! extern void debug_loop (struct loop *, int);
! extern void debug (struct loop &ref);
! extern void debug (struct loop *ptr);
! extern void debug_verbose (struct loop &ref);
! extern void debug_verbose (struct loop *ptr);
! extern void debug_loop_num (unsigned, int);
! extern void print_loops (FILE *, int);
! extern void print_loops_bb (FILE *, basic_block, int, int);
! extern void cleanup_dead_labels (void);
! extern void group_case_labels_stmt (gimple);
! extern void group_case_labels (void);
  extern gimple first_stmt (basic_block);
  extern gimple last_stmt (basic_block);
  extern gimple last_and_only_stmt (basic_block);
- extern edge find_taken_edge (basic_block, tree);
- extern basic_block label_to_block_fn (struct function *, tree);
- #define label_to_block(t) (label_to_block_fn (cfun, t))
- extern void notice_special_calls (gimple);
- extern void clear_special_calls (void);
  extern void verify_gimple_in_seq (gimple_seq);
  extern void verify_gimple_in_cfg (struct function *);
  extern tree gimple_block_label (basic_block);
! extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
  extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
  					basic_block *, bool);
  extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
  				      basic_block *);
  extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
  					  vec<basic_block> *bbs_p);
! extern void add_phi_args_after_copy_bb (basic_block);
! extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
  extern bool gimple_purge_dead_eh_edges (basic_block);
  extern bool gimple_purge_all_dead_eh_edges (const_bitmap);
  extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
  extern bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap);
- extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
- 			     tree, tree);
- extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,
- 			     tree, tree, tree);
  extern tree gimplify_build3 (gimple_stmt_iterator *, enum tree_code,
  			     tree, tree, tree, tree);
! extern void init_empty_tree_cfg (void);
! extern void init_empty_tree_cfg_for_function (struct function *);
! extern void fold_cond_expr_cond (void);
! extern void make_abnormal_goto_edges (basic_block, bool);
! extern void replace_uses_by (tree, tree);
! extern void start_recording_case_labels (void);
! extern void end_recording_case_labels (void);
! extern basic_block move_sese_region_to_fn (struct function *, basic_block,
! 				           basic_block, tree);
! void remove_edge_and_dominated_blocks (edge);
! bool tree_node_can_be_shared (tree);
! 
! 
! 
! /* In tree-ssa-loop*.c  */
! 
! unsigned tree_predictive_commoning (void);
! bool parallelize_loops (void);
! 
! bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple, bool);
! 
! enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
! enum ev_direction scev_direction (const_tree);
! 
! struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
! 
! /* In tree-ssa-threadedge.c */
! extern void threadedge_initialize_values (void);
! extern void threadedge_finalize_values (void);
! extern vec<tree> ssa_name_values;
! #define SSA_NAME_VALUE(x) \
!     (SSA_NAME_VERSION (x) < ssa_name_values.length () \
!      ? ssa_name_values[SSA_NAME_VERSION (x)] \
!      : NULL_TREE)
! extern void set_ssa_name_value (tree, tree);
! extern bool potentially_threadable_block (basic_block);
! extern void thread_across_edge (gimple, edge, bool,
! 				vec<tree> *, tree (*) (gimple, gimple));
! extern void propagate_threaded_block_debug_into (basic_block, basic_block);
! 
! /* In tree-loop-linear.c  */
! extern void linear_transform_loops (void);
! extern unsigned perfect_loop_nest_depth (struct loop *);
! 
! /* In graphite.c  */
! extern void graphite_transform_loops (void);
! 
! /* In tree-data-ref.c  */
! extern void tree_check_data_deps (void);
! 
! /* In gimplify.c  */
! tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
! tree force_gimple_operand (tree, gimple_seq *, bool, tree);
! tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
! 				 gimple_predicate, tree,
! 				 bool, enum gsi_iterator_update);
! tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
! 			       bool, enum gsi_iterator_update);
! tree gimple_fold_indirect_ref (tree);
! 
! /* In tree-ssa-live.c */
! extern void remove_unused_locals (void);
! extern void dump_scope_blocks (FILE *, int);
! extern void debug_scope_blocks (int);
! extern void debug_scope_block (tree, int);
! 
! /* In tree-ssa-address.c  */
! 
! /* Description of a memory address.  */
! 
! struct mem_address
! {
!   tree symbol, base, index, step, offset;
! };
! 
! struct affine_tree_combination;
! tree create_mem_ref (gimple_stmt_iterator *, tree,
! 		     struct affine_tree_combination *, tree, tree, tree, bool);
! rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
! void get_address_description (tree, struct mem_address *);
! tree maybe_fold_tmr (tree);
! 
! unsigned int execute_fixup_cfg (void);
! 
! /* In ipa-pure-const.c  */
! void warn_function_noreturn (tree);
! 
! /* In tree-parloops.c  */
! bool parallelized_function_p (tree);
  
- #include "tree-flow-inline.h"
  
  #endif /* _TREE_FLOW_H  */
--- 87,163 ----
  void omp_expand_local (basic_block);
  tree copy_var_decl (tree, tree, tree);
  
  /* Location to track pending stmt for edge insertion.  */
  #define PENDING_STMT(e)	((e)->insns.g)
  
! extern void init_empty_tree_cfg_for_function (struct function *);
! extern void init_empty_tree_cfg (void);
! extern void fold_cond_expr_cond (void);
! extern void start_recording_case_labels (void);
! extern void end_recording_case_labels (void);
! extern basic_block label_to_block_fn (struct function *, tree);
! #define label_to_block(t) (label_to_block_fn (cfun, t))
! extern void make_abnormal_goto_edges (basic_block, bool);
! extern void cleanup_dead_labels (void);
! extern void group_case_labels_stmt (gimple);
! extern void group_case_labels (void);
! extern void replace_uses_by (tree, tree);
  extern basic_block single_noncomplex_succ (basic_block bb);
! extern void notice_special_calls (gimple);
! extern void clear_special_calls (void);
! extern edge find_taken_edge (basic_block, tree);
  extern void gimple_debug_bb (basic_block);
  extern basic_block gimple_debug_bb_n (int);
  extern void gimple_debug_cfg (int);
+ extern void gimple_dump_cfg (FILE *, int);
  extern void dump_cfg_stats (FILE *);
  extern void debug_cfg_stats (void);
! extern bool stmt_can_make_abnormal_goto (gimple);
! extern bool is_ctrl_stmt (gimple);
! extern bool is_ctrl_altering_stmt (gimple);
! extern bool simple_goto_p (gimple);
! extern bool stmt_ends_bb_p (gimple);
! extern void delete_tree_cfg_annotations (void);
  extern gimple first_stmt (basic_block);
  extern gimple last_stmt (basic_block);
  extern gimple last_and_only_stmt (basic_block);
  extern void verify_gimple_in_seq (gimple_seq);
  extern void verify_gimple_in_cfg (struct function *);
  extern tree gimple_block_label (basic_block);
! extern void add_phi_args_after_copy_bb (basic_block);
! extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
  extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
  					basic_block *, bool);
  extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
  				      basic_block *);
  extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
  					  vec<basic_block> *bbs_p);
! extern basic_block move_sese_region_to_fn (struct function *, basic_block,
! 				           basic_block, tree);
! extern void dump_function_to_file (tree, FILE *, int);
! extern void debug_function (tree, int) ;
! extern void print_loops_bb (FILE *, basic_block, int, int);
! extern void print_loops (FILE *, int);
! extern void debug (struct loop &ref);
! extern void debug (struct loop *ptr);
! extern void debug_verbose (struct loop &ref);
! extern void debug_verbose (struct loop *ptr);
! extern void debug_loops (int);
! extern void debug_loop (struct loop *, int);
! extern void debug_loop_num (unsigned, int);
! void remove_edge_and_dominated_blocks (edge);
  extern bool gimple_purge_dead_eh_edges (basic_block);
  extern bool gimple_purge_all_dead_eh_edges (const_bitmap);
  extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
  extern bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap);
  extern tree gimplify_build3 (gimple_stmt_iterator *, enum tree_code,
  			     tree, tree, tree, tree);
! extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,
! 			     tree, tree, tree);
! extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
! 			     tree, tree);
! extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
! extern unsigned int execute_fixup_cfg (void);
  
  
  #endif /* _TREE_FLOW_H  */
*** D/tree-ssa-address.h	1969-12-31 19:00:00.000000000 -0500
--- tree-ssa-address.h	2013-10-03 18:29:14.239424576 -0400
***************
*** 0 ****
--- 1,32 ----
+ /* Header file for memory address lowering and mode selection.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ 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/>.  */
+ 
+ #ifndef GCC_TREE_SSA_ADDRESS_H
+ #define GCC_TREE_SSA_ADDRESS_H
+ 
+ extern rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
+ extern rtx addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand);
+ extern void get_address_description (tree, struct mem_address *);
+ extern tree tree_mem_ref_addr (tree, tree);
+ tree create_mem_ref (gimple_stmt_iterator *, tree,
+ 		     struct affine_tree_combination *, tree, tree, tree, bool);
+ extern void copy_ref_info (tree, tree);
+ tree maybe_fold_tmr (tree);
+ 
+ #endif /* GCC_TREE_SSA_ADDRESS_H */
*** D/tree-ssa-address.c	2013-10-03 13:14:02.942474203 -0400
--- tree-ssa-address.c	2013-10-03 19:35:41.994763595 -0400
*************** along with GCC; see the file COPYING3.
*** 42,47 ****
--- 42,48 ----
  #include "ggc.h"
  #include "target.h"
  #include "expmed.h"
+ #include "tree-ssa-address.h"
  
  /* TODO -- handling of symbols (according to Richard Hendersons
     comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
*************** gen_addr_rtx (enum machine_mode address_
*** 173,178 ****
--- 174,186 ----
      *addr = const0_rtx;
  }
  
+ /* Description of a memory address.  */
+ 
+ struct mem_address
+ {
+   tree symbol, base, index, step, offset;
+ };
+ 
  /* Returns address for TARGET_MEM_REF with parameters given by ADDR
     in address space AS.
     If REALLY_EXPAND is false, just make fake registers instead
*************** addr_for_mem_ref (struct mem_address *ad
*** 256,261 ****
--- 264,280 ----
    return address;
  }
  
+ /* implement addr_for_mem_ref() directly from a tree, which avoids exporting
+    the mem_address structure.  */
+ 
+ rtx
+ addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand)
+ {
+   struct mem_address addr;
+   get_address_description (exp, &addr);
+   return addr_for_mem_ref (&addr, as, really_expand);
+ }
+ 
  /* Returns address of MEM_REF in TYPE.  */
  
  tree
*** D/expr.c	2013-10-03 13:14:02.916474214 -0400
--- expr.c	2013-10-03 18:29:14.214424625 -0400
*************** expand_expr_real_1 (tree exp, rtx target
*** 9560,9571 ****
        {
  	addr_space_t as
  	  = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
- 	struct mem_address addr;
  	enum insn_code icode;
  	unsigned int align;
  
! 	get_address_description (exp, &addr);
! 	op0 = addr_for_mem_ref (&addr, as, true);
  	op0 = memory_address_addr_space (mode, op0, as);
  	temp = gen_rtx_MEM (mode, op0);
  	set_mem_attributes (temp, exp, 0);
--- 9560,9569 ----
        {
  	addr_space_t as
  	  = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
  	enum insn_code icode;
  	unsigned int align;
  
! 	op0 = addr_for_mem_ref (exp, as, true);
  	op0 = memory_address_addr_space (mode, op0, as);
  	temp = gen_rtx_MEM (mode, op0);
  	set_mem_attributes (temp, exp, 0);
*** D/tree-ssa-live.h	2013-10-03 13:14:02.943474203 -0400
--- tree-ssa-live.h	2013-10-04 07:22:27.857663100 -0400
*************** typedef struct _var_map
*** 70,81 ****
  
  extern var_map init_var_map (int);
  extern void delete_var_map (var_map);
- extern void dump_var_map (FILE *, var_map);
- extern void debug (_var_map &ref);
- extern void debug (_var_map *ptr);
  extern int var_union (var_map, tree, tree);
  extern void partition_view_normal (var_map, bool);
  extern void partition_view_bitmap (var_map, bitmap, bool);
  #ifdef ENABLE_CHECKING
  extern void register_ssa_partition_check (tree ssa_var);
  #endif
--- 70,85 ----
  
  extern var_map init_var_map (int);
  extern void delete_var_map (var_map);
  extern int var_union (var_map, tree, tree);
  extern void partition_view_normal (var_map, bool);
  extern void partition_view_bitmap (var_map, bitmap, bool);
+ extern void dump_scope_blocks (FILE *, int);
+ extern void debug_scope_block (tree, int);
+ extern void debug_scope_blocks (int);
+ extern void remove_unused_locals (void);
+ extern void dump_var_map (FILE *, var_map);
+ extern void debug (_var_map &ref);
+ extern void debug (_var_map *ptr);
  #ifdef ENABLE_CHECKING
  extern void register_ssa_partition_check (tree ssa_var);
  #endif
*************** typedef struct tree_live_info_d
*** 241,256 ****
  } *tree_live_info_p;
  
  
- extern tree_live_info_p calculate_live_ranges (var_map);
- extern void calculate_live_on_exit (tree_live_info_p);
- extern void delete_tree_live_info (tree_live_info_p);
- 
  #define LIVEDUMP_ENTRY	0x01
  #define LIVEDUMP_EXIT	0x02
  #define LIVEDUMP_ALL	(LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
! extern void dump_live_info (FILE *, tree_live_info_p, int);
  extern void debug (tree_live_info_d &ref);
  extern void debug (tree_live_info_d *ptr);
  
  
  /*  Return TRUE if P is marked as a global in LIVE.  */
--- 245,259 ----
  } *tree_live_info_p;
  
  
  #define LIVEDUMP_ENTRY	0x01
  #define LIVEDUMP_EXIT	0x02
  #define LIVEDUMP_ALL	(LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
! extern void delete_tree_live_info (tree_live_info_p);
! extern void calculate_live_on_exit (tree_live_info_p);
! extern tree_live_info_p calculate_live_ranges (var_map);
  extern void debug (tree_live_info_d &ref);
  extern void debug (tree_live_info_d *ptr);
+ extern void dump_live_info (FILE *, tree_live_info_p, int);
  
  
  /*  Return TRUE if P is marked as a global in LIVE.  */
*** D/passes.c	2013-10-03 13:14:02.931474208 -0400
--- passes.c	2013-10-04 08:06:49.476466844 -0400
*************** along with GCC; see the file COPYING3.
*** 72,77 ****
--- 72,78 ----
  #include "tree-pretty-print.h" /* for dump_function_header */
  #include "context.h"
  #include "pass_manager.h"
+ #include "tree-ssa-live.h"  /* For remove_unused_locals.  */
  
  using namespace gcc;
  
*** D/gimple-pretty-print.h	2013-10-03 13:14:02.922474212 -0400
--- gimple-pretty-print.h	2013-10-03 18:29:14.220424613 -0400
*************** extern void debug (gimple_statement_d &r
*** 33,38 ****
--- 33,39 ----
  extern void debug (gimple_statement_d *ptr);
  extern void print_gimple_expr (FILE *, gimple, int, int);
  extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int);
+ extern void gimple_dump_bb (FILE *, basic_block, int, int);
  extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block);
  
  #endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
*** D/graphite.h	1969-12-31 19:00:00.000000000 -0500
--- graphite.h	2013-10-03 18:29:14.221424611 -0400
***************
*** 0 ****
--- 1,25 ----
+ /* Header file for Gimple Represented as Polyhedra.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ 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/>.  */
+ 
+ #ifndef GCC_GRAPHITE_H
+ #define GCC_GRAPHITE_H
+ 
+ extern void graphite_transform_loops (void);
+ 
+ #endif /* GCC_GRAPHITE_H */
*** D/graphite.c	2013-10-03 13:14:02.923474211 -0400
--- graphite.c	2013-10-03 18:29:14.221424611 -0400
*************** along with GCC; see the file COPYING3.
*** 55,60 ****
--- 55,61 ----
  #include "tree-scalar-evolution.h"
  #include "sese.h"
  #include "dbgcnt.h"
+ #include "graphite.h"
  
  #ifdef HAVE_cloog
  
*** D/ipa-pure-const.c	2013-10-03 13:14:02.925474210 -0400
--- ipa-pure-const.c	2013-10-04 09:55:58.669276341 -0400
*************** warn_function_const (tree decl, bool kno
*** 179,185 ****
  			 known_finite, warned_about, "const");
  }
  
! void
  warn_function_noreturn (tree decl)
  {
    static struct pointer_set_t *warned_about;
--- 179,185 ----
  			 known_finite, warned_about, "const");
  }
  
! static void
  warn_function_noreturn (tree decl)
  {
    static struct pointer_set_t *warned_about;
*************** make_pass_local_pure_const (gcc::context
*** 1722,1724 ****
--- 1722,1781 ----
  {
    return new pass_local_pure_const (ctxt);
  }
+ 
+ /* Emit noreturn warnings.  */
+ 
+ static unsigned int
+ execute_warn_function_noreturn (void)
+ {
+   if (!TREE_THIS_VOLATILE (current_function_decl)
+       && EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
+     warn_function_noreturn (current_function_decl);
+   return 0;
+ }
+ 
+ static bool
+ gate_warn_function_noreturn (void)
+ {
+   return warn_suggest_attribute_noreturn;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_warn_function_noreturn =
+ {
+   GIMPLE_PASS, /* type */
+   "*warn_function_noreturn", /* name */
+   OPTGROUP_NONE, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_NONE, /* tv_id */
+   PROP_cfg, /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_warn_function_noreturn : public gimple_opt_pass
+ {
+ public:
+   pass_warn_function_noreturn (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   bool gate () { return gate_warn_function_noreturn (); }
+   unsigned int execute () { return execute_warn_function_noreturn (); }
+ 
+ }; // class pass_warn_function_noreturn
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_warn_function_noreturn (gcc::context *ctxt)
+ {
+   return new pass_warn_function_noreturn (ctxt);
+ }
+ 
+ 
*** D/tree-cfg.c	2013-10-03 13:14:02.938474205 -0400
--- tree-cfg.c	2013-10-04 09:55:59.655276727 -0400
*************** along with GCC; see the file COPYING3.
*** 41,46 ****
--- 41,47 ----
  #include "pointer-set.h"
  #include "tree-inline.h"
  #include "target.h"
+ #include "tree-ssa-live.h"
  
  /* This file contains functions for building the Control Flow Graph (CFG)
     for a function tree.  */
*************** verify_gimple_in_seq (gimple_seq stmts)
*** 4449,4455 ****
  
  /* Return true when the T can be shared.  */
  
! bool
  tree_node_can_be_shared (tree t)
  {
    if (IS_TYPE_OR_DECL_P (t)
--- 4450,4456 ----
  
  /* Return true when the T can be shared.  */
  
! static bool
  tree_node_can_be_shared (tree t)
  {
    if (IS_TYPE_OR_DECL_P (t)
*************** gimple_move_block_after (basic_block bb,
*** 5459,5465 ****
  /* Return TRUE if block BB has no executable statements, otherwise return
     FALSE.  */
  
! bool
  gimple_empty_block_p (basic_block bb)
  {
    /* BB must have no executable statements.  */
--- 5460,5466 ----
  /* Return TRUE if block BB has no executable statements, otherwise return
     FALSE.  */
  
! static bool
  gimple_empty_block_p (basic_block bb)
  {
    /* BB must have no executable statements.  */
*************** make_pass_warn_function_return (gcc::con
*** 8106,8167 ****
    return new pass_warn_function_return (ctxt);
  }
  
- /* Emit noreturn warnings.  */
- 
- static unsigned int
- execute_warn_function_noreturn (void)
- {
-   if (!TREE_THIS_VOLATILE (current_function_decl)
-       && EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0)
-     warn_function_noreturn (current_function_decl);
-   return 0;
- }
- 
- static bool
- gate_warn_function_noreturn (void)
- {
-   return warn_suggest_attribute_noreturn;
- }
- 
- namespace {
- 
- const pass_data pass_data_warn_function_noreturn =
- {
-   GIMPLE_PASS, /* type */
-   "*warn_function_noreturn", /* name */
-   OPTGROUP_NONE, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_NONE, /* tv_id */
-   PROP_cfg, /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_warn_function_noreturn : public gimple_opt_pass
- {
- public:
-   pass_warn_function_noreturn (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_warn_function_noreturn, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   bool gate () { return gate_warn_function_noreturn (); }
-   unsigned int execute () { return execute_warn_function_noreturn (); }
- 
- }; // class pass_warn_function_noreturn
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_warn_function_noreturn (gcc::context *ctxt)
- {
-   return new pass_warn_function_noreturn (ctxt);
- }
- 
- 
  /* Walk a gimplified function and warn for functions whose return value is
     ignored and attribute((warn_unused_result)) is set.  This is done before
     inlining, so we don't have to worry about that.  */
--- 8107,8112 ----
*************** make_pass_warn_unused_result (gcc::conte
*** 8278,8283 ****
--- 8223,8368 ----
    return new pass_warn_unused_result (ctxt);
  }
  
+ /* IPA passes, compilation of earlier functions or inlining
+    might have changed some properties, such as marked functions nothrow,
+    pure, const or noreturn.
+    Remove redundant edges and basic blocks, and create new ones if necessary.
+ 
+    This pass can't be executed as stand alone pass from pass manager, because
+    in between inlining and this fixup the verify_flow_info would fail.  */
+ 
+ unsigned int
+ execute_fixup_cfg (void)
+ {
+   basic_block bb;
+   gimple_stmt_iterator gsi;
+   int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
+   gcov_type count_scale;
+   edge e;
+   edge_iterator ei;
+ 
+   count_scale
+       = GCOV_COMPUTE_SCALE (cgraph_get_node (current_function_decl)->count,
+                             ENTRY_BLOCK_PTR->count);
+ 
+   ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
+   EXIT_BLOCK_PTR->count = apply_scale (EXIT_BLOCK_PTR->count,
+                                        count_scale);
+ 
+   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
+     e->count = apply_scale (e->count, count_scale);
+ 
+   FOR_EACH_BB (bb)
+     {
+       bb->count = apply_scale (bb->count, count_scale);
+       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ 	{
+ 	  gimple stmt = gsi_stmt (gsi);
+ 	  tree decl = is_gimple_call (stmt)
+ 		      ? gimple_call_fndecl (stmt)
+ 		      : NULL;
+ 	  if (decl)
+ 	    {
+ 	      int flags = gimple_call_flags (stmt);
+ 	      if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
+ 		{
+ 		  if (gimple_purge_dead_abnormal_call_edges (bb))
+ 		    todo |= TODO_cleanup_cfg;
+ 
+ 		  if (gimple_in_ssa_p (cfun))
+ 		    {
+ 		      todo |= TODO_update_ssa | TODO_cleanup_cfg;
+ 		      update_stmt (stmt);
+ 		    }
+ 		}
+ 
+ 	      if (flags & ECF_NORETURN
+ 		  && fixup_noreturn_call (stmt))
+ 		todo |= TODO_cleanup_cfg;
+ 	     }
+ 
+ 	  if (maybe_clean_eh_stmt (stmt)
+ 	      && gimple_purge_dead_eh_edges (bb))
+ 	    todo |= TODO_cleanup_cfg;
+ 	}
+ 
+       FOR_EACH_EDGE (e, ei, bb->succs)
+         e->count = apply_scale (e->count, count_scale);
+ 
+       /* If we have a basic block with no successors that does not
+ 	 end with a control statement or a noreturn call end it with
+ 	 a call to __builtin_unreachable.  This situation can occur
+ 	 when inlining a noreturn call that does in fact return.  */
+       if (EDGE_COUNT (bb->succs) == 0)
+ 	{
+ 	  gimple stmt = last_stmt (bb);
+ 	  if (!stmt
+ 	      || (!is_ctrl_stmt (stmt)
+ 		  && (!is_gimple_call (stmt)
+ 		      || (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
+ 	    {
+ 	      stmt = gimple_build_call
+ 		  (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
+ 	      gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ 	      gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ 	    }
+ 	}
+     }
+   if (count_scale != REG_BR_PROB_BASE)
+     compute_function_frequency ();
+ 
+   /* We just processed all calls.  */
+   if (cfun->gimple_df)
+     vec_free (MODIFIED_NORETURN_CALLS (cfun));
+ 
+   /* Dump a textual representation of the flowgraph.  */
+   if (dump_file)
+     gimple_dump_cfg (dump_file, dump_flags);
+ 
+   if (current_loops
+       && (todo & TODO_cleanup_cfg))
+     loops_state_set (LOOPS_NEED_FIXUP);
+ 
+   return todo;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_fixup_cfg =
+ {
+   GIMPLE_PASS, /* type */
+   "*free_cfg_annotations", /* name */
+   OPTGROUP_NONE, /* optinfo_flags */
+   false, /* has_gate */
+   true, /* has_execute */
+   TV_NONE, /* tv_id */
+   PROP_cfg, /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_fixup_cfg : public gimple_opt_pass
+ {
+ public:
+   pass_fixup_cfg (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_fixup_cfg, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   opt_pass * clone () { return new pass_fixup_cfg (m_ctxt); }
+   unsigned int execute () { return execute_fixup_cfg (); }
+ 
+ }; // class pass_fixup_cfg
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_fixup_cfg (gcc::context *ctxt)
+ {
+   return new pass_fixup_cfg (ctxt);
+ }
  
  /* Garbage collection support for edge_def.  */
  
*** D/tree-optimize.c	2013-10-03 13:14:02.941474203 -0400
--- tree-optimize.c	2013-10-03 18:30:33.664269125 -0400
*************** make_pass_cleanup_cfg_post_optimizing (g
*** 127,269 ****
    return new pass_cleanup_cfg_post_optimizing (ctxt);
  }
  
- /* IPA passes, compilation of earlier functions or inlining
-    might have changed some properties, such as marked functions nothrow,
-    pure, const or noreturn.
-    Remove redundant edges and basic blocks, and create new ones if necessary.
  
-    This pass can't be executed as stand alone pass from pass manager, because
-    in between inlining and this fixup the verify_flow_info would fail.  */
- 
- unsigned int
- execute_fixup_cfg (void)
- {
-   basic_block bb;
-   gimple_stmt_iterator gsi;
-   int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
-   gcov_type count_scale;
-   edge e;
-   edge_iterator ei;
- 
-   count_scale
-       = GCOV_COMPUTE_SCALE (cgraph_get_node (current_function_decl)->count,
-                             ENTRY_BLOCK_PTR->count);
- 
-   ENTRY_BLOCK_PTR->count = cgraph_get_node (current_function_decl)->count;
-   EXIT_BLOCK_PTR->count = apply_scale (EXIT_BLOCK_PTR->count,
-                                        count_scale);
- 
-   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
-     e->count = apply_scale (e->count, count_scale);
- 
-   FOR_EACH_BB (bb)
-     {
-       bb->count = apply_scale (bb->count, count_scale);
-       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- 	{
- 	  gimple stmt = gsi_stmt (gsi);
- 	  tree decl = is_gimple_call (stmt)
- 		      ? gimple_call_fndecl (stmt)
- 		      : NULL;
- 	  if (decl)
- 	    {
- 	      int flags = gimple_call_flags (stmt);
- 	      if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
- 		{
- 		  if (gimple_purge_dead_abnormal_call_edges (bb))
- 		    todo |= TODO_cleanup_cfg;
- 
- 		  if (gimple_in_ssa_p (cfun))
- 		    {
- 		      todo |= TODO_update_ssa | TODO_cleanup_cfg;
- 		      update_stmt (stmt);
- 		    }
- 		}
- 
- 	      if (flags & ECF_NORETURN
- 		  && fixup_noreturn_call (stmt))
- 		todo |= TODO_cleanup_cfg;
- 	     }
- 
- 	  if (maybe_clean_eh_stmt (stmt)
- 	      && gimple_purge_dead_eh_edges (bb))
- 	    todo |= TODO_cleanup_cfg;
- 	}
- 
-       FOR_EACH_EDGE (e, ei, bb->succs)
-         e->count = apply_scale (e->count, count_scale);
- 
-       /* If we have a basic block with no successors that does not
- 	 end with a control statement or a noreturn call end it with
- 	 a call to __builtin_unreachable.  This situation can occur
- 	 when inlining a noreturn call that does in fact return.  */
-       if (EDGE_COUNT (bb->succs) == 0)
- 	{
- 	  gimple stmt = last_stmt (bb);
- 	  if (!stmt
- 	      || (!is_ctrl_stmt (stmt)
- 		  && (!is_gimple_call (stmt)
- 		      || (gimple_call_flags (stmt) & ECF_NORETURN) == 0)))
- 	    {
- 	      stmt = gimple_build_call
- 		  (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
- 	      gimple_stmt_iterator gsi = gsi_last_bb (bb);
- 	      gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- 	    }
- 	}
-     }
-   if (count_scale != REG_BR_PROB_BASE)
-     compute_function_frequency ();
- 
-   /* We just processed all calls.  */
-   if (cfun->gimple_df)
-     vec_free (MODIFIED_NORETURN_CALLS (cfun));
- 
-   /* Dump a textual representation of the flowgraph.  */
-   if (dump_file)
-     gimple_dump_cfg (dump_file, dump_flags);
- 
-   if (current_loops
-       && (todo & TODO_cleanup_cfg))
-     loops_state_set (LOOPS_NEED_FIXUP);
- 
-   return todo;
- }
- 
- namespace {
- 
- const pass_data pass_data_fixup_cfg =
- {
-   GIMPLE_PASS, /* type */
-   "*free_cfg_annotations", /* name */
-   OPTGROUP_NONE, /* optinfo_flags */
-   false, /* has_gate */
-   true, /* has_execute */
-   TV_NONE, /* tv_id */
-   PROP_cfg, /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_fixup_cfg : public gimple_opt_pass
- {
- public:
-   pass_fixup_cfg (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_fixup_cfg, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   opt_pass * clone () { return new pass_fixup_cfg (m_ctxt); }
-   unsigned int execute () { return execute_fixup_cfg (); }
- 
- }; // class pass_fixup_cfg
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_fixup_cfg (gcc::context *ctxt)
- {
-   return new pass_fixup_cfg (ctxt);
- }
--- 127,130 ----
*** D/tree-chrec.h	2013-10-03 13:14:02.938474205 -0400
--- tree-chrec.h	2013-10-04 12:28:13.473741616 -0400
*************** tree_is_chrec (const_tree expr)
*** 52,57 ****
--- 52,59 ----
  }
  
  
+ enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
+ enum ev_direction scev_direction (const_tree);
  
  /* Chrec folding functions.  */
  extern tree chrec_fold_plus (tree, tree, tree);
*************** extern tree hide_evolution_in_other_loop
*** 72,77 ****
--- 74,81 ----
  extern tree reset_evolution_in_loop (unsigned, tree, tree);
  extern tree chrec_merge (tree, tree);
  extern void for_each_scev_op (tree *, bool (*) (tree *, void *), void *);
+ extern bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple,
+ 				 bool);
  
  /* Observers.  */
  extern bool eq_evolutions_p (const_tree, const_tree);
*** D/tree-data-ref.h	2013-10-03 13:14:02.939474204 -0400
--- tree-data-ref.h	2013-10-03 18:29:14.236424582 -0400
*************** extern bool dr_may_alias_p (const struct
*** 406,411 ****
--- 406,412 ----
  			    const struct data_reference *, bool);
  extern bool dr_equal_offsets_p (struct data_reference *,
                                  struct data_reference *);
+ extern void tree_check_data_deps (void);
  
  
  /* Return true when the base objects of data references A and B are
*** D/tree-dump.c	2013-10-03 13:14:02.939474204 -0400
--- tree-dump.c	2013-10-03 18:29:14.236424582 -0400
*************** along with GCC; see the file COPYING3.
*** 29,34 ****
--- 29,35 ----
  #include "langhooks.h"
  #include "tree-iterator.h"
  #include "tree-pretty-print.h"
+ #include "tree-flow.h"
  
  static unsigned int queue (dump_info_p, const_tree, int);
  static void dump_index (dump_info_p, unsigned int);
*** D/tree-dump.h	2013-10-03 13:14:02.939474204 -0400
--- tree-dump.h	2013-10-03 18:29:14.236424582 -0400
*************** extern void queue_and_dump_type (dump_in
*** 90,96 ****
  extern void dump_function (int, tree);
  extern int dump_flag (dump_info_p, int, const_tree);
  
- /* In tree-cfg.c  */
- extern void dump_function_to_file (tree, FILE *, int);
- 
  #endif /* ! GCC_TREE_DUMP_H */
--- 90,93 ----
*** D/tree-parloops.h	1969-12-31 19:00:00.000000000 -0500
--- tree-parloops.h	2013-10-03 18:29:14.238424577 -0400
***************
*** 0 ****
--- 1,26 ----
+ /* Header file for loop autoparallelization.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ 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/>.  */
+ 
+ #ifndef GCC_TREE_PARLOOPS_H
+ #define GCC_TREE_PARLOOPS_H
+ 
+ extern bool parallelized_function_p (tree);
+ extern bool parallelize_loops (void);
+ 
+ #endif /* GCC_TREE_PARLOOPS_H */
*** D/tree-parloops.c	2013-10-03 13:14:02.941474203 -0400
--- tree-parloops.c	2013-10-03 18:29:14.238424577 -0400
*************** along with GCC; see the file COPYING3.
*** 31,36 ****
--- 31,37 ----
  #include "langhooks.h"
  #include "tree-vectorizer.h"
  #include "tree-hasher.h"
+ #include "tree-parloops.h"
  
  /* This pass tries to distribute iterations of loops into several threads.
     The implementation is straightforward -- for each loop we test whether its
*** D/tree-predcom.c	2013-10-03 13:14:02.941474203 -0400
--- tree-predcom.c	2013-10-03 18:29:14.238424577 -0400
*************** along with GCC; see the file COPYING3.
*** 201,206 ****
--- 201,207 ----
  #include "tree-pass.h"
  #include "tree-affine.h"
  #include "tree-inline.h"
+ #include "tree-predcom.h"
  
  /* The maximum number of iterations between the considered memory
     references.  */
*** D/tree-predcom.h	1969-12-31 19:00:00.000000000 -0500
--- tree-predcom.h	2013-10-03 18:29:14.238424577 -0400
***************
*** 0 ****
--- 1,25 ----
+ /* Header file for predictive commoning.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ 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/>.  */
+ 
+ #ifndef GCC_TREE_PREDCOM_H
+ #define GCC_TREE_PREDCOM_H
+ 
+ unsigned tree_predictive_commoning (void);
+ 
+ #endif /* GCC_TREE_PREDCOM_H */
*** D/tree-ssa-dom.c	2013-10-03 13:14:02.943474203 -0400
--- tree-ssa-dom.c	2013-10-03 18:29:14.239424576 -0400
*************** tree_ssa_dominator_optimize (void)
*** 902,908 ****
  
    /* Free the value-handle array.  */
    threadedge_finalize_values ();
-   ssa_name_values.release ();
  
    return 0;
  }
--- 902,907 ----
*** D/tree-ssa-threadedge.h	1969-12-31 19:00:00.000000000 -0500
--- tree-ssa-threadedge.h	2013-10-03 18:29:14.242424570 -0400
***************
*** 0 ****
--- 1,36 ----
+ /* Header file for SSA jump threading.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ 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/>.  */
+ 
+ #ifndef GCC_TREE_SSA_THREADEDGE_H
+ #define GCC_TREE_SSA_THREADEDGE_H
+ 
+ extern vec<tree> ssa_name_values;
+ #define SSA_NAME_VALUE(x) \
+     (SSA_NAME_VERSION (x) < ssa_name_values.length () \
+      ? ssa_name_values[SSA_NAME_VERSION (x)] \
+      : NULL_TREE)
+ extern void set_ssa_name_value (tree, tree);
+ extern void threadedge_initialize_values (void);
+ extern void threadedge_finalize_values (void);
+ extern bool potentially_threadable_block (basic_block);
+ extern void propagate_threaded_block_debug_into (basic_block, basic_block);
+ extern void thread_across_edge (gimple, edge, bool,
+ 				vec<tree> *, tree (*) (gimple, gimple));
+ 
+ #endif /* GCC_TREE_SSA_THREADEDGE_H */
*** D/tree-ssa.h	2013-10-03 13:14:02.943474203 -0400
--- tree-ssa.h	2013-10-03 18:29:14.239424576 -0400
*************** along with GCC; see the file COPYING3.
*** 28,33 ****
--- 28,35 ----
  #include "tree-ssanames.h"
  #include "tree-ssa-dom.h"
  #include "tree-flow.h"
+ #include "tree-ssa-threadedge.h"
+ #include "tree-ssa-address.h"
  
  /* Mapping for redirected edges.  */
  struct _edge_var_map {
*** D/tree-ssa-loop.c	2013-10-03 13:14:02.943474203 -0400
--- tree-ssa-loop.c	2013-10-03 18:29:14.240424574 -0400
*************** along with GCC; see the file COPYING3.
*** 34,39 ****
--- 34,43 ----
  #include "tree-vectorizer.h"
  #include "tree-ssa-loop-prefetch.h"
  #include "tree-ssa-loop-unswitch.h"
+ #include "tree-predcom.h"
+ #include "tree-parloops.h"
+ #include "graphite.h"
+ #include "tree-data-ref.h"
  
  /* The loop superpass.  */
  
*** D/tree-vectorizer.h	2013-10-03 13:14:02.947474201 -0400
--- tree-vectorizer.h	2013-10-03 18:29:14.243424568 -0400
*************** extern LOC vect_location;
*** 899,904 ****
--- 899,905 ----
     in tree-vect-loop-manip.c.  */
  extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
  extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
+ struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
  extern void vect_loop_versioning (loop_vec_info, unsigned int, bool);
  extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *,
  					    unsigned int, bool);
*** D/tree.h	2013-10-03 13:14:02.940474204 -0400
--- tree.h	2013-10-03 18:29:14.237424579 -0400
*************** extern void cache_integer_cst (tree);
*** 4203,4212 ****
  /* In cgraph.c */
  extern void change_decl_assembler_name (tree, tree);
  
- /* In gimplify.c */
- extern tree unshare_expr (tree);
- extern tree unshare_expr_without_location (tree);
- 
  /* In stmt.c */
  
  extern void expand_label (tree);
--- 4203,4208 ----
*************** extern bool block_may_fallthru (const_tr
*** 4525,4530 ****
--- 4521,4531 ----
  extern void using_eh_for_cleanups (void);
  extern bool using_eh_for_cleanups_p (void);
  
+ extern tree unshare_expr (tree);
+ extern tree unshare_expr_without_location (tree);
+ extern void unvisit_body (tree);
+ extern void unshare_body (tree);
+ 
  /* In tree-nested.c */
  extern tree build_addr (tree, tree);
  
*************** extern void set_decl_incoming_rtl (tree,
*** 4709,4715 ****
  
  /* In gimple.c.  */
  extern tree get_base_address (tree t);
- extern void mark_addressable (tree);
  
  /* In tree.c.  */
  extern int tree_map_base_eq (const void *, const void *);
--- 4710,4715 ----
*************** extern unsigned int tree_decl_map_hash (
*** 4737,4746 ****
  #define tree_vec_map_hash tree_decl_map_hash
  #define tree_vec_map_marked_p tree_map_base_marked_p
  
- /* In tree-ssa-address.c.  */
- extern tree tree_mem_ref_addr (tree, tree);
- extern void copy_ref_info (tree, tree);
- 
  /* In tree-vrp.c */
  extern bool ssa_name_nonnegative_p (const_tree);
  
--- 4737,4742 ----
*** D/tree.c	2013-10-03 13:14:02.938474205 -0400
--- tree.c	2013-10-03 18:29:14.235424583 -0400
*************** walk_tree_without_duplicates_1 (tree *tp
*** 11219,11225 ****
--- 11219,11454 ----
    pointer_set_destroy (pset);
    return result;
  }
+ 
+ /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
+    nodes that are referenced more than once in GENERIC functions.  This is
+    necessary because gimplification (translation into GIMPLE) is performed
+    by modifying tree nodes in-place, so gimplication of a shared node in a
+    first context could generate an invalid GIMPLE form in a second context.
  
+    This is achieved with a simple mark/copy/unmark algorithm that walks the
+    GENERIC representation top-down, marks nodes with TREE_VISITED the first
+    time it encounters them, duplicates them if they already have TREE_VISITED
+    set, and finally removes the TREE_VISITED marks it has set.
+ 
+    The algorithm works only at the function level, i.e. it generates a GENERIC
+    representation of a function with no nodes shared within the function when
+    passed a GENERIC function (except for nodes that are allowed to be shared).
+ 
+    At the global level, it is also necessary to unshare tree nodes that are
+    referenced in more than one function, for the same aforementioned reason.
+    This requires some cooperation from the front-end.  There are 2 strategies:
+ 
+      1. Manual unsharing.  The front-end needs to call unshare_expr on every
+         expression that might end up being shared across functions.
+ 
+      2. Deep unsharing.  This is an extension of regular unsharing.  Instead
+         of calling unshare_expr on expressions that might be shared across
+         functions, the front-end pre-marks them with TREE_VISITED.  This will
+         ensure that they are unshared on the first reference within functions
+         when the regular unsharing algorithm runs.  The counterpart is that
+         this algorithm must look deeper than for manual unsharing, which is
+         specified by LANG_HOOKS_DEEP_UNSHARING.
+ 
+   If there are only few specific cases of node sharing across functions, it is
+   probably easier for a front-end to unshare the expressions manually.  On the
+   contrary, if the expressions generated at the global level are as widespread
+   as expressions generated within functions, deep unsharing is very likely the
+   way to go.  */
+ 
+ /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
+    These nodes model computations that must be done once.  If we were to
+    unshare something like SAVE_EXPR(i++), the gimplification process would
+    create wrong code.  However, if DATA is non-null, it must hold a pointer
+    set that is used to unshare the subtrees of these nodes.  */
+ 
+ static tree
+ mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
+ {
+   tree t = *tp;
+   enum tree_code code = TREE_CODE (t);
+ 
+   /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
+      copy their subtrees if we can make sure to do it only once.  */
+   if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
+     {
+       if (data && !pointer_set_insert ((struct pointer_set_t *)data, t))
+ 	;
+       else
+ 	*walk_subtrees = 0;
+     }
+ 
+   /* Stop at types, decls, constants like copy_tree_r.  */
+   else if (TREE_CODE_CLASS (code) == tcc_type
+ 	   || TREE_CODE_CLASS (code) == tcc_declaration
+ 	   || TREE_CODE_CLASS (code) == tcc_constant
+ 	   /* We can't do anything sensible with a BLOCK used as an
+ 	      expression, but we also can't just die when we see it
+ 	      because of non-expression uses.  So we avert our eyes
+ 	      and cross our fingers.  Silly Java.  */
+ 	   || code == BLOCK)
+     *walk_subtrees = 0;
+ 
+   /* Cope with the statement expression extension.  */
+   else if (code == STATEMENT_LIST)
+     ;
+ 
+   /* Leave the bulk of the work to copy_tree_r itself.  */
+   else
+     copy_tree_r (tp, walk_subtrees, NULL);
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
+    If *TP has been visited already, then *TP is deeply copied by calling
+    mostly_copy_tree_r.  DATA is passed to mostly_copy_tree_r unmodified.  */
+ 
+ static tree
+ copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
+ {
+   tree t = *tp;
+   enum tree_code code = TREE_CODE (t);
+ 
+   /* Skip types, decls, and constants.  But we do want to look at their
+      types and the bounds of types.  Mark them as visited so we properly
+      unmark their subtrees on the unmark pass.  If we've already seen them,
+      don't look down further.  */
+   if (TREE_CODE_CLASS (code) == tcc_type
+       || TREE_CODE_CLASS (code) == tcc_declaration
+       || TREE_CODE_CLASS (code) == tcc_constant)
+     {
+       if (TREE_VISITED (t))
+ 	*walk_subtrees = 0;
+       else
+ 	TREE_VISITED (t) = 1;
+     }
+ 
+   /* If this node has been visited already, unshare it and don't look
+      any deeper.  */
+   else if (TREE_VISITED (t))
+     {
+       walk_tree (tp, mostly_copy_tree_r, data, NULL);
+       *walk_subtrees = 0;
+     }
+ 
+   /* Otherwise, mark the node as visited and keep looking.  */
+   else
+     TREE_VISITED (t) = 1;
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Unshare most of the shared trees rooted at *TP.  DATA is passed to the
+    copy_if_shared_r callback unmodified.  */
+ 
+ static inline void
+ copy_if_shared (tree *tp, void *data)
+ {
+   walk_tree (tp, copy_if_shared_r, data, NULL);
+ }
+ 
+ /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
+    any nested functions.  */
+ 
+ void
+ unshare_body (tree fndecl)
+ {
+   struct cgraph_node *cgn = cgraph_get_node (fndecl);
+   /* If the language requires deep unsharing, we need a pointer set to make
+      sure we don't repeatedly unshare subtrees of unshareable nodes.  */
+   struct pointer_set_t *visited
+     = lang_hooks.deep_unsharing ? pointer_set_create () : NULL;
+ 
+   copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
+   copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
+   copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
+ 
+   if (visited)
+     pointer_set_destroy (visited);
+ 
+   if (cgn)
+     for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+       unshare_body (cgn->symbol.decl);
+ }
+ 
+ /* Callback for walk_tree to unmark the visited trees rooted at *TP.
+    Subtrees are walked until the first unvisited node is encountered.  */
+ 
+ static tree
+ unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+ {
+   tree t = *tp;
+ 
+   /* If this node has been visited, unmark it and keep looking.  */
+   if (TREE_VISITED (t))
+     TREE_VISITED (t) = 0;
+ 
+   /* Otherwise, don't look any deeper.  */
+   else
+     *walk_subtrees = 0;
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Unmark the visited trees rooted at *TP.  */
+ 
+ static inline void
+ unmark_visited (tree *tp)
+ {
+   walk_tree (tp, unmark_visited_r, NULL, NULL);
+ }
+ 
+ /* Likewise, but mark all trees as not visited.  */
+ 
+ void
+ unvisit_body (tree fndecl)
+ {
+   struct cgraph_node *cgn = cgraph_get_node (fndecl);
+ 
+   unmark_visited (&DECL_SAVED_TREE (fndecl));
+   unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
+   unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
+ 
+   if (cgn)
+     for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+       unvisit_body (cgn->symbol.decl);
+ }
+ 
+ /* Unconditionally make an unshared copy of EXPR.  This is used when using
+    stored expressions which span multiple functions, such as BINFO_VTABLE,
+    as the normal unsharing process can't tell that they're shared.  */
+ 
+ tree
+ unshare_expr (tree expr)
+ {
+   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
+   return expr;
+ }
+ 
+ /* Worker for unshare_expr_without_location.  */
+ 
+ static tree
+ prune_expr_location (tree *tp, int *walk_subtrees, void *)
+ {
+   if (EXPR_P (*tp))
+     SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
+   else
+     *walk_subtrees = 0;
+   return NULL_TREE;
+ }
+ 
+ /* Similar to unshare_expr but also prune all expression locations
+    from EXPR.  */
+ 
+ tree
+ unshare_expr_without_location (tree expr)
+ {
+   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
+   if (EXPR_P (expr))
+     walk_tree (&expr, prune_expr_location, NULL, NULL);
+   return expr;
+ }
  
  tree
  tree_block (tree t)
*** D/gimple.c	2013-10-03 13:14:02.921474212 -0400
--- gimple.c	2013-10-03 18:29:14.219424615 -0400
*************** nonfreeing_call_p (gimple call)
*** 4441,4444 ****
--- 4441,4491 ----
    return false;
  }
  
+ /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
+    and VAR.  If some statements are produced, emits them at GSI.
+    If BEFORE is true.  the statements are appended before GSI, otherwise
+    they are appended after it.  M specifies the way GSI moves after
+    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
+ 
+ tree
+ force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
+ 			    gimple_predicate gimple_test_f,
+ 			    tree var, bool before,
+ 			    enum gsi_iterator_update m)
+ {
+   gimple_seq stmts;
+ 
+   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
+ 
+   if (!gimple_seq_empty_p (stmts))
+     {
+       if (before)
+ 	gsi_insert_seq_before (gsi, stmts, m);
+       else
+ 	gsi_insert_seq_after (gsi, stmts, m);
+     }
+ 
+   return expr;
+ }
+ 
+ /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
+    If SIMPLE is true, force the result to be either ssa_name or an invariant,
+    otherwise just force it to be a rhs expression.  If some statements are
+    produced, emits them at GSI.  If BEFORE is true, the statements are
+    appended before GSI, otherwise they are appended after it.  M specifies
+    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
+    are the usual values).  */
+ 
+ tree
+ force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
+ 			  bool simple_p, tree var, bool before,
+ 			  enum gsi_iterator_update m)
+ {
+   return force_gimple_operand_gsi_1 (gsi, expr,
+ 				     simple_p
+ 				     ? is_gimple_val : is_gimple_reg_rhs,
+ 				     var, before, m);
+ }
+ 
+ 
  #include "gt-gimple.h"
*** D/gimple.h	2013-10-03 13:14:02.922474212 -0400
--- gimple.h	2013-10-03 18:29:14.220424613 -0400
*************** along with GCC; see the file COPYING3.
*** 32,37 ****
--- 32,38 ----
  #include "internal-fn.h"
  #include "gimple-fold.h"
  #include "tree-eh.h"
+ #include "gimplify.h"
  
  typedef gimple gimple_seq_node;
  
*************** gimple gimple_build_omp_atomic_store (tr
*** 797,804 ****
  gimple gimple_build_transaction (gimple_seq, tree);
  gimple gimple_build_predict (enum br_predictor, enum prediction);
  enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
- void sort_case_labels (vec<tree> );
- void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
  void gimple_set_body (tree, gimple_seq);
  gimple_seq gimple_body (tree);
  bool gimple_has_body_p (tree);
--- 798,803 ----
*************** bool gimple_has_side_effects (const_gimp
*** 829,835 ****
  bool gimple_could_trap_p (gimple);
  bool gimple_could_trap_p_1 (gimple, bool, bool);
  bool gimple_assign_rhs_could_trap_p (gimple);
- void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
  bool empty_body_p (gimple_seq);
  unsigned get_gimple_rhs_num_ops (enum tree_code);
  #define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
--- 828,833 ----
*************** extern bool gimple_asm_clobbers_memory_p
*** 900,944 ****
  extern bool useless_type_conversion_p (tree, tree);
  extern bool types_compatible_p (tree, tree);
  
- /* In gimplify.c  */
- extern tree create_tmp_var_raw (tree, const char *);
- extern tree create_tmp_var_name (const char *);
- extern tree create_tmp_var (tree, const char *);
- extern tree create_tmp_reg (tree, const char *);
- extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
- extern tree get_formal_tmp_var (tree, gimple_seq *);
- extern void declare_vars (tree, gimple, bool);
- extern void annotate_all_with_location (gimple_seq, location_t);
- 
- /* Validation of GIMPLE expressions.  Note that these predicates only check
-    the basic form of the expression, they don't recurse to make sure that
-    underlying nodes are also of the right form.  */
- typedef bool (*gimple_predicate)(tree);
- 
- 
- /* FIXME we should deduce this from the predicate.  */
- enum fallback {
-   fb_none = 0,		/* Do not generate a temporary.  */
- 
-   fb_rvalue = 1,	/* Generate an rvalue to hold the result of a
- 			   gimplified expression.  */
- 
-   fb_lvalue = 2,	/* Generate an lvalue to hold the result of a
- 			   gimplified expression.  */
- 
-   fb_mayfail = 4,	/* Gimplification may fail.  Error issued
- 			   afterwards.  */
-   fb_either= fb_rvalue | fb_lvalue
- };
- 
- typedef int fallback_t;
- 
- enum gimplify_status {
-   GS_ERROR	= -2,	/* Something Bad Seen.  */
-   GS_UNHANDLED	= -1,	/* A langhook result for "I dunno".  */
-   GS_OK		= 0,	/* We did something, maybe more to do.  */
-   GS_ALL_DONE	= 1	/* The expression is fully gimplified.  */
- };
  
  /* Formal (expression) temporary table handling: multiple occurrences of
     the same scalar expression are evaluated into the same temporary.  */
--- 898,903 ----
*************** inc_gimple_stmt_max_uid (struct function
*** 1049,1079 ****
    return fn->last_stmt_uid++;
  }
  
- extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
- 					   bool (*) (tree), fallback_t);
- extern void gimplify_type_sizes (tree, gimple_seq *);
- extern void gimplify_one_sizepos (tree *, gimple_seq *);
- enum gimplify_status gimplify_self_mod_expr (tree *, gimple_seq *, gimple_seq *,
- 					     bool, tree);
- extern bool gimplify_stmt (tree *, gimple_seq *);
- extern gimple gimplify_body (tree, bool);
  extern void push_gimplify_context (struct gimplify_ctx *);
  extern void pop_gimplify_context (gimple);
- extern void gimplify_and_add (tree, gimple_seq *);
  
  /* Miscellaneous helpers.  */
- extern void gimple_add_tmp_var (tree);
- extern gimple gimple_current_bind_expr (void);
- extern vec<gimple> gimple_bind_expr_stack (void);
- extern tree voidify_wrapper_expr (tree, tree);
- extern tree build_and_jump (tree *);
- extern tree force_labels_r (tree *, int *, void *);
- extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
- 						  gimple_seq *);
  struct gimplify_omp_ctx;
- extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
- extern tree gimple_boolify (tree);
- extern gimple_predicate rhs_predicate_for (tree);
  extern tree canonicalize_cond_expr_cond (tree);
  extern void dump_decl_set (FILE *, bitmap);
  extern bool gimple_can_coalesce_p (tree, tree);
--- 1008,1018 ----
*************** extern void lower_nested_functions (tree
*** 1091,1097 ****
  extern void insert_field_into_struct (tree, tree);
  
  /* In gimplify.c.  */
- extern void gimplify_function_tree (tree);
  
  /* In cfgexpand.c.  */
  extern tree gimple_assign_rhs_to_tree (gimple);
--- 1030,1035 ----
*************** gimple_seq_set_location (gimple_seq seq,
*** 5478,5482 ****
--- 5416,5427 ----
  
  #define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
  
+ tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
+ 				 gimple_predicate, tree,
+ 				 bool, enum gsi_iterator_update);
+ tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
+ 			       bool, enum gsi_iterator_update);
+ 
+ 
  
  #endif  /* GCC_GIMPLE_H */
*** D/gimplify.h	1969-12-31 19:00:00.000000000 -0500
--- gimplify.h	2013-10-03 18:29:14.221424611 -0400
***************
*** 0 ****
--- 1,92 ----
+ /* Header file for lowering trees to gimple.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ 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/>.  */
+ 
+ #ifndef GCC_GIMPLIFY_H
+ #define GCC_GIMPLIFY_H
+ 
+ enum gimplify_status {
+   GS_ERROR	= -2,	/* Something Bad Seen.  */
+   GS_UNHANDLED	= -1,	/* A langhook result for "I dunno".  */
+   GS_OK		= 0,	/* We did something, maybe more to do.  */
+   GS_ALL_DONE	= 1	/* The expression is fully gimplified.  */
+ };
+ 
+ /* Validation of GIMPLE expressions.  Note that these predicates only check
+    the basic form of the expression, they don't recurse to make sure that
+    underlying nodes are also of the right form.  */
+ 
+ typedef bool (*gimple_predicate)(tree);
+ 
+ /* FIXME we should deduce this from the predicate.  */
+ enum fallback {
+   fb_none = 0,		/* Do not generate a temporary.  */
+ 
+   fb_rvalue = 1,	/* Generate an rvalue to hold the result of a
+ 			   gimplified expression.  */
+ 
+   fb_lvalue = 2,	/* Generate an lvalue to hold the result of a
+ 			   gimplified expression.  */
+ 
+   fb_mayfail = 4,	/* Gimplification may fail.  Error issued
+ 			   afterwards.  */
+   fb_either= fb_rvalue | fb_lvalue
+ };
+ 
+ typedef int fallback_t;
+ 
+ extern void mark_addressable (tree);
+ extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
+ extern void push_gimplify_context (struct gimplify_ctx *);
+ extern void pop_gimplify_context (gimple);
+ extern gimple gimple_current_bind_expr (void);
+ extern vec<gimple> gimple_bind_expr_stack (void);
+ extern void gimplify_and_add (tree, gimple_seq *);
+ extern tree create_tmp_var_name (const char *);
+ extern tree create_tmp_var_raw (tree, const char *);
+ extern tree create_tmp_var (tree, const char *);
+ extern tree create_tmp_reg (tree, const char *);
+ extern bool is_gimple_reg_rhs (tree);
+ extern tree get_formal_tmp_var (tree, gimple_seq *);
+ extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
+ extern void declare_vars (tree, gimple, bool);
+ extern void gimple_add_tmp_var (tree);
+ extern void annotate_all_with_location (gimple_seq, location_t);
+ extern tree voidify_wrapper_expr (tree, tree);
+ extern void sort_case_labels (vec<tree> );
+ extern void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
+ extern tree build_and_jump (tree *);
+ extern enum gimplify_status gimplify_self_mod_expr (tree *, gimple_seq *,
+ 						    gimple_seq *, bool, tree);
+ extern tree gimple_boolify (tree);
+ extern tree gimple_fold_indirect_ref (tree);
+ extern bool gimplify_stmt (tree *, gimple_seq *);
+ extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
+ extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
+ 					   bool (*) (tree), fallback_t);
+ extern void gimplify_type_sizes (tree, gimple_seq *);
+ extern void gimplify_one_sizepos (tree *, gimple_seq *);
+ extern gimple gimplify_body (tree, bool);
+ extern void gimplify_function_tree (tree);
+ extern void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
+ extern tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
+ extern tree force_gimple_operand (tree, gimple_seq *, bool, tree);
+ 
+ extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
+ 						  gimple_seq *);
+ #endif /* GCC_GIMPLIFY_H */
*** D/gimplify.c	2013-10-03 13:14:02.922474212 -0400
--- gimplify.c	2013-10-04 09:28:37.763983114 -0400
*************** static struct gimplify_omp_ctx *gimplify
*** 91,96 ****
--- 91,97 ----
  
  /* Forward declaration.  */
  static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
+ static tree force_labels_r (tree *, int *, void *);
  
  /* Mark X addressable.  Unlike the langhook we expect X to be in gimple
     form and we don't do any syntax checking.  */
*************** create_tmp_reg (tree type, const char *p
*** 462,468 ****
  /* Returns true iff T is a valid RHS for an assignment to a renamed
     user -- or front-end generated artificial -- variable.  */
  
! static bool
  is_gimple_reg_rhs (tree t)
  {
    return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
--- 463,469 ----
  /* Returns true iff T is a valid RHS for an assignment to a renamed
     user -- or front-end generated artificial -- variable.  */
  
! bool
  is_gimple_reg_rhs (tree t)
  {
    return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
*************** annotate_all_with_location (gimple_seq s
*** 813,1047 ****
      }
  }
  
- /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
-    nodes that are referenced more than once in GENERIC functions.  This is
-    necessary because gimplification (translation into GIMPLE) is performed
-    by modifying tree nodes in-place, so gimplication of a shared node in a
-    first context could generate an invalid GIMPLE form in a second context.
- 
-    This is achieved with a simple mark/copy/unmark algorithm that walks the
-    GENERIC representation top-down, marks nodes with TREE_VISITED the first
-    time it encounters them, duplicates them if they already have TREE_VISITED
-    set, and finally removes the TREE_VISITED marks it has set.
- 
-    The algorithm works only at the function level, i.e. it generates a GENERIC
-    representation of a function with no nodes shared within the function when
-    passed a GENERIC function (except for nodes that are allowed to be shared).
- 
-    At the global level, it is also necessary to unshare tree nodes that are
-    referenced in more than one function, for the same aforementioned reason.
-    This requires some cooperation from the front-end.  There are 2 strategies:
- 
-      1. Manual unsharing.  The front-end needs to call unshare_expr on every
-         expression that might end up being shared across functions.
- 
-      2. Deep unsharing.  This is an extension of regular unsharing.  Instead
-         of calling unshare_expr on expressions that might be shared across
-         functions, the front-end pre-marks them with TREE_VISITED.  This will
-         ensure that they are unshared on the first reference within functions
-         when the regular unsharing algorithm runs.  The counterpart is that
-         this algorithm must look deeper than for manual unsharing, which is
-         specified by LANG_HOOKS_DEEP_UNSHARING.
- 
-   If there are only few specific cases of node sharing across functions, it is
-   probably easier for a front-end to unshare the expressions manually.  On the
-   contrary, if the expressions generated at the global level are as widespread
-   as expressions generated within functions, deep unsharing is very likely the
-   way to go.  */
- 
- /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
-    These nodes model computations that must be done once.  If we were to
-    unshare something like SAVE_EXPR(i++), the gimplification process would
-    create wrong code.  However, if DATA is non-null, it must hold a pointer
-    set that is used to unshare the subtrees of these nodes.  */
- 
- static tree
- mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
- {
-   tree t = *tp;
-   enum tree_code code = TREE_CODE (t);
- 
-   /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
-      copy their subtrees if we can make sure to do it only once.  */
-   if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
-     {
-       if (data && !pointer_set_insert ((struct pointer_set_t *)data, t))
- 	;
-       else
- 	*walk_subtrees = 0;
-     }
- 
-   /* Stop at types, decls, constants like copy_tree_r.  */
-   else if (TREE_CODE_CLASS (code) == tcc_type
- 	   || TREE_CODE_CLASS (code) == tcc_declaration
- 	   || TREE_CODE_CLASS (code) == tcc_constant
- 	   /* We can't do anything sensible with a BLOCK used as an
- 	      expression, but we also can't just die when we see it
- 	      because of non-expression uses.  So we avert our eyes
- 	      and cross our fingers.  Silly Java.  */
- 	   || code == BLOCK)
-     *walk_subtrees = 0;
- 
-   /* Cope with the statement expression extension.  */
-   else if (code == STATEMENT_LIST)
-     ;
- 
-   /* Leave the bulk of the work to copy_tree_r itself.  */
-   else
-     copy_tree_r (tp, walk_subtrees, NULL);
- 
-   return NULL_TREE;
- }
- 
- /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
-    If *TP has been visited already, then *TP is deeply copied by calling
-    mostly_copy_tree_r.  DATA is passed to mostly_copy_tree_r unmodified.  */
- 
- static tree
- copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
- {
-   tree t = *tp;
-   enum tree_code code = TREE_CODE (t);
- 
-   /* Skip types, decls, and constants.  But we do want to look at their
-      types and the bounds of types.  Mark them as visited so we properly
-      unmark their subtrees on the unmark pass.  If we've already seen them,
-      don't look down further.  */
-   if (TREE_CODE_CLASS (code) == tcc_type
-       || TREE_CODE_CLASS (code) == tcc_declaration
-       || TREE_CODE_CLASS (code) == tcc_constant)
-     {
-       if (TREE_VISITED (t))
- 	*walk_subtrees = 0;
-       else
- 	TREE_VISITED (t) = 1;
-     }
- 
-   /* If this node has been visited already, unshare it and don't look
-      any deeper.  */
-   else if (TREE_VISITED (t))
-     {
-       walk_tree (tp, mostly_copy_tree_r, data, NULL);
-       *walk_subtrees = 0;
-     }
- 
-   /* Otherwise, mark the node as visited and keep looking.  */
-   else
-     TREE_VISITED (t) = 1;
- 
-   return NULL_TREE;
- }
- 
- /* Unshare most of the shared trees rooted at *TP.  DATA is passed to the
-    copy_if_shared_r callback unmodified.  */
- 
- static inline void
- copy_if_shared (tree *tp, void *data)
- {
-   walk_tree (tp, copy_if_shared_r, data, NULL);
- }
- 
- /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
-    any nested functions.  */
- 
- static void
- unshare_body (tree fndecl)
- {
-   struct cgraph_node *cgn = cgraph_get_node (fndecl);
-   /* If the language requires deep unsharing, we need a pointer set to make
-      sure we don't repeatedly unshare subtrees of unshareable nodes.  */
-   struct pointer_set_t *visited
-     = lang_hooks.deep_unsharing ? pointer_set_create () : NULL;
- 
-   copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
-   copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
-   copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
- 
-   if (visited)
-     pointer_set_destroy (visited);
- 
-   if (cgn)
-     for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
-       unshare_body (cgn->symbol.decl);
- }
- 
- /* Callback for walk_tree to unmark the visited trees rooted at *TP.
-    Subtrees are walked until the first unvisited node is encountered.  */
- 
- static tree
- unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
- {
-   tree t = *tp;
- 
-   /* If this node has been visited, unmark it and keep looking.  */
-   if (TREE_VISITED (t))
-     TREE_VISITED (t) = 0;
  
-   /* Otherwise, don't look any deeper.  */
-   else
-     *walk_subtrees = 0;
- 
-   return NULL_TREE;
- }
- 
- /* Unmark the visited trees rooted at *TP.  */
- 
- static inline void
- unmark_visited (tree *tp)
- {
-   walk_tree (tp, unmark_visited_r, NULL, NULL);
- }
- 
- /* Likewise, but mark all trees as not visited.  */
- 
- static void
- unvisit_body (tree fndecl)
- {
-   struct cgraph_node *cgn = cgraph_get_node (fndecl);
- 
-   unmark_visited (&DECL_SAVED_TREE (fndecl));
-   unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
-   unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
- 
-   if (cgn)
-     for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
-       unvisit_body (cgn->symbol.decl);
- }
- 
- /* Unconditionally make an unshared copy of EXPR.  This is used when using
-    stored expressions which span multiple functions, such as BINFO_VTABLE,
-    as the normal unsharing process can't tell that they're shared.  */
- 
- tree
- unshare_expr (tree expr)
- {
-   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
-   return expr;
- }
- 
- /* Worker for unshare_expr_without_location.  */
- 
- static tree
- prune_expr_location (tree *tp, int *walk_subtrees, void *)
- {
-   if (EXPR_P (*tp))
-     SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
-   else
-     *walk_subtrees = 0;
-   return NULL_TREE;
- }
- 
- /* Similar to unshare_expr but also prune all expression locations
-    from EXPR.  */
- 
- tree
- unshare_expr_without_location (tree expr)
- {
-   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
-   if (EXPR_P (expr))
-     walk_tree (&expr, prune_expr_location, NULL, NULL);
-   return expr;
- }
  
  /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
     contain statements and have a value.  Assign its value to a temporary
--- 814,820 ----
*************** gimplify_exit_expr (tree *expr_p)
*** 1862,1868 ****
  /* A helper function to be called via walk_tree.  Mark all labels under *TP
     as being forced.  To be called for DECL_INITIAL of static variables.  */
  
! tree
  force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
  {
    if (TYPE_P (*tp))
--- 1635,1641 ----
  /* A helper function to be called via walk_tree.  Mark all labels under *TP
     as being forced.  To be called for DECL_INITIAL of static variables.  */
  
! static tree
  force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
  {
    if (TYPE_P (*tp))
*************** gimplify_init_ctor_eval (tree object, ve
*** 3792,3798 ****
  
  /* Return the appropriate RHS predicate for this LHS.  */
  
! gimple_predicate
  rhs_predicate_for (tree lhs)
  {
    if (is_gimple_reg (lhs))
--- 3565,3571 ----
  
  /* Return the appropriate RHS predicate for this LHS.  */
  
! static gimple_predicate
  rhs_predicate_for (tree lhs)
  {
    if (is_gimple_reg (lhs))
*************** force_gimple_operand (tree expr, gimple_
*** 8796,8846 ****
  				 var);
  }
  
- /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
-    and VAR.  If some statements are produced, emits them at GSI.
-    If BEFORE is true.  the statements are appended before GSI, otherwise
-    they are appended after it.  M specifies the way GSI moves after
-    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
- 
- tree
- force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
- 			    gimple_predicate gimple_test_f,
- 			    tree var, bool before,
- 			    enum gsi_iterator_update m)
- {
-   gimple_seq stmts;
- 
-   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
- 
-   if (!gimple_seq_empty_p (stmts))
-     {
-       if (before)
- 	gsi_insert_seq_before (gsi, stmts, m);
-       else
- 	gsi_insert_seq_after (gsi, stmts, m);
-     }
- 
-   return expr;
- }
- 
- /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
-    If SIMPLE is true, force the result to be either ssa_name or an invariant,
-    otherwise just force it to be a rhs expression.  If some statements are
-    produced, emits them at GSI.  If BEFORE is true, the statements are
-    appended before GSI, otherwise they are appended after it.  M specifies
-    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
-    are the usual values).  */
- 
- tree
- force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
- 			  bool simple_p, tree var, bool before,
- 			  enum gsi_iterator_update m)
- {
-   return force_gimple_operand_gsi_1 (gsi, expr,
- 				     simple_p
- 				     ? is_gimple_val : is_gimple_reg_rhs,
- 				     var, before, m);
- }
- 
- 
  #include "gt-gimplify.h"
--- 8569,8572 ----