diff mbox

[1/2] add gimplfy-be.[ch] for iterator-aware BE-only gimplification routines.

Message ID 5284E7F2.1080806@redhat.com
State New
Headers show

Commit Message

Andrew MacLeod Nov. 14, 2013, 3:10 p.m. UTC
This patch splits out the force_gimple_operand  parts of gimplify.[ch] 
into their own file which will prevent the front ends from having to see 
iterators, and breaks the annoying dependency cycle between gimple.h, 
gimplify.h and gimple-iterator.h.  I suspect more stuff may end up here, 
but this is all that is needed for now.

There were also a few gimplification related things still hanging around 
in gimple.h so I moved those to gimplify.h as well.

This also allows gimple-iterator.h to finally take ownership of "enum 
gsi_iterator_update".

When I originally created gimplify.h, I included gimple.h right from 
gimplify.h thinking it would be better for the front end files, but 
really, no. It just complicates things, so I flatten gimplify.h as well 
here...  That's the primary reason for the #include churn.  Now gimple.h 
is included where it is needed rather than blanket including it with 
gimplfy.h.

I also trimmed the #include list in gimplify.c and gimplify-be.c to only 
include what is actually required.

Next I will clean up what remains of gimple.h, and flatten it. Then the 
gimple refactoring is done for now.

patch 1 is the core changes
patch2 contains the resulting include changes.

Bootstrapped on x86_64-unknown-linux-gnu with no new regressions, and 
stage 1 built for all targets to confirm those changes.

OK?

Andrew

PS Interestingly, many back end files still need gimplify.h, and the 
vast majority of them are actually only looking for 'unshare_expr'... 
which is used by both the front ends and back ends.  (Some front end 
files are also including gimplify.h simply to get that routine.)

It is obviously a very tree specific thing since it duplicates most of a 
tree, but is only required because gimple uses unshared trees for 
expressions and such. Its not really part of the gimplification process, 
but it is utilized by it.  I am wondering if perhaps we ought to split 
this code out as well and make "tree-unshare.[ch]"...

Comments

Richard Biener Nov. 14, 2013, 3:41 p.m. UTC | #1
On Thu, Nov 14, 2013 at 4:10 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
> This patch splits out the force_gimple_operand  parts of gimplify.[ch] into
> their own file which will prevent the front ends from having to see
> iterators, and breaks the annoying dependency cycle between gimple.h,
> gimplify.h and gimple-iterator.h.  I suspect more stuff may end up here, but
> this is all that is needed for now.
>
> There were also a few gimplification related things still hanging around in
> gimple.h so I moved those to gimplify.h as well.
>
> This also allows gimple-iterator.h to finally take ownership of "enum
> gsi_iterator_update".
>
> When I originally created gimplify.h, I included gimple.h right from
> gimplify.h thinking it would be better for the front end files, but really,
> no. It just complicates things, so I flatten gimplify.h as well here...
> That's the primary reason for the #include churn.  Now gimple.h is included
> where it is needed rather than blanket including it with gimplfy.h.
>
> I also trimmed the #include list in gimplify.c and gimplify-be.c to only
> include what is actually required.
>
> Next I will clean up what remains of gimple.h, and flatten it. Then the
> gimple refactoring is done for now.
>
> patch 1 is the core changes
> patch2 contains the resulting include changes.
>
> Bootstrapped on x86_64-unknown-linux-gnu with no new regressions, and stage
> 1 built for all targets to confirm those changes.
>
> OK?

Eh, it's not "backend", it's "middle-end" please.  And that should include
gimple_regimplify_operands.

    GS_ALL_DONE = 1     /* The expression is fully gimplified.  */
  };
+ /* Gimplify hashtable helper.  */
+
+ struct gimplify_hasher : typed_free_remove <elt_t>
+ {
+   typedef elt_t value_type;

watch out for missing vertical space when cut & pasting (just look over
your own patches).

Why put this in a header?  That's super-ugly - this all should be
private to gimplifciation.

+ /* Return true if gimplify_one_sizepos doesn't need to gimplify
+    expr (when in TYPE_SIZE{,_UNIT} and similar type/decl size/bitsize
+    fields).  */
+ static inline bool
+ is_gimple_sizepos (tree expr)

likewise.  And in C++ times it's now plain 'inline', not 'static inline'.

Oh, I see you moved it from gimple.h - oh well.

Thus, ok with s/gimplify-be.[ch]/gimplify-me.[ch]/ (still ugly name).

Thanks,
Richard.


> Andrew
>
> PS Interestingly, many back end files still need gimplify.h, and the vast
> majority of them are actually only looking for 'unshare_expr'... which is
> used by both the front ends and back ends.  (Some front end files are also
> including gimplify.h simply to get that routine.)
>
> It is obviously a very tree specific thing since it duplicates most of a
> tree, but is only required because gimple uses unshared trees for
> expressions and such. Its not really part of the gimplification process, but
> it is utilized by it.  I am wondering if perhaps we ought to split this code
> out as well and make "tree-unshare.[ch]"...
Andrew MacLeod Nov. 14, 2013, 4:56 p.m. UTC | #2
On 11/14/2013 10:41 AM, Richard Biener wrote:
> On Thu, Nov 14, 2013 at 4:10 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
>> This patch splits out the force_gimple_operand  parts of gimplify.[ch] into
>> their own file which will prevent the front ends from having to see
>> iterators, and breaks the annoying dependency cycle between gimple.h,
>> gimplify.h and gimple-iterator.h.  I suspect more stuff may end up here, but
>> this is all that is needed for now.
>>
>> There were also a few gimplification related things still hanging around in
>> gimple.h so I moved those to gimplify.h as well.
>>
>> This also allows gimple-iterator.h to finally take ownership of "enum
>> gsi_iterator_update".
>>
>> When I originally created gimplify.h, I included gimple.h right from
>> gimplify.h thinking it would be better for the front end files, but really,
>> no. It just complicates things, so I flatten gimplify.h as well here...
>> That's the primary reason for the #include churn.  Now gimple.h is included
>> where it is needed rather than blanket including it with gimplfy.h.
>>
>> I also trimmed the #include list in gimplify.c and gimplify-be.c to only
>> include what is actually required.
>>
>> Next I will clean up what remains of gimple.h, and flatten it. Then the
>> gimple refactoring is done for now.
>>
>> patch 1 is the core changes
>> patch2 contains the resulting include changes.
>>
>> Bootstrapped on x86_64-unknown-linux-gnu with no new regressions, and stage
>> 1 built for all targets to confirm those changes.
>>
>> OK?
> Eh, it's not "backend", it's "middle-end" please.  And that should include
> gimple_regimplify_operands.

OK, I have to expose rhs_predicate_for() in gimplify.h to do that, but 
its not a big deal.  done.

>
>      GS_ALL_DONE = 1     /* The expression is fully gimplified.  */
>    };
> + /* Gimplify hashtable helper.  */
> +
> + struct gimplify_hasher : typed_free_remove <elt_t>
> + {
> +   typedef elt_t value_type;
>
> watch out for missing vertical space when cut & pasting (just look over
> your own patches).

Just missed that one.   These gimlpify-hasher routines seem to move 
safely into gimplify.c.

>
> Why put this in a header?  That's super-ugly - this all should be
> private to gimplifciation.
>
> + /* Return true if gimplify_one_sizepos doesn't need to gimplify
> +    expr (when in TYPE_SIZE{,_UNIT} and similar type/decl size/bitsize
> +    fields).  */
> + static inline bool
> + is_gimple_sizepos (tree expr)
>
> likewise.  And in C++ times it's now plain 'inline', not 'static inline'.
Yeah, except this routine is also used outside of gimplifcation at the 
moment, in tree.c of all places... for variably_modified_type_p().  
Tackling that issue is a little outside the scope of what I'm doing at 
this moment :-P.

So does that mean when "processing" an include file, we generally ought 
to strip out any 'static inline' and just make them 'inline' now?


> Oh, I see you moved it from gimple.h - oh well.
>
> Thus, ok with s/gimplify-be.[ch]/gimplify-me.[ch]/ (still ugly name).
>
>
yeah... I'm open to alternate suggestions :-)  I eventually hope to be 
rid of the file anyway....

Andrew
diff mbox

Patch


	* gimplify-be.h:  New file.  Add prototypes.
	* gimplify.h: Don't include gimple.h.
	(struct gimplify_hasher, struct gimplify_ctx, is_gimple_sizepos,
	gimplify_hasher::hash, gimplify_hasher::equal): Relocate from gimple.h.
	* gimple.h (struct gimplify_hasher, gimplify_hasher::hash,
	gimplify_hasher::equal, struct gimplify_ctx, is_gimple_sizepos): Move
	to gimplify.h.
	(enum gsi_iterator_update): Move to gimple-iterator.h.
	* gimple-iterator.h (enum gsi_iterator_update): Relocate from gimple.h.
	* gimplify-be.c: New File.
	(force_gimple_operand_1, force_gimple_operand,
	force_gimple_operand_gsi_1, force_gimple_operand_gsi): Relocate from
	gimplify.c.
	* gimplify.c (force_gimple_operand_1, force_gimple_operand,
	force_gimple_operand_gsi_1, force_gimple_operand_gsi): Move to
	gimplify-be.c.
	* Makefile.in (OBJS): Add gimplify-be.o

Index: gimplify-be.h
===================================================================
*** gimplify-be.h	(revision 0)
--- gimplify-be.h	(working copy)
***************
*** 0 ****
--- 1,36 ----
+ /* Header file for back end 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_BE_H
+ #define GCC_GIMPLIFY_BE_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);
+ 
+ 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);
+ 
+ #endif /* GCC_GIMPLIFY_BE_H */
Index: gimplify.h
===================================================================
*** gimplify.h	(revision 204762)
--- gimplify.h	(working copy)
*************** along with GCC; see the file COPYING3.
*** 20,27 ****
  #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.  */
--- 20,25 ----
*************** enum gimplify_status {
*** 50,56 ****
--- 48,86 ----
    GS_OK		= 0,	/* We did something, maybe more to do.  */
    GS_ALL_DONE	= 1	/* The expression is fully gimplified.  */
  };
+ /* Gimplify hashtable helper.  */
+ 
+ struct gimplify_hasher : typed_free_remove <elt_t>
+ {
+   typedef elt_t value_type;
+   typedef elt_t compare_type;
+   static inline hashval_t hash (const value_type *);
+   static inline bool equal (const value_type *, const compare_type *);
+ };
+ 
+ struct gimplify_ctx
+ {
+   struct gimplify_ctx *prev_context;
+ 
+   vec<gimple> bind_expr_stack;
+   tree temps;
+   gimple_seq conditional_cleanups;
+   tree exit_label;
+   tree return_temp;
+ 
+   vec<tree> case_labels;
+   /* The formal temporary table.  Should this be persistent?  */
+   hash_table <gimplify_hasher> temp_htab;
+ 
+   int conditions;
+   bool save_stack;
+   bool into_ssa;
+   bool allow_rhs_cond_expr;
+   bool in_cleanup_point_expr;
+ };
  
+ 
+ extern struct gimplify_ctx *gimplify_ctxp;
  extern void push_gimplify_context (struct gimplify_ctx *);
  extern void pop_gimplify_context (gimple);
  extern gimple gimple_current_bind_expr (void);
*************** extern void gimplify_one_sizepos (tree *
*** 77,92 ****
  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 */
--- 107,163 ----
  extern gimple gimplify_body (tree, bool);
  extern void gimplify_function_tree (tree);
  extern void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
  extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
  						  gimple_seq *);
  gimple gimplify_assign (tree, tree, gimple_seq *);
  
+ /* Return true if gimplify_one_sizepos doesn't need to gimplify
+    expr (when in TYPE_SIZE{,_UNIT} and similar type/decl size/bitsize
+    fields).  */
+ static inline bool
+ is_gimple_sizepos (tree expr)
+ {
+   /* gimplify_one_sizepos doesn't need to do anything if the value isn't there,
+      is constant, or contains A PLACEHOLDER_EXPR.  We also don't want to do
+      anything if it's already a VAR_DECL.  If it's a VAR_DECL from another
+      function, the gimplifier will want to replace it with a new variable,
+      but that will cause problems if this type is from outside the function.
+      It's OK to have that here.  */
+   return (expr == NULL_TREE
+ 	  || TREE_CONSTANT (expr)
+ 	  || TREE_CODE (expr) == VAR_DECL
+ 	  || CONTAINS_PLACEHOLDER_P (expr));
+ }                                        
+ 
+ inline hashval_t
+ gimplify_hasher::hash (const value_type *p)
+ {
+   tree t = p->val;
+   return iterative_hash_expr (t, 0);
+ }
+ 
+ inline bool
+ gimplify_hasher::equal (const value_type *p1, const compare_type *p2)
+ {
+   tree t1 = p1->val;
+   tree t2 = p2->val;
+   enum tree_code code = TREE_CODE (t1);
+ 
+   if (TREE_CODE (t2) != code
+       || TREE_TYPE (t1) != TREE_TYPE (t2))
+     return false;
+ 
+   if (!operand_equal_p (t1, t2, 0))
+     return false;
+ 
+ #ifdef ENABLE_CHECKING
+   /* Only allow them to compare equal if they also hash equal; otherwise
+      results are nondeterminate, and we fail bootstrap comparison.  */
+   gcc_assert (hash (p1) == hash (p2));
+ #endif
+ 
+   return true;
+ }
+ 
+ 
  #endif /* GCC_GIMPLIFY_H */
Index: gimple.h
===================================================================
*** gimple.h	(revision 204763)
--- gimple.h	(working copy)
*************** typedef struct gimple_temp_hash_elt
*** 847,931 ****
    tree temp;  /* Value */
  } elt_t;
  
- /* Gimplify hashtable helper.  */
- 
- struct gimplify_hasher : typed_free_remove <elt_t>
- {
-   typedef elt_t value_type;
-   typedef elt_t compare_type;
-   static inline hashval_t hash (const value_type *);
-   static inline bool equal (const value_type *, const compare_type *);
- };
- 
- inline hashval_t
- gimplify_hasher::hash (const value_type *p)
- {
-   tree t = p->val;
-   return iterative_hash_expr (t, 0);
- }
- 
- inline bool
- gimplify_hasher::equal (const value_type *p1, const compare_type *p2)
- {
-   tree t1 = p1->val;
-   tree t2 = p2->val;
-   enum tree_code code = TREE_CODE (t1);
- 
-   if (TREE_CODE (t2) != code
-       || TREE_TYPE (t1) != TREE_TYPE (t2))
-     return false;
- 
-   if (!operand_equal_p (t1, t2, 0))
-     return false;
- 
- #ifdef ENABLE_CHECKING
-   /* Only allow them to compare equal if they also hash equal; otherwise
-      results are nondeterminate, and we fail bootstrap comparison.  */
-   gcc_assert (hash (p1) == hash (p2));
- #endif
- 
-   return true;
- }
- 
- struct gimplify_ctx
- {
-   struct gimplify_ctx *prev_context;
- 
-   vec<gimple> bind_expr_stack;
-   tree temps;
-   gimple_seq conditional_cleanups;
-   tree exit_label;
-   tree return_temp;
- 
-   vec<tree> case_labels;
-   /* The formal temporary table.  Should this be persistent?  */
-   hash_table <gimplify_hasher> temp_htab;
- 
-   int conditions;
-   bool save_stack;
-   bool into_ssa;
-   bool allow_rhs_cond_expr;
-   bool in_cleanup_point_expr;
- };
- 
- /* Return true if gimplify_one_sizepos doesn't need to gimplify
-    expr (when in TYPE_SIZE{,_UNIT} and similar type/decl size/bitsize
-    fields).  */
- static inline bool
- is_gimple_sizepos (tree expr)
- {
-   /* gimplify_one_sizepos doesn't need to do anything if the value isn't there,
-      is constant, or contains A PLACEHOLDER_EXPR.  We also don't want to do
-      anything if it's already a VAR_DECL.  If it's a VAR_DECL from another
-      function, the gimplifier will want to replace it with a new variable,
-      but that will cause problems if this type is from outside the function.
-      It's OK to have that here.  */
-   return (expr == NULL_TREE
- 	  || TREE_CONSTANT (expr)
- 	  || TREE_CODE (expr) == VAR_DECL
- 	  || CONTAINS_PLACEHOLDER_P (expr));
- }                                        
- 
  /* Get the number of the next statement uid to be allocated.  */
  static inline unsigned int
  gimple_stmt_max_uid (struct function *fn)
--- 847,852 ----
*************** inc_gimple_stmt_max_uid (struct function
*** 948,954 ****
  }
  
  /* Miscellaneous helpers.  */
- struct gimplify_omp_ctx;
  extern tree canonicalize_cond_expr_cond (tree);
  extern void dump_decl_set (FILE *, bitmap);
  extern bool nonfreeing_call_p (gimple);
--- 869,874 ----
*************** gimple_expr_type (const_gimple stmt)
*** 5201,5216 ****
      return void_type_node;
  }
  
- enum gsi_iterator_update
- {
-   GSI_NEW_STMT,		/* Only valid when single statement is added, move
- 			   iterator to it.  */
-   GSI_SAME_STMT,	/* Leave the iterator at the same statement.  */
-   GSI_CONTINUE_LINKING	/* Move iterator to whatever position is suitable
- 			   for linking other statements in the same
- 			   direction.  */
- };
- 
  gimple gimple_call_copy_skip_args (gimple, bitmap);
  
  /* Enum and arrays used for allocation stats.  Keep in sync with
--- 5121,5126 ----
Index: gimple-iterator.h
===================================================================
*** gimple-iterator.h	(revision 204763)
--- gimple-iterator.h	(working copy)
*************** typedef struct gimple_stmt_iterator_d
*** 35,40 ****
--- 35,50 ----
    basic_block bb;
  } gimple_stmt_iterator;
   
+ enum gsi_iterator_update
+ {
+   GSI_NEW_STMT,		/* Only valid when single statement is added, move
+ 			   iterator to it.  */
+   GSI_SAME_STMT,	/* Leave the iterator at the same statement.  */
+   GSI_CONTINUE_LINKING	/* Move iterator to whatever position is suitable
+ 			   for linking other statements in the same
+ 			   direction.  */
+ };
+ 
  extern void gsi_insert_seq_before_without_update (gimple_stmt_iterator *,
  						  gimple_seq,
  						  enum gsi_iterator_update);
Index: gimplify-be.c
===================================================================
*** gimplify-be.c	(revision 0)
--- gimplify-be.c	(working copy)
***************
*** 0 ****
--- 1,148 ----
+ /* Tree lowering to gimple for backend use only.  
+    This converts the GENERIC functions-as-trees tree representation into
+    the GIMPLE form.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+    Major work done by Sebastian Pop <s.pop@laposte.net>,
+    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
+ 
+ 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/>.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tree.h"
+ #include "gimple.h"
+ #include "gimple-iterator.h"
+ #include "gimplify.h"
+ #include "gimplify-be.h"
+ #include "gimple-ssa.h"
+ #include "tree-ssanames.h"
+ 
+ 
+ /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
+    the predicate that will hold for the result.  If VAR is not NULL, make the
+    base variable of the final destination be VAR if suitable.  */
+ 
+ tree
+ force_gimple_operand_1 (tree expr, gimple_seq *stmts,
+ 			gimple_predicate gimple_test_f, tree var)
+ {
+   enum gimplify_status ret;
+   struct gimplify_ctx gctx;
+   location_t saved_location;
+ 
+   *stmts = NULL;
+ 
+   /* gimple_test_f might be more strict than is_gimple_val, make
+      sure we pass both.  Just checking gimple_test_f doesn't work
+      because most gimple predicates do not work recursively.  */
+   if (is_gimple_val (expr)
+       && (*gimple_test_f) (expr))
+     return expr;
+ 
+   push_gimplify_context (&gctx);
+   gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
+   gimplify_ctxp->allow_rhs_cond_expr = true;
+   saved_location = input_location;
+   input_location = UNKNOWN_LOCATION;
+ 
+   if (var)
+     {
+       if (gimplify_ctxp->into_ssa
+ 	  && is_gimple_reg (var))
+ 	var = make_ssa_name (var, NULL);
+       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
+     }
+ 
+   if (TREE_CODE (expr) != MODIFY_EXPR
+       && TREE_TYPE (expr) == void_type_node)
+     {
+       gimplify_and_add (expr, stmts);
+       expr = NULL_TREE;
+     }
+   else
+     {
+       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
+       gcc_assert (ret != GS_ERROR);
+     }
+ 
+   input_location = saved_location;
+   pop_gimplify_context (NULL);
+ 
+   return expr;
+ }
+ 
+ /* Expand EXPR to list of gimple statements STMTS.  If SIMPLE is true,
+    force the result to be either ssa_name or an invariant, otherwise
+    just force it to be a rhs expression.  If VAR is not NULL, make the
+    base variable of the final destination be VAR if suitable.  */
+ 
+ tree
+ force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
+ {
+   return force_gimple_operand_1 (expr, stmts,
+ 				 simple ? is_gimple_val : is_gimple_reg_rhs,
+ 				 var);
+ }
+ 
+ /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
+    and VAR.  If some statements are produced, emits them at GSI.
+    If BEFORE is true.  the statements are appended before GSI, otherwise
+    they are appended after it.  M specifies the way GSI moves after
+    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
+ 
+ tree
+ force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
+ 			    gimple_predicate gimple_test_f,
+ 			    tree var, bool before,
+ 			    enum gsi_iterator_update m)
+ {
+   gimple_seq stmts;
+ 
+   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
+ 
+   if (!gimple_seq_empty_p (stmts))
+     {
+       if (before)
+ 	gsi_insert_seq_before (gsi, stmts, m);
+       else
+ 	gsi_insert_seq_after (gsi, stmts, m);
+     }
+ 
+   return expr;
+ }
+ 
+ /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
+    If SIMPLE is true, force the result to be either ssa_name or an invariant,
+    otherwise just force it to be a rhs expression.  If some statements are
+    produced, emits them at GSI.  If BEFORE is true, the statements are
+    appended before GSI, otherwise they are appended after it.  M specifies
+    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
+    are the usual values).  */
+ 
+ tree
+ force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
+ 			  bool simple_p, tree var, bool before,
+ 			  enum gsi_iterator_update m)
+ {
+   return force_gimple_operand_gsi_1 (gsi, expr,
+ 				     simple_p
+ 				     ? is_gimple_val : is_gimple_reg_rhs,
+ 				     var, before, m);
+ }
+ 
+ 
Index: gimplify.c
===================================================================
*** gimplify.c	(revision 204763)
--- gimplify.c	(working copy)
*************** along with GCC; see the file COPYING3.
*** 23,30 ****
  #include "config.h"
  #include "system.h"
  #include "coretypes.h"
- #include "tm.h"
  #include "tree.h"
  #include "gimplify.h"
  #include "gimple-iterator.h"
  #include "tree-iterator.h"
--- 23,30 ----
  #include "config.h"
  #include "system.h"
  #include "coretypes.h"
  #include "tree.h"
+ #include "gimple.h"
  #include "gimplify.h"
  #include "gimple-iterator.h"
  #include "tree-iterator.h"
*************** along with GCC; see the file COPYING3.
*** 37,60 ****
  #include "tree-cfg.h"
  #include "tree-ssanames.h"
  #include "tree-ssa.h"
- #include "timevar.h"
- #include "hashtab.h"
- #include "flags.h"
- #include "function.h"
- #include "ggc.h"
  #include "diagnostic-core.h"
  #include "target.h"
- #include "pointer-set.h"
  #include "splay-tree.h"
- #include "vec.h"
  #include "omp-low.h"
  #include "gimple-low.h"
  #include "cilk.h"
  
  #include "langhooks-def.h"	/* FIXME: for lhd_set_decl_assembler_name */
  #include "tree-pass.h"		/* FIXME: only for PROP_gimple_any */
- #include "expr.h"
- #include "tm_p.h"
  
  enum gimplify_omp_var_data
  {
--- 37,51 ----
*************** struct gimplify_omp_ctx
*** 102,108 ****
    bool combined_loop;
  };
  
! static struct gimplify_ctx *gimplify_ctxp;
  static struct gimplify_omp_ctx *gimplify_omp_ctxp;
  
  
--- 93,99 ----
    bool combined_loop;
  };
  
! struct gimplify_ctx *gimplify_ctxp;
  static struct gimplify_omp_ctx *gimplify_omp_ctxp;
  
  
*************** gimple_regimplify_operands (gimple stmt,
*** 8759,8876 ****
    pop_gimplify_context (NULL);
  }
  
- /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
-    the predicate that will hold for the result.  If VAR is not NULL, make the
-    base variable of the final destination be VAR if suitable.  */
- 
- tree
- force_gimple_operand_1 (tree expr, gimple_seq *stmts,
- 			gimple_predicate gimple_test_f, tree var)
- {
-   enum gimplify_status ret;
-   struct gimplify_ctx gctx;
-   location_t saved_location;
- 
-   *stmts = NULL;
- 
-   /* gimple_test_f might be more strict than is_gimple_val, make
-      sure we pass both.  Just checking gimple_test_f doesn't work
-      because most gimple predicates do not work recursively.  */
-   if (is_gimple_val (expr)
-       && (*gimple_test_f) (expr))
-     return expr;
- 
-   push_gimplify_context (&gctx);
-   gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
-   gimplify_ctxp->allow_rhs_cond_expr = true;
-   saved_location = input_location;
-   input_location = UNKNOWN_LOCATION;
- 
-   if (var)
-     {
-       if (gimplify_ctxp->into_ssa
- 	  && is_gimple_reg (var))
- 	var = make_ssa_name (var, NULL);
-       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
-     }
- 
-   if (TREE_CODE (expr) != MODIFY_EXPR
-       && TREE_TYPE (expr) == void_type_node)
-     {
-       gimplify_and_add (expr, stmts);
-       expr = NULL_TREE;
-     }
-   else
-     {
-       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
-       gcc_assert (ret != GS_ERROR);
-     }
- 
-   input_location = saved_location;
-   pop_gimplify_context (NULL);
- 
-   return expr;
- }
- 
- /* Expand EXPR to list of gimple statements STMTS.  If SIMPLE is true,
-    force the result to be either ssa_name or an invariant, otherwise
-    just force it to be a rhs expression.  If VAR is not NULL, make the
-    base variable of the final destination be VAR if suitable.  */
- 
- tree
- force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
- {
-   return force_gimple_operand_1 (expr, stmts,
- 				 simple ? is_gimple_val : is_gimple_reg_rhs,
- 				 var);
- }
- 
- /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
-    and VAR.  If some statements are produced, emits them at GSI.
-    If BEFORE is true.  the statements are appended before GSI, otherwise
-    they are appended after it.  M specifies the way GSI moves after
-    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
- 
- tree
- force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
- 			    gimple_predicate gimple_test_f,
- 			    tree var, bool before,
- 			    enum gsi_iterator_update m)
- {
-   gimple_seq stmts;
- 
-   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
- 
-   if (!gimple_seq_empty_p (stmts))
-     {
-       if (before)
- 	gsi_insert_seq_before (gsi, stmts, m);
-       else
- 	gsi_insert_seq_after (gsi, stmts, m);
-     }
- 
-   return expr;
- }
- 
- /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
-    If SIMPLE is true, force the result to be either ssa_name or an invariant,
-    otherwise just force it to be a rhs expression.  If some statements are
-    produced, emits them at GSI.  If BEFORE is true, the statements are
-    appended before GSI, otherwise they are appended after it.  M specifies
-    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
-    are the usual values).  */
- 
- tree
- force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
- 			  bool simple_p, tree var, bool before,
- 			  enum gsi_iterator_update m)
- {
-   return force_gimple_operand_gsi_1 (gsi, expr,
- 				     simple_p
- 				     ? is_gimple_val : is_gimple_reg_rhs,
- 				     var, before, m);
- }
- 
  /* Return a dummy expression of type TYPE in order to keep going after an
     error.  */
  
--- 8750,8755 ----
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 204763)
--- Makefile.in	(working copy)
*************** OBJS = \
*** 1242,1247 ****
--- 1242,1248 ----
  	gimple-streamer-out.o \
  	gimple-walk.o \
  	gimplify.o \
+ 	gimplify-be.o \
  	godump.o \
  	graph.o \
  	graphds.o \