
	* 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 \
