diff mbox

[1/4] Separate gimple.[ch] and gimplify.[ch]

Message ID 5281460E.1070001@redhat.com
State New
Headers show

Commit Message

Andrew MacLeod Nov. 11, 2013, 9:03 p.m. UTC
This was/is relatively painful, and there will be another set after this 
to really finish it.

The front ends and the middle end both make extensive use of 
gimplification  There is no way at this early point to really separate 
them unless we created a gimplify-fe.[ch] and gimplfy-be.[ch]   so all I 
can do is structure the headers a bit better.

These patches split out the gimplification part of gimple.c and 
gimplify.c to be in gimplify.c, and adds gimplify.h for the prototypes.
Some routines from gimplify.c have been moved to gimple-expr.[ch], and 
occasionally gimple.c as appropriate.

At the moment, gimplify.h cannot compile without gimple.h, so gimplify.h 
includes gimple.h, and all the consumers of gimplification now include 
gimplify.h (or just gimpl-expr.h, if thats all they really needed)   The 
next set of patches will attempt address this and reduce it to only what 
is really needed, but first there is an anomaly that needs a solution.

So on to the anomaly that causes the issue.  force_gimple_operand* is 
extensively used by the middle end, but not by the front end at all.  
The front ends do not use the statement iterators, but 2 of the 
force_gimple_operand() routines work with gsi's, and as such, have  
"enum gsi_iterator_update" in the prototype.   This means that 
gimplify.h will not compile without understanding what enum 
gsi_iterator_update is, but no front end routine ever needs it.  the 
choices are:

  a) put "enum gsi_iterator_update" in gimple-iterator.h where it 
belongs and force anyone including gimpllfy.h to include it, even though 
no front end ever uses the routines that require it.
  b) leave "enum gsi_iterator_update" in gimple.h, and require anyone 
using gimplify.h to include gimple.h. Similar circumstance, but at least 
a few places also require gimple.h...
  c) put enum gsi_iterator_update" in coretypes.h until such time that 
the front end interface is better defined and no longer requires it
  d) split gimplifcation now into 2 parts, gimplify.[ch] for the front 
ends which doesn't include those routines that only the middle end 
requires, and gimplfy-be.[ch] for the routines which are used 
exclusively by the BE.  this will allow all the types to go where they 
belong, only only include the bits things actually need.

My order of preference is d) then c)... a) is a distant third, and I 
really dislike  b).... for what thats worth... opinions on how to 
structure it?

Anyway, these 4 set sof patches bootstrap on x86_64-unknown-linux-gnu 
with no new regressions. I've built all languages, and configured/built 
stage 1 of all the targets that utilized gimple.h, replacing gimple.h 
with gimplify,h to ensure they compile.  Ive also tried seeing if any of 
the language parts required gimplify.h, or gimple.h, or just some other 
conponent  that was being included indirectly... so there aree some 
minor cutbacks on includes there.

patch 1 is the main changes,
patch 2 contains the include changes for the body of the middle/back end
patch 3 are the front end changes
patch4  has the config/* changes for any file which used gimple.h and I 
built stage 1 for.

OK for mainline?

Andrew

PS. Once these are in I'll work on the followups to extract 
gimple-iterator.[ch], clean up gimple.h to only have the appropriate 
prototypes in the correct order, and then truly flatten the include web. 
Its just getting a bit too messy to do all at once.

Comments

Andrew MacLeod Nov. 11, 2013, 9:09 p.m. UTC | #1
This one covers the config target files which included gimple.h

Bootstraps on x86_64-unknown-linux-gnu with no new regressions, and 
compiled stage1 on each of the targets utilizing these config/*.c files 
to ensure they compiled.

targets I used were:

aarch64-linux-gnu
alpha-linux-gnu
ia64-linux
m32c-elf
mep-elf
mips64-elf
rs6000-ibm-aix4.3
s390-linux-gnu
sh64-linux
sparc-linux-gnu
spu-elf
tilegx-linux-gnu
tilepro-linux-gnu
x86_64-unknown-cygwin
xstormy16-elf
xtensa-linux

OK for mainline?

Andrew
Jeff Law Nov. 12, 2013, 7:23 p.m. UTC | #2
On 11/11/13 14:03, Andrew MacLeod wrote:
>
> So on to the anomaly that causes the issue.  force_gimple_operand* is
> extensively used by the middle end, but not by the front end at all. The
> front ends do not use the statement iterators, but 2 of the
> force_gimple_operand() routines work with gsi's, and as such, have "enum
> gsi_iterator_update" in the prototype.   This means that gimplify.h will
> not compile without understanding what enum gsi_iterator_update is, but
> no front end routine ever needs it.  the choices are:
>
>   a) put "enum gsi_iterator_update" in gimple-iterator.h where it
> belongs and force anyone including gimpllfy.h to include it, even though
> no front end ever uses the routines that require it.
>   b) leave "enum gsi_iterator_update" in gimple.h, and require anyone
> using gimplify.h to include gimple.h. Similar circumstance, but at least
> a few places also require gimple.h...
>   c) put enum gsi_iterator_update" in coretypes.h until such time that
> the front end interface is better defined and no longer requires it
>   d) split gimplifcation now into 2 parts, gimplify.[ch] for the front
> ends which doesn't include those routines that only the middle end
> requires, and gimplfy-be.[ch] for the routines which are used
> exclusively by the BE.  this will allow all the types to go where they
> belong, only only include the bits things actually need.
>
> My order of preference is d) then c)... a) is a distant third, and I
> really dislike  b).... for what thats worth... opinions on how to
> structure it?
I'd go with "d" as well.  "c" is quick and easy but just deferrs the 
problem.


>
> Anyway, these 4 set sof patches bootstrap on x86_64-unknown-linux-gnu
> with no new regressions. I've built all languages, and configured/built
> stage 1 of all the targets that utilized gimple.h, replacing gimple.h
> with gimplify,h to ensure they compile.  Ive also tried seeing if any of
> the language parts required gimplify.h, or gimple.h, or just some other
> conponent  that was being included indirectly... so there aree some
> minor cutbacks on includes there.
>
> patch 1 is the main changes,
> patch 2 contains the include changes for the body of the middle/back end
> patch 3 are the front end changes
> patch4  has the config/* changes for any file which used gimple.h and I
> built stage 1 for.
>
> OK for mainline?
1-3 are good.  You didn't include a patch in #4 :-)  Assuming it does 
the obvious things, I'm comfortable pre-approving that hunk as wel.

jeff
diff mbox

Patch


	* gimple-expr.h (create_tmp_var_name, create_tmp_var_raw,
	create_tmp_var, create_tmp_reg, mark_addressable, is_gimple_reg_rhs):
	Relocate prototypes from gimple.h.
	* gimplify.h: New File.  Relocate some prototypes from gimple.h here.
	(gimple_predicate, enum fallback, enum gimplify_status): Relocate
	from gimple.h.
	* gimple.h: Move some prototypes to gimplify.h.
	(gimple_predicate, enum fallback, enum gimplify_status): Move to
	gimplify.h.
	(gimple_do_not_emit_location_p, gimple_set_do_not_emit_location):
	Relocate from gimpify.c.
	* gimple-expr.c (remove_suffix, tmp_var_id_num, create_tmp_var_name,
	create_tmp_var_raw, create_tmp_var, create_tmp_reg, mark_addressable,
	is_gimple_reg_rhs) Relocate from gimplify.c.
	* gimplify.c (mark_addressable): Move to gimple-expr.c.
	(gimple_seq_add_stmt_without_update): Move to gimple.c.
	(remove_suffix, tmp_var_id_num, create_tmp_var_name, create_tmp_var_raw,
	create_tmp_var, create_tmp_reg, is_gimple_reg_rhs): Move to 
	gimple-expr.c.
	(should_carry_location_p): Move to gimple.c.
	(gimple_do_not_emit_location_p, gimple_set_do_not_emit_location): Move
	to gimple.h.
	(annotate_one_with_location, annotate_all_with_location_after,
	annotate_all_with_location): Move to gimple.c.
	(compare_case_labels, sort_case_labels,
	preprocess_case_label_vec_for_gimple): Move to gimple.c.
	(rhs_predicate_for): Make static.
	(gimplify_assign): Relocate from gimple.c.
	* gimple.c (gimplify_assign): Move to gimplify.c.
	(gimple_seq_add_stmt_without_update, should_carry_location_p,
	annotate_one_with_location, annotate_all_with_location_after,
	annotate_all_with_location, compare_case_labels, sort_case_labels,
	preprocess_case_label_vec_for_gimple): Relocate from gimplify.c.
	* tree.h (unshare_expr, unshare_expr_without_location,
	mark_addressable): Move prototypes to gimplify.h.
	* Makefile.in (GTFILES): gimple-expr.c now has the GTY tag for
	tmp_var_id_num

Index: gimple-expr.h
===================================================================
*** gimple-expr.h	(revision 204496)
--- gimple-expr.h	(working copy)
*************** along with GCC; see the file COPYING3.
*** 22,33 ****
--- 22,39 ----
  
  extern bool useless_type_conversion_p (tree, tree);
  
+ 
  extern void gimple_set_body (tree, gimple_seq);
  extern gimple_seq gimple_body (tree);
  extern bool gimple_has_body_p (tree);
  extern const char *gimple_decl_printable_name (tree, int);
  extern tree copy_var_decl (tree, tree, tree);
  extern bool gimple_can_coalesce_p (tree, tree);
+ 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 void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *,
  				     tree *);
*************** extern bool is_gimple_asm_val (tree);
*** 46,51 ****
--- 52,59 ----
  extern bool is_gimple_min_lval (tree);
  extern bool is_gimple_call_addr (tree);
  extern bool is_gimple_mem_ref_addr (tree);
+ extern void mark_addressable (tree);
+ extern bool is_gimple_reg_rhs (tree);
  
  /* Return true if a conversion from either type of TYPE1 and TYPE2
     to the other is not required.  Otherwise return false.  */
Index: gimplify.h
===================================================================
*** gimplify.h	(revision 0)
--- gimplify.h	(working copy)
***************
*** 0 ****
--- 1,92 ----
+ /* Header file for gimplification.
+    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
+ 
+ #include "gimple.h"
+ 
+ /* 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.  */
+ };
+ 
+ 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 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 tree unshare_expr (tree);
+ extern tree unshare_expr_without_location (tree);
+ extern tree voidify_wrapper_expr (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 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 tree force_gimple_operand_gsi_1 (gimple_stmt_iterator *, tree,
+ 					gimple_predicate, tree,
+ 					bool, enum gsi_iterator_update);
+ extern tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
+ 				      bool, enum gsi_iterator_update);
+ 
+ extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
+ 						  gimple_seq *);
+ gimple gimplify_assign (tree, tree, gimple_seq *);
+ 
+ #endif /* GCC_GIMPLIFY_H */
Index: gimple.h
===================================================================
*** gimple.h	(revision 204496)
--- gimple.h	(working copy)
*************** gimple gimple_build_call_valist (tree, u
*** 766,772 ****
  gimple gimple_build_call_internal (enum internal_fn, unsigned, ...);
  gimple gimple_build_call_internal_vec (enum internal_fn, vec<tree> );
  gimple gimple_build_call_from_tree (tree);
- gimple gimplify_assign (tree, tree, gimple_seq *);
  gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
  gimple gimple_build_label (tree label);
  gimple gimple_build_goto (tree dest);
--- 766,771 ----
*************** gimple gimple_build_omp_atomic_store (tr
*** 806,813 ****
  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 *);
  gimple_seq gimple_seq_alloc (void);
  void gimple_seq_free (gimple_seq);
  void gimple_seq_add_seq (gimple_seq *, gimple_seq);
--- 805,810 ----
*************** bool gimple_has_side_effects (const_gimp
*** 834,841 ****
  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)
  gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
--- 831,840 ----
  bool gimple_could_trap_p (gimple);
  bool gimple_could_trap_p_1 (gimple, bool, bool);
  bool gimple_assign_rhs_could_trap_p (gimple);
  bool empty_body_p (gimple_seq);
+ extern void annotate_all_with_location_after (gimple_seq, gimple_stmt_iterator,
+ 					      location_t);
+ extern void annotate_all_with_location (gimple_seq, location_t);
  unsigned get_gimple_rhs_num_ops (enum tree_code);
  #define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
  gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
*************** extern bool gimple_ior_addresses_taken (
*** 859,906 ****
  extern bool gimple_call_builtin_p (gimple, enum built_in_class);
  extern bool gimple_call_builtin_p (gimple, enum built_in_function);
  extern bool gimple_asm_clobbers_memory_p (const_gimple);
- 
- /* 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);
  extern unsigned gimple_call_get_nobnd_arg_index (const_gimple, unsigned);
  
- /* 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.  */
  
--- 858,865 ----
*************** inc_gimple_stmt_max_uid (struct function
*** 1010,1040 ****
    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 nonfreeing_call_p (gimple);
--- 969,976 ----
*************** extern void compute_transaction_bits (vo
*** 1048,1056 ****
  extern void lower_nested_functions (tree);
  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);
  
--- 984,989 ----
*************** gimple_seq_empty_p (gimple_seq s)
*** 1121,1134 ****
    return s == NULL;
  }
  
! void gimple_seq_add_stmt (gimple_seq *, gimple);
! 
! /* Link gimple statement GS to the end of the sequence *SEQ_P.  If
!    *SEQ_P is NULL, a new sequence is allocated.  This function is
!    similar to gimple_seq_add_stmt, but does not scan the operands.
!    During gimplification, we need to manipulate statement sequences
!    before the def/use vectors have been constructed.  */
! void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
  
  /* Allocate a new sequence and initialize its first element with STMT.  */
  
--- 1054,1061 ----
    return s == NULL;
  }
  
! extern void gimple_seq_add_stmt (gimple_seq *, gimple);
! extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
  
  /* Allocate a new sequence and initialize its first element with STMT.  */
  
*************** void gsi_commit_one_edge_insert (edge, b
*** 5563,5577 ****
  void gsi_commit_edge_inserts (void);
  gimple gimple_call_copy_skip_args (gimple, bitmap);
  
- /* 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);
- 
  /* Convenience routines to walk all statements of a gimple function.
     Note that this is useful exclusively before the code is converted
     into SSA form.  Once the program is in SSA form, the standard
--- 5490,5495 ----
*************** gimple_seq_set_location (gimple_seq seq,
*** 5684,5689 ****
--- 5602,5628 ----
      gimple_set_location (gsi_stmt (i), loc);
  }
  
+ /* Return true if a location should not be emitted for this statement
+    by annotate_all_with_location.  */
+ 
+ static inline bool
+ gimple_do_not_emit_location_p (gimple g)
+ {
+   return gimple_plf (g, GF_PLF_1);
+ }
+ 
+ /* Mark statement G so a location will not be emitted by
+    annotate_one_with_location.  */
+ 
+ static inline void
+ gimple_set_do_not_emit_location (gimple g)
+ {
+   /* The PLF flags are initialized to 0 when a new tuple is created,
+      so no need to initialize it anywhere.  */
+   gimple_set_plf (g, GF_PLF_1, true);
+ }
+ 
+ 
  /* Macros for showing usage statistics.  */
  #define SCALE(x) ((unsigned long) ((x) < 1024*10	\
  		  ? (x)					\
*************** gimple_seq_set_location (gimple_seq seq,
*** 5695,5698 ****
--- 5634,5640 ----
  
  #define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
  
+ extern void sort_case_labels (vec<tree> );
+ extern void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
+ 
  #endif  /* GCC_GIMPLE_H */
Index: gimple-expr.c
===================================================================
*** gimple-expr.c	(revision 204496)
--- gimple-expr.c	(working copy)
*************** along with GCC; see the file COPYING3.
*** 24,31 ****
  #include "coretypes.h"
  #include "tm.h"
  #include "tree.h"
! #include "gimple.h"
  #include "demangle.h"
  
  /* ----- Type related -----  */
  
--- 24,32 ----
  #include "coretypes.h"
  #include "tm.h"
  #include "tree.h"
! #include "gimplify.h"
  #include "demangle.h"
+ #include "gimple-ssa.h"
  
  /* ----- Type related -----  */
  
*************** gimple_can_coalesce_p (tree name1, tree
*** 406,411 ****
--- 407,522 ----
    return false;
  }
  
+ /* Strip off a legitimate source ending from the input string NAME of
+    length LEN.  Rather than having to know the names used by all of
+    our front ends, we strip off an ending of a period followed by
+    up to five characters.  (Java uses ".class".)  */
+ 
+ static inline void
+ remove_suffix (char *name, int len)
+ {
+   int i;
+ 
+   for (i = 2;  i < 8 && len > i;  i++)
+     {
+       if (name[len - i] == '.')
+ 	{
+ 	  name[len - i] = '\0';
+ 	  break;
+ 	}
+     }
+ }
+ 
+ /* Create a new temporary name with PREFIX.  Return an identifier.  */
+ 
+ static GTY(()) unsigned int tmp_var_id_num;
+ 
+ tree
+ create_tmp_var_name (const char *prefix)
+ {
+   char *tmp_name;
+ 
+   if (prefix)
+     {
+       char *preftmp = ASTRDUP (prefix);
+ 
+       remove_suffix (preftmp, strlen (preftmp));
+       clean_symbol_name (preftmp);
+ 
+       prefix = preftmp;
+     }
+ 
+   ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
+   return get_identifier (tmp_name);
+ }
+ 
+ /* Create a new temporary variable declaration of type TYPE.
+    Do NOT push it into the current binding.  */
+ 
+ tree
+ create_tmp_var_raw (tree type, const char *prefix)
+ {
+   tree tmp_var;
+ 
+   tmp_var = build_decl (input_location,
+ 			VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
+ 			type);
+ 
+   /* The variable was declared by the compiler.  */
+   DECL_ARTIFICIAL (tmp_var) = 1;
+   /* And we don't want debug info for it.  */
+   DECL_IGNORED_P (tmp_var) = 1;
+ 
+   /* Make the variable writable.  */
+   TREE_READONLY (tmp_var) = 0;
+ 
+   DECL_EXTERNAL (tmp_var) = 0;
+   TREE_STATIC (tmp_var) = 0;
+   TREE_USED (tmp_var) = 1;
+ 
+   return tmp_var;
+ }
+ 
+ /* Create a new temporary variable declaration of type TYPE.  DO push the
+    variable into the current binding.  Further, assume that this is called
+    only from gimplification or optimization, at which point the creation of
+    certain types are bugs.  */
+ 
+ tree
+ create_tmp_var (tree type, const char *prefix)
+ {
+   tree tmp_var;
+ 
+   /* We don't allow types that are addressable (meaning we can't make copies),
+      or incomplete.  We also used to reject every variable size objects here,
+      but now support those for which a constant upper bound can be obtained.
+      The processing for variable sizes is performed in gimple_add_tmp_var,
+      point at which it really matters and possibly reached via paths not going
+      through this function, e.g. after direct calls to create_tmp_var_raw.  */
+   gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type));
+ 
+   tmp_var = create_tmp_var_raw (type, prefix);
+   gimple_add_tmp_var (tmp_var);
+   return tmp_var;
+ }
+ 
+ /* Create a new temporary variable declaration of type TYPE by calling
+    create_tmp_var and if TYPE is a vector or a complex number, mark the new
+    temporary as gimple register.  */
+ 
+ tree
+ create_tmp_reg (tree type, const char *prefix)
+ {
+   tree tmp;
+ 
+   tmp = create_tmp_var (type, prefix);
+   if (TREE_CODE (type) == COMPLEX_TYPE
+       || TREE_CODE (type) == VECTOR_TYPE)
+     DECL_GIMPLE_REG_P (tmp) = 1;
+ 
+   return tmp;
+ }
+ 
  
  /* ----- Expression related -----  */
  
*************** is_gimple_mem_ref_addr (tree t)
*** 719,721 ****
--- 830,874 ----
  	      && (CONSTANT_CLASS_P (TREE_OPERAND (t, 0))
  		  || decl_address_invariant_p (TREE_OPERAND (t, 0)))));
  }
+ 
+ /* Mark X addressable.  Unlike the langhook we expect X to be in gimple
+    form and we don't do any syntax checking.  */
+ 
+ void
+ mark_addressable (tree x)
+ {
+   while (handled_component_p (x))
+     x = TREE_OPERAND (x, 0);
+   if (TREE_CODE (x) == MEM_REF
+       && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
+     x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
+   if (TREE_CODE (x) != VAR_DECL
+       && TREE_CODE (x) != PARM_DECL
+       && TREE_CODE (x) != RESULT_DECL)
+     return;
+   TREE_ADDRESSABLE (x) = 1;
+ 
+   /* Also mark the artificial SSA_NAME that points to the partition of X.  */
+   if (TREE_CODE (x) == VAR_DECL
+       && !DECL_EXTERNAL (x)
+       && !TREE_STATIC (x)
+       && cfun->gimple_df != NULL
+       && cfun->gimple_df->decls_to_pointers != NULL)
+     {
+       void *namep
+ 	= pointer_map_contains (cfun->gimple_df->decls_to_pointers, x); 
+       if (namep)
+ 	TREE_ADDRESSABLE (*(tree *)namep) = 1;
+     }
+ }
+ 
+ /* 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;
+ }
+ 
+ #include "gt-gimple-expr.h"
Index: gimplify.c
===================================================================
*** gimplify.c	(revision 204496)
--- gimplify.c	(working copy)
*************** along with GCC; see the file COPYING3.
*** 25,31 ****
  #include "coretypes.h"
  #include "tm.h"
  #include "tree.h"
! #include "gimple.h"
  #include "tree-iterator.h"
  #include "tree-inline.h"
  #include "tree-pretty-print.h"
--- 25,31 ----
  #include "coretypes.h"
  #include "tm.h"
  #include "tree.h"
! #include "gimplify.h"
  #include "tree-iterator.h"
  #include "tree-inline.h"
  #include "tree-pretty-print.h"
*************** static struct gimplify_omp_ctx *gimplify
*** 108,162 ****
  /* Forward declaration.  */
  static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
  
- /* Mark X addressable.  Unlike the langhook we expect X to be in gimple
-    form and we don't do any syntax checking.  */
- 
- void
- mark_addressable (tree x)
- {
-   while (handled_component_p (x))
-     x = TREE_OPERAND (x, 0);
-   if (TREE_CODE (x) == MEM_REF
-       && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
-     x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
-   if (TREE_CODE (x) != VAR_DECL
-       && TREE_CODE (x) != PARM_DECL
-       && TREE_CODE (x) != RESULT_DECL)
-     return;
-   TREE_ADDRESSABLE (x) = 1;
- 
-   /* Also mark the artificial SSA_NAME that points to the partition of X.  */
-   if (TREE_CODE (x) == VAR_DECL
-       && !DECL_EXTERNAL (x)
-       && !TREE_STATIC (x)
-       && cfun->gimple_df != NULL
-       && cfun->gimple_df->decls_to_pointers != NULL)
-     {
-       void *namep
- 	= pointer_map_contains (cfun->gimple_df->decls_to_pointers, x); 
-       if (namep)
- 	TREE_ADDRESSABLE (*(tree *)namep) = 1;
-     }
- }
- 
- /* Link gimple statement GS to the end of the sequence *SEQ_P.  If
-    *SEQ_P is NULL, a new sequence is allocated.  This function is
-    similar to gimple_seq_add_stmt, but does not scan the operands.
-    During gimplification, we need to manipulate statement sequences
-    before the def/use vectors have been constructed.  */
- 
- void
- gimple_seq_add_stmt_without_update (gimple_seq *seq_p, gimple gs)
- {
-   gimple_stmt_iterator si;
- 
-   if (gs == NULL)
-     return;
- 
-   si = gsi_last (*seq_p);
-   gsi_insert_after_without_update (&si, gs, GSI_NEW_STMT);
- }
- 
  /* Shorter alias name for the above function for use in gimplify.c
     only.  */
  
--- 108,113 ----
*************** gimplify_and_return_first (tree t, gimpl
*** 365,489 ****
      return gimple_seq_first_stmt (*seq_p);
  }
  
- /* Strip off a legitimate source ending from the input string NAME of
-    length LEN.  Rather than having to know the names used by all of
-    our front ends, we strip off an ending of a period followed by
-    up to five characters.  (Java uses ".class".)  */
- 
- static inline void
- remove_suffix (char *name, int len)
- {
-   int i;
- 
-   for (i = 2;  i < 8 && len > i;  i++)
-     {
-       if (name[len - i] == '.')
- 	{
- 	  name[len - i] = '\0';
- 	  break;
- 	}
-     }
- }
- 
- /* Create a new temporary name with PREFIX.  Return an identifier.  */
- 
- static GTY(()) unsigned int tmp_var_id_num;
- 
- tree
- create_tmp_var_name (const char *prefix)
- {
-   char *tmp_name;
- 
-   if (prefix)
-     {
-       char *preftmp = ASTRDUP (prefix);
- 
-       remove_suffix (preftmp, strlen (preftmp));
-       clean_symbol_name (preftmp);
- 
-       prefix = preftmp;
-     }
- 
-   ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
-   return get_identifier (tmp_name);
- }
- 
- /* Create a new temporary variable declaration of type TYPE.
-    Do NOT push it into the current binding.  */
- 
- tree
- create_tmp_var_raw (tree type, const char *prefix)
- {
-   tree tmp_var;
- 
-   tmp_var = build_decl (input_location,
- 			VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
- 			type);
- 
-   /* The variable was declared by the compiler.  */
-   DECL_ARTIFICIAL (tmp_var) = 1;
-   /* And we don't want debug info for it.  */
-   DECL_IGNORED_P (tmp_var) = 1;
- 
-   /* Make the variable writable.  */
-   TREE_READONLY (tmp_var) = 0;
- 
-   DECL_EXTERNAL (tmp_var) = 0;
-   TREE_STATIC (tmp_var) = 0;
-   TREE_USED (tmp_var) = 1;
- 
-   return tmp_var;
- }
- 
- /* Create a new temporary variable declaration of type TYPE.  DO push the
-    variable into the current binding.  Further, assume that this is called
-    only from gimplification or optimization, at which point the creation of
-    certain types are bugs.  */
- 
- tree
- create_tmp_var (tree type, const char *prefix)
- {
-   tree tmp_var;
- 
-   /* We don't allow types that are addressable (meaning we can't make copies),
-      or incomplete.  We also used to reject every variable size objects here,
-      but now support those for which a constant upper bound can be obtained.
-      The processing for variable sizes is performed in gimple_add_tmp_var,
-      point at which it really matters and possibly reached via paths not going
-      through this function, e.g. after direct calls to create_tmp_var_raw.  */
-   gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type));
- 
-   tmp_var = create_tmp_var_raw (type, prefix);
-   gimple_add_tmp_var (tmp_var);
-   return tmp_var;
- }
- 
- /* Create a new temporary variable declaration of type TYPE by calling
-    create_tmp_var and if TYPE is a vector or a complex number, mark the new
-    temporary as gimple register.  */
- 
- tree
- create_tmp_reg (tree type, const char *prefix)
- {
-   tree tmp;
- 
-   tmp = create_tmp_var (type, prefix);
-   if (TREE_CODE (type) == COMPLEX_TYPE
-       || TREE_CODE (type) == VECTOR_TYPE)
-     DECL_GIMPLE_REG_P (tmp) = 1;
- 
-   return tmp;
- }
- 
- /* 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;
- }
- 
  /* Returns true iff T is a valid RHS for an assignment to an un-renamed
     LHS, or for a call argument.  */
  
--- 316,321 ----
*************** gimple_add_tmp_var (tree tmp)
*** 750,833 ****
      }
  }
  
- /* Determine whether to assign a location to the statement GS.  */
- 
- static bool
- should_carry_location_p (gimple gs)
- {
-   /* Don't emit a line note for a label.  We particularly don't want to
-      emit one for the break label, since it doesn't actually correspond
-      to the beginning of the loop/switch.  */
-   if (gimple_code (gs) == GIMPLE_LABEL)
-     return false;
- 
-   return true;
- }
- 
- /* Return true if a location should not be emitted for this statement
-    by annotate_one_with_location.  */
- 
- static inline bool
- gimple_do_not_emit_location_p (gimple g)
- {
-   return gimple_plf (g, GF_PLF_1);
- }
- 
- /* Mark statement G so a location will not be emitted by
-    annotate_one_with_location.  */
- 
- static inline void
- gimple_set_do_not_emit_location (gimple g)
- {
-   /* The PLF flags are initialized to 0 when a new tuple is created,
-      so no need to initialize it anywhere.  */
-   gimple_set_plf (g, GF_PLF_1, true);
- }
- 
- /* Set the location for gimple statement GS to LOCATION.  */
- 
- static void
- annotate_one_with_location (gimple gs, location_t location)
- {
-   if (!gimple_has_location (gs)
-       && !gimple_do_not_emit_location_p (gs)
-       && should_carry_location_p (gs))
-     gimple_set_location (gs, location);
- }
- 
- /* Set LOCATION for all the statements after iterator GSI in sequence
-    SEQ.  If GSI is pointing to the end of the sequence, start with the
-    first statement in SEQ.  */
- 
- static void
- annotate_all_with_location_after (gimple_seq seq, gimple_stmt_iterator gsi,
- 				  location_t location)
- {
-   if (gsi_end_p (gsi))
-     gsi = gsi_start (seq);
-   else
-     gsi_next (&gsi);
- 
-   for (; !gsi_end_p (gsi); gsi_next (&gsi))
-     annotate_one_with_location (gsi_stmt (gsi), location);
- }
- 
- /* Set the location for all the statements in a sequence STMT_P to LOCATION.  */
  
- void
- annotate_all_with_location (gimple_seq stmt_p, location_t location)
- {
-   gimple_stmt_iterator i;
- 
-   if (gimple_seq_empty_p (stmt_p))
-     return;
- 
-   for (i = gsi_start (stmt_p); !gsi_end_p (i); gsi_next (&i))
-     {
-       gimple gs = gsi_stmt (i);
-       annotate_one_with_location (gs, location);
-     }
- }
  
  /* 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
--- 582,588 ----
*************** gimplify_vla_decl (tree decl, gimple_seq
*** 1441,1446 ****
--- 1196,1215 ----
    gimplify_ctxp->save_stack = true;
  }
  
+ /* 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))
+     *walk_subtrees = 0;
+   if (TREE_CODE (*tp) == LABEL_DECL)
+     FORCED_LABEL (*tp) = 1;
+ 
+   return NULL_TREE;
+ }
+ 
  /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
     and initialization explicit.  */
  
*************** gimplify_statement_list (tree *expr_p, g
*** 1557,1764 ****
  
    return GS_ALL_DONE;
  }
- 
- /* Compare two case labels.  Because the front end should already have
-    made sure that case ranges do not overlap, it is enough to only compare
-    the CASE_LOW values of each case label.  */
- 
- static int
- compare_case_labels (const void *p1, const void *p2)
- {
-   const_tree const case1 = *(const_tree const*)p1;
-   const_tree const case2 = *(const_tree const*)p2;
- 
-   /* The 'default' case label always goes first.  */
-   if (!CASE_LOW (case1))
-     return -1;
-   else if (!CASE_LOW (case2))
-     return 1;
-   else
-     return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
- }
- 
- /* Sort the case labels in LABEL_VEC in place in ascending order.  */
  
- void
- sort_case_labels (vec<tree> label_vec)
- {
-   label_vec.qsort (compare_case_labels);
- }
- 
- /* Prepare a vector of case labels to be used in a GIMPLE_SWITCH statement.
- 
-    LABELS is a vector that contains all case labels to look at.
- 
-    INDEX_TYPE is the type of the switch index expression.  Case labels
-    in LABELS are discarded if their values are not in the value range
-    covered by INDEX_TYPE.  The remaining case label values are folded
-    to INDEX_TYPE.
- 
-    If a default case exists in LABELS, it is removed from LABELS and
-    returned in DEFAULT_CASEP.  If no default case exists, but the
-    case labels already cover the whole range of INDEX_TYPE, a default
-    case is returned pointing to one of the existing case labels.
-    Otherwise DEFAULT_CASEP is set to NULL_TREE.
- 
-    DEFAULT_CASEP may be NULL, in which case the above comment doesn't
-    apply and no action is taken regardless of whether a default case is
-    found or not.  */
- 
- void
- preprocess_case_label_vec_for_gimple (vec<tree> labels,
- 				      tree index_type,
- 				      tree *default_casep)
- {
-   tree min_value, max_value;
-   tree default_case = NULL_TREE;
-   size_t i, len;
- 
-   i = 0;
-   min_value = TYPE_MIN_VALUE (index_type);
-   max_value = TYPE_MAX_VALUE (index_type);
-   while (i < labels.length ())
-     {
-       tree elt = labels[i];
-       tree low = CASE_LOW (elt);
-       tree high = CASE_HIGH (elt);
-       bool remove_element = FALSE;
- 
-       if (low)
- 	{
- 	  gcc_checking_assert (TREE_CODE (low) == INTEGER_CST);
- 	  gcc_checking_assert (!high || TREE_CODE (high) == INTEGER_CST);
- 
- 	  /* This is a non-default case label, i.e. it has a value.
- 
- 	     See if the case label is reachable within the range of
- 	     the index type.  Remove out-of-range case values.  Turn
- 	     case ranges into a canonical form (high > low strictly)
- 	     and convert the case label values to the index type.
- 
- 	     NB: The type of gimple_switch_index() may be the promoted
- 	     type, but the case labels retain the original type.  */
- 
- 	  if (high)
- 	    {
- 	      /* This is a case range.  Discard empty ranges.
- 		 If the bounds or the range are equal, turn this
- 		 into a simple (one-value) case.  */
- 	      int cmp = tree_int_cst_compare (high, low);
- 	      if (cmp < 0)
- 		remove_element = TRUE;
- 	      else if (cmp == 0)
- 		high = NULL_TREE;
- 	    }
- 
- 	  if (! high)
- 	    {
- 	      /* If the simple case value is unreachable, ignore it.  */
- 	      if ((TREE_CODE (min_value) == INTEGER_CST
- 		   && tree_int_cst_compare (low, min_value) < 0)
- 		  || (TREE_CODE (max_value) == INTEGER_CST
- 		      && tree_int_cst_compare (low, max_value) > 0))
- 		remove_element = TRUE;
- 	      else
- 		low = fold_convert (index_type, low);
- 	    }
- 	  else
- 	    {
- 	      /* If the entire case range is unreachable, ignore it.  */
- 	      if ((TREE_CODE (min_value) == INTEGER_CST
- 		   && tree_int_cst_compare (high, min_value) < 0)
- 		  || (TREE_CODE (max_value) == INTEGER_CST
- 		      && tree_int_cst_compare (low, max_value) > 0))
- 		remove_element = TRUE;
- 	      else
- 		{
- 		  /* If the lower bound is less than the index type's
- 		     minimum value, truncate the range bounds.  */
- 		  if (TREE_CODE (min_value) == INTEGER_CST
- 		      && tree_int_cst_compare (low, min_value) < 0)
- 		    low = min_value;
- 		  low = fold_convert (index_type, low);
- 
- 		  /* If the upper bound is greater than the index type's
- 		     maximum value, truncate the range bounds.  */
- 		  if (TREE_CODE (max_value) == INTEGER_CST
- 		      && tree_int_cst_compare (high, max_value) > 0)
- 		    high = max_value;
- 		  high = fold_convert (index_type, high);
- 
- 		  /* We may have folded a case range to a one-value case.  */
- 		  if (tree_int_cst_equal (low, high))
- 		    high = NULL_TREE;
- 		}
- 	    }
- 
- 	  CASE_LOW (elt) = low;
- 	  CASE_HIGH (elt) = high;
- 	}
-       else
- 	{
- 	  gcc_assert (!default_case);
- 	  default_case = elt;
- 	  /* The default case must be passed separately to the
- 	     gimple_build_switch routine.  But if DEFAULT_CASEP
- 	     is NULL, we do not remove the default case (it would
- 	     be completely lost).  */
- 	  if (default_casep)
- 	    remove_element = TRUE;
- 	}
- 
-       if (remove_element)
- 	labels.ordered_remove (i);
-       else
- 	i++;
-     }
-   len = i;
- 
-   if (!labels.is_empty ())
-     sort_case_labels (labels);
- 
-   if (default_casep && !default_case)
-     {
-       /* If the switch has no default label, add one, so that we jump
- 	 around the switch body.  If the labels already cover the whole
- 	 range of the switch index_type, add the default label pointing
- 	 to one of the existing labels.  */
-       if (len
- 	  && TYPE_MIN_VALUE (index_type)
- 	  && TYPE_MAX_VALUE (index_type)
- 	  && tree_int_cst_equal (CASE_LOW (labels[0]),
- 				 TYPE_MIN_VALUE (index_type)))
- 	{
- 	  tree low, high = CASE_HIGH (labels[len - 1]);
- 	  if (!high)
- 	    high = CASE_LOW (labels[len - 1]);
- 	  if (tree_int_cst_equal (high, TYPE_MAX_VALUE (index_type)))
- 	    {
- 	      for (i = 1; i < len; i++)
- 		{
- 		  high = CASE_LOW (labels[i]);
- 		  low = CASE_HIGH (labels[i - 1]);
- 		  if (!low)
- 		    low = CASE_LOW (labels[i - 1]);
- 		  if ((TREE_INT_CST_LOW (low) + 1
- 		       != TREE_INT_CST_LOW (high))
- 		      || (TREE_INT_CST_HIGH (low)
- 			  + (TREE_INT_CST_LOW (high) == 0)
- 			  != TREE_INT_CST_HIGH (high)))
- 		    break;
- 		}
- 	      if (i == len)
- 		{
- 		  tree label = CASE_LABEL (labels[0]);
- 		  default_case = build_case_label (NULL_TREE, NULL_TREE,
- 						   label);
- 		}
- 	    }
- 	}
-     }
- 
-   if (default_casep)
-     *default_casep = default_case;
- }
  
  /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
     branch to.  */
--- 1326,1332 ----
*************** gimplify_exit_expr (tree *expr_p)
*** 1882,1901 ****
    return GS_OK;
  }
  
- /* 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))
-     *walk_subtrees = 0;
-   if (TREE_CODE (*tp) == LABEL_DECL)
-     FORCED_LABEL (*tp) = 1;
- 
-   return NULL_TREE;
- }
- 
  /* *EXPR_P is a COMPONENT_REF being used as an rvalue.  If its type is
     different from its canonical type, wrap the whole thing inside a
     NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
--- 1450,1455 ----
*************** gimplify_init_ctor_eval (tree object, ve
*** 3838,3844 ****
  
  /* Return the appropriate RHS predicate for this LHS.  */
  
! gimple_predicate
  rhs_predicate_for (tree lhs)
  {
    if (is_gimple_reg (lhs))
--- 3392,3398 ----
  
  /* Return the appropriate RHS predicate for this LHS.  */
  
! static gimple_predicate
  rhs_predicate_for (tree lhs)
  {
    if (is_gimple_reg (lhs))
*************** gimplify_va_arg_expr (tree *expr_p, gimp
*** 9421,9424 ****
      }
  }
  
! #include "gt-gimplify.h"
--- 8975,8994 ----
      }
  }
  
! /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
! 
!    DST/SRC are the destination and source respectively.  You can pass
!    ungimplified trees in DST or SRC, in which case they will be
!    converted to a gimple operand if necessary.
! 
!    This function returns the newly created GIMPLE_ASSIGN tuple.  */
! 
! gimple
! gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
! {
!   tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
!   gimplify_and_add (t, seq_p);
!   ggc_free (t);
!   return gimple_seq_last_stmt (*seq_p);
! }
! 
Index: gimple.c
===================================================================
*** gimple.c	(revision 204496)
--- gimple.c	(working copy)
*************** along with GCC; see the file COPYING3.
*** 29,34 ****
--- 29,35 ----
  #include "hard-reg-set.h"
  #include "basic-block.h"
  #include "gimple.h"
+ #include "gimplify.h"
  #include "diagnostic.h"
  #include "value-prof.h"
  #include "flags.h"
*************** gimple_build_assign_with_ops (enum tree_
*** 446,469 ****
  }
  
  
- /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
- 
-    DST/SRC are the destination and source respectively.  You can pass
-    ungimplified trees in DST or SRC, in which case they will be
-    converted to a gimple operand if necessary.
- 
-    This function returns the newly created GIMPLE_ASSIGN tuple.  */
- 
- gimple
- gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
- {
-   tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
-   gimplify_and_add (t, seq_p);
-   ggc_free (t);
-   return gimple_seq_last_stmt (*seq_p);
- }
- 
- 
  /* Build a GIMPLE_COND statement.
  
     PRED is the condition used to compare LHS and the RHS.
--- 447,452 ----
*************** gimple_seq_add_stmt (gimple_seq *seq_p,
*** 1172,1177 ****
--- 1155,1177 ----
    gsi_insert_after (&si, gs, GSI_NEW_STMT);
  }
  
+ /* Link gimple statement GS to the end of the sequence *SEQ_P.  If
+    *SEQ_P is NULL, a new sequence is allocated.  This function is
+    similar to gimple_seq_add_stmt, but does not scan the operands.
+    During gimplification, we need to manipulate statement sequences
+    before the def/use vectors have been constructed.  */
+ 
+ void
+ gimple_seq_add_stmt_without_update (gimple_seq *seq_p, gimple gs)
+ {
+   gimple_stmt_iterator si;
+ 
+   if (gs == NULL)
+     return;
+ 
+   si = gsi_last (*seq_p);
+   gsi_insert_after_without_update (&si, gs, GSI_NEW_STMT);
+ }
  
  /* Append sequence SRC to the end of sequence *DST_P.  If *DST_P is
     NULL, a new sequence is allocated.  */
*************** gimple_seq_add_seq (gimple_seq *dst_p, g
*** 1187,1192 ****
--- 1187,1250 ----
    gsi_insert_seq_after (&si, src, GSI_NEW_STMT);
  }
  
+ /* Determine whether to assign a location to the statement GS.  */
+ 
+ static bool
+ should_carry_location_p (gimple gs)
+ {
+   /* Don't emit a line note for a label.  We particularly don't want to
+      emit one for the break label, since it doesn't actually correspond
+      to the beginning of the loop/switch.  */
+   if (gimple_code (gs) == GIMPLE_LABEL)
+     return false;
+ 
+   return true;
+ }
+ 
+ /* Set the location for gimple statement GS to LOCATION.  */
+ 
+ static void
+ annotate_one_with_location (gimple gs, location_t location)
+ {
+   if (!gimple_has_location (gs)
+       && !gimple_do_not_emit_location_p (gs)
+       && should_carry_location_p (gs))
+     gimple_set_location (gs, location);
+ }
+ 
+ /* Set LOCATION for all the statements after iterator GSI in sequence
+    SEQ.  If GSI is pointing to the end of the sequence, start with the
+    first statement in SEQ.  */
+ 
+ void
+ annotate_all_with_location_after (gimple_seq seq, gimple_stmt_iterator gsi,
+ 				  location_t location)
+ {
+   if (gsi_end_p (gsi))
+     gsi = gsi_start (seq);
+   else
+     gsi_next (&gsi);
+ 
+   for (; !gsi_end_p (gsi); gsi_next (&gsi))
+     annotate_one_with_location (gsi_stmt (gsi), location);
+ }
+ 
+ /* Set the location for all the statements in a sequence STMT_P to LOCATION.  */
+ 
+ void
+ annotate_all_with_location (gimple_seq stmt_p, location_t location)
+ {
+   gimple_stmt_iterator i;
+ 
+   if (gimple_seq_empty_p (stmt_p))
+     return;
+ 
+   for (i = gsi_start (stmt_p); !gsi_end_p (i); gsi_next (&i))
+     {
+       gimple gs = gsi_stmt (i);
+       annotate_one_with_location (gs, location);
+     }
+ }
  
  /* Helper function of empty_body_p.  Return true if STMT is an empty
     statement.  */
*************** infer_nonnull_range (gimple stmt, tree o
*** 3428,3430 ****
--- 3486,3690 ----
  
    return false;
  }
+ 
+ /* Compare two case labels.  Because the front end should already have
+    made sure that case ranges do not overlap, it is enough to only compare
+    the CASE_LOW values of each case label.  */
+ 
+ static int
+ compare_case_labels (const void *p1, const void *p2)
+ {
+   const_tree const case1 = *(const_tree const*)p1;
+   const_tree const case2 = *(const_tree const*)p2;
+ 
+   /* The 'default' case label always goes first.  */
+   if (!CASE_LOW (case1))
+     return -1;
+   else if (!CASE_LOW (case2))
+     return 1;
+   else
+     return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
+ }
+ 
+ /* Sort the case labels in LABEL_VEC in place in ascending order.  */
+ 
+ void
+ sort_case_labels (vec<tree> label_vec)
+ {
+   label_vec.qsort (compare_case_labels);
+ }
+ 
+ /* Prepare a vector of case labels to be used in a GIMPLE_SWITCH statement.
+ 
+    LABELS is a vector that contains all case labels to look at.
+ 
+    INDEX_TYPE is the type of the switch index expression.  Case labels
+    in LABELS are discarded if their values are not in the value range
+    covered by INDEX_TYPE.  The remaining case label values are folded
+    to INDEX_TYPE.
+ 
+    If a default case exists in LABELS, it is removed from LABELS and
+    returned in DEFAULT_CASEP.  If no default case exists, but the
+    case labels already cover the whole range of INDEX_TYPE, a default
+    case is returned pointing to one of the existing case labels.
+    Otherwise DEFAULT_CASEP is set to NULL_TREE.
+ 
+    DEFAULT_CASEP may be NULL, in which case the above comment doesn't
+    apply and no action is taken regardless of whether a default case is
+    found or not.  */
+ 
+ void
+ preprocess_case_label_vec_for_gimple (vec<tree> labels,
+ 				      tree index_type,
+ 				      tree *default_casep)
+ {
+   tree min_value, max_value;
+   tree default_case = NULL_TREE;
+   size_t i, len;
+ 
+   i = 0;
+   min_value = TYPE_MIN_VALUE (index_type);
+   max_value = TYPE_MAX_VALUE (index_type);
+   while (i < labels.length ())
+     {
+       tree elt = labels[i];
+       tree low = CASE_LOW (elt);
+       tree high = CASE_HIGH (elt);
+       bool remove_element = FALSE;
+ 
+       if (low)
+ 	{
+ 	  gcc_checking_assert (TREE_CODE (low) == INTEGER_CST);
+ 	  gcc_checking_assert (!high || TREE_CODE (high) == INTEGER_CST);
+ 
+ 	  /* This is a non-default case label, i.e. it has a value.
+ 
+ 	     See if the case label is reachable within the range of
+ 	     the index type.  Remove out-of-range case values.  Turn
+ 	     case ranges into a canonical form (high > low strictly)
+ 	     and convert the case label values to the index type.
+ 
+ 	     NB: The type of gimple_switch_index() may be the promoted
+ 	     type, but the case labels retain the original type.  */
+ 
+ 	  if (high)
+ 	    {
+ 	      /* This is a case range.  Discard empty ranges.
+ 		 If the bounds or the range are equal, turn this
+ 		 into a simple (one-value) case.  */
+ 	      int cmp = tree_int_cst_compare (high, low);
+ 	      if (cmp < 0)
+ 		remove_element = TRUE;
+ 	      else if (cmp == 0)
+ 		high = NULL_TREE;
+ 	    }
+ 
+ 	  if (! high)
+ 	    {
+ 	      /* If the simple case value is unreachable, ignore it.  */
+ 	      if ((TREE_CODE (min_value) == INTEGER_CST
+ 		   && tree_int_cst_compare (low, min_value) < 0)
+ 		  || (TREE_CODE (max_value) == INTEGER_CST
+ 		      && tree_int_cst_compare (low, max_value) > 0))
+ 		remove_element = TRUE;
+ 	      else
+ 		low = fold_convert (index_type, low);
+ 	    }
+ 	  else
+ 	    {
+ 	      /* If the entire case range is unreachable, ignore it.  */
+ 	      if ((TREE_CODE (min_value) == INTEGER_CST
+ 		   && tree_int_cst_compare (high, min_value) < 0)
+ 		  || (TREE_CODE (max_value) == INTEGER_CST
+ 		      && tree_int_cst_compare (low, max_value) > 0))
+ 		remove_element = TRUE;
+ 	      else
+ 		{
+ 		  /* If the lower bound is less than the index type's
+ 		     minimum value, truncate the range bounds.  */
+ 		  if (TREE_CODE (min_value) == INTEGER_CST
+ 		      && tree_int_cst_compare (low, min_value) < 0)
+ 		    low = min_value;
+ 		  low = fold_convert (index_type, low);
+ 
+ 		  /* If the upper bound is greater than the index type's
+ 		     maximum value, truncate the range bounds.  */
+ 		  if (TREE_CODE (max_value) == INTEGER_CST
+ 		      && tree_int_cst_compare (high, max_value) > 0)
+ 		    high = max_value;
+ 		  high = fold_convert (index_type, high);
+ 
+ 		  /* We may have folded a case range to a one-value case.  */
+ 		  if (tree_int_cst_equal (low, high))
+ 		    high = NULL_TREE;
+ 		}
+ 	    }
+ 
+ 	  CASE_LOW (elt) = low;
+ 	  CASE_HIGH (elt) = high;
+ 	}
+       else
+ 	{
+ 	  gcc_assert (!default_case);
+ 	  default_case = elt;
+ 	  /* The default case must be passed separately to the
+ 	     gimple_build_switch routine.  But if DEFAULT_CASEP
+ 	     is NULL, we do not remove the default case (it would
+ 	     be completely lost).  */
+ 	  if (default_casep)
+ 	    remove_element = TRUE;
+ 	}
+ 
+       if (remove_element)
+ 	labels.ordered_remove (i);
+       else
+ 	i++;
+     }
+   len = i;
+ 
+   if (!labels.is_empty ())
+     sort_case_labels (labels);
+ 
+   if (default_casep && !default_case)
+     {
+       /* If the switch has no default label, add one, so that we jump
+ 	 around the switch body.  If the labels already cover the whole
+ 	 range of the switch index_type, add the default label pointing
+ 	 to one of the existing labels.  */
+       if (len
+ 	  && TYPE_MIN_VALUE (index_type)
+ 	  && TYPE_MAX_VALUE (index_type)
+ 	  && tree_int_cst_equal (CASE_LOW (labels[0]),
+ 				 TYPE_MIN_VALUE (index_type)))
+ 	{
+ 	  tree low, high = CASE_HIGH (labels[len - 1]);
+ 	  if (!high)
+ 	    high = CASE_LOW (labels[len - 1]);
+ 	  if (tree_int_cst_equal (high, TYPE_MAX_VALUE (index_type)))
+ 	    {
+ 	      for (i = 1; i < len; i++)
+ 		{
+ 		  high = CASE_LOW (labels[i]);
+ 		  low = CASE_HIGH (labels[i - 1]);
+ 		  if (!low)
+ 		    low = CASE_LOW (labels[i - 1]);
+ 		  if ((TREE_INT_CST_LOW (low) + 1
+ 		       != TREE_INT_CST_LOW (high))
+ 		      || (TREE_INT_CST_HIGH (low)
+ 			  + (TREE_INT_CST_LOW (high) == 0)
+ 			  != TREE_INT_CST_HIGH (high)))
+ 		    break;
+ 		}
+ 	      if (i == len)
+ 		{
+ 		  tree label = CASE_LABEL (labels[0]);
+ 		  default_case = build_case_label (NULL_TREE, NULL_TREE,
+ 						   label);
+ 		}
+ 	    }
+ 	}
+     }
+ 
+   if (default_casep)
+     *default_casep = default_case;
+ }
Index: tree.h
===================================================================
*** tree.h	(revision 204496)
--- tree.h	(working copy)
*************** extern void cache_integer_cst (tree);
*** 4290,4299 ****
  /* 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);
--- 4290,4295 ----
*************** extern void set_decl_incoming_rtl (tree,
*** 4797,4803 ****
  
  /* In gimple.c.  */
  extern tree get_base_address (tree t);
- extern void mark_addressable (tree);
  
  /* In tree.c.  */
  extern tree drop_tree_overflow (tree);
--- 4793,4798 ----
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 204496)
--- Makefile.in	(working copy)
*************** GTFILES = $(CPP_ID_DATA_H) $(srcdir)/inp
*** 2254,2260 ****
    $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
    $(srcdir)/tree-cfg.c \
    $(srcdir)/tree-dfa.c \
!   $(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
    $(srcdir)/tree-chrec.h \
    $(srcdir)/tree-scalar-evolution.c \
    $(srcdir)/tree-ssa-operands.h \
--- 2254,2260 ----
    $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
    $(srcdir)/tree-cfg.c \
    $(srcdir)/tree-dfa.c \
!   $(srcdir)/tree-iterator.c $(srcdir)/gimple-expr.c \
    $(srcdir)/tree-chrec.h \
    $(srcdir)/tree-scalar-evolution.c \
    $(srcdir)/tree-ssa-operands.h \