Patchwork [cxx-conversion] gimplify_ctx::temp_htab hash table

login
register
mail settings
Submitter Lawrence Crowl
Date Dec. 2, 2012, 1:44 a.m.
Message ID <CAGqM8fbRr5csj1292_5a1O=Uj5pTYOu-ud7a6kN+fk91S+BvRA@mail.gmail.com>
Download mbox | patch
Permalink /patch/203170/
State New
Headers show

Comments

Lawrence Crowl - Dec. 2, 2012, 1:44 a.m.
Change gimplify.c gimplify_ctx::temp_htab hash table from htab_t to
hash_table.

Move struct gimple_temp_hash_elt and struct gimplify_ctx to a new
gimplify-ctx.h, because they are used few places.


Tested on x86-64.

Okay for branch?
Diego Novillo - Dec. 3, 2012, 8 p.m.
On 2012-12-01 20:44 , Lawrence Crowl wrote:

> Index: gcc/gimple-fold.c
> ===================================================================
> --- gcc/gimple-fold.c	(revision 193902)
> +++ gcc/gimple-fold.c	(working copy)
> @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.
>   #include "tree-ssa-propagate.h"
>   #include "target.h"
>   #include "gimple-fold.h"
> +#include "gimplify-ctx.h"
>
>   /* Return true when DECL can be referenced from current unit.
>      FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
> Index: gcc/tree-mudflap.c
> ===================================================================
> --- gcc/tree-mudflap.c	(revision 193902)
> +++ gcc/tree-mudflap.c	(working copy)
> @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.
>   #include "ggc.h"
>   #include "cgraph.h"
>   #include "gimple.h"
> +#include "gimplify-ctx.h"
>
>   extern void add_bb_to_loop (basic_block, struct loop *);
>
> Index: gcc/tree-inline.c
> ===================================================================
> --- gcc/tree-inline.c	(revision 193902)
> +++ gcc/tree-inline.c	(working copy)
> @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.
>   #include "value-prof.h"
>   #include "tree-pass.h"
>   #include "target.h"
> +#include "gimplify-ctx.h"

I don't follow.  It seems that factoring into gimplify-ctx.h does not 
actually buy much.  The files using it are just including *another* 
file.  Whereas previously, they were getting that content from gimple.h.

Unless we can stop including gimple.h from these files, I don't see a 
lot of gain in this factoring.  Am I missing something?


Diego.
Lawrence Crowl - Dec. 3, 2012, 8:14 p.m.
On 12/3/12, Diego Novillo <dnovillo@google.com> wrote:
> On 2012-12-01 20:44 , Lawrence Crowl wrote:
>> Index: gcc/gimple-fold.c
>> ===================================================================
>> --- gcc/gimple-fold.c	(revision 193902)
>> +++ gcc/gimple-fold.c	(working copy)
>> @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.
>>   #include "tree-ssa-propagate.h"
>>   #include "target.h"
>>   #include "gimple-fold.h"
>> +#include "gimplify-ctx.h"
>>
>>   /* Return true when DECL can be referenced from current unit.
>>      FROM_DECL (if non-null) specify constructor of variable DECL was
>> taken from.
>> Index: gcc/tree-mudflap.c
>> ===================================================================
>> --- gcc/tree-mudflap.c	(revision 193902)
>> +++ gcc/tree-mudflap.c	(working copy)
>> @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.
>>   #include "ggc.h"
>>   #include "cgraph.h"
>>   #include "gimple.h"
>> +#include "gimplify-ctx.h"
>>
>>   extern void add_bb_to_loop (basic_block, struct loop *);
>>
>> Index: gcc/tree-inline.c
>> ===================================================================
>> --- gcc/tree-inline.c	(revision 193902)
>> +++ gcc/tree-inline.c	(working copy)
>> @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.
>>   #include "value-prof.h"
>>   #include "tree-pass.h"
>>   #include "target.h"
>> +#include "gimplify-ctx.h"
>
> I don't follow.  It seems that factoring into gimplify-ctx.h does
> not actually buy much.  The files using it are just including
> *another* file.  Whereas previously, they were getting that
> content from gimple.h.
>
> Unless we can stop including gimple.h from these files, I don't
> see a lot of gain in this factoring.  Am I missing something?

There at least 70 files that include gimple.h, and only 5 that need
gimple-ctx.h.  By splitting it out, at least 65 files will not need
to parse the gimplify_ctx struct, the gimple_temp_hash_elt struct,
the gimplify_hasher template struct, and may not need to include
hash-table.h.

It's all about avoiding superfluous compilation in other files.
Richard Guenther - Dec. 4, 2012, 9:23 a.m.
On Mon, Dec 3, 2012 at 9:14 PM, Lawrence Crowl <crowl@googlers.com> wrote:
> On 12/3/12, Diego Novillo <dnovillo@google.com> wrote:
>> On 2012-12-01 20:44 , Lawrence Crowl wrote:
>>> Index: gcc/gimple-fold.c
>>> ===================================================================
>>> --- gcc/gimple-fold.c        (revision 193902)
>>> +++ gcc/gimple-fold.c        (working copy)
>>> @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.
>>>   #include "tree-ssa-propagate.h"
>>>   #include "target.h"
>>>   #include "gimple-fold.h"
>>> +#include "gimplify-ctx.h"
>>>
>>>   /* Return true when DECL can be referenced from current unit.
>>>      FROM_DECL (if non-null) specify constructor of variable DECL was
>>> taken from.
>>> Index: gcc/tree-mudflap.c
>>> ===================================================================
>>> --- gcc/tree-mudflap.c       (revision 193902)
>>> +++ gcc/tree-mudflap.c       (working copy)
>>> @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.
>>>   #include "ggc.h"
>>>   #include "cgraph.h"
>>>   #include "gimple.h"
>>> +#include "gimplify-ctx.h"
>>>
>>>   extern void add_bb_to_loop (basic_block, struct loop *);
>>>
>>> Index: gcc/tree-inline.c
>>> ===================================================================
>>> --- gcc/tree-inline.c        (revision 193902)
>>> +++ gcc/tree-inline.c        (working copy)
>>> @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.
>>>   #include "value-prof.h"
>>>   #include "tree-pass.h"
>>>   #include "target.h"
>>> +#include "gimplify-ctx.h"
>>
>> I don't follow.  It seems that factoring into gimplify-ctx.h does
>> not actually buy much.  The files using it are just including
>> *another* file.  Whereas previously, they were getting that
>> content from gimple.h.
>>
>> Unless we can stop including gimple.h from these files, I don't
>> see a lot of gain in this factoring.  Am I missing something?
>
> There at least 70 files that include gimple.h, and only 5 that need
> gimple-ctx.h.  By splitting it out, at least 65 files will not need
> to parse the gimplify_ctx struct, the gimple_temp_hash_elt struct,
> the gimplify_hasher template struct, and may not need to include
> hash-table.h.
>
> It's all about avoiding superfluous compilation in other files.

But it's backward - gimple.h is the core file as it provides GIMPLE.
The gimplifier and its context certainly requires to know about
GIMPLE.

Btw, if we still want to split it I'd rather have gimplify.h (and also
put all exports from gimplify.c there, not only gimplify_ctx).  Still
I don't think it would buy us much.

Richard.

> --
> Lawrence Crowl
Diego Novillo - Dec. 4, 2012, 2:06 p.m.
On Tue, Dec 4, 2012 at 4:23 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Mon, Dec 3, 2012 at 9:14 PM, Lawrence Crowl <crowl@googlers.com> wrote:
>> On 12/3/12, Diego Novillo <dnovillo@google.com> wrote:
>>> On 2012-12-01 20:44 , Lawrence Crowl wrote:
>>>> Index: gcc/gimple-fold.c
>>>> ===================================================================
>>>> --- gcc/gimple-fold.c        (revision 193902)
>>>> +++ gcc/gimple-fold.c        (working copy)
>>>> @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.
>>>>   #include "tree-ssa-propagate.h"
>>>>   #include "target.h"
>>>>   #include "gimple-fold.h"
>>>> +#include "gimplify-ctx.h"
>>>>
>>>>   /* Return true when DECL can be referenced from current unit.
>>>>      FROM_DECL (if non-null) specify constructor of variable DECL was
>>>> taken from.
>>>> Index: gcc/tree-mudflap.c
>>>> ===================================================================
>>>> --- gcc/tree-mudflap.c       (revision 193902)
>>>> +++ gcc/tree-mudflap.c       (working copy)
>>>> @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.
>>>>   #include "ggc.h"
>>>>   #include "cgraph.h"
>>>>   #include "gimple.h"
>>>> +#include "gimplify-ctx.h"
>>>>
>>>>   extern void add_bb_to_loop (basic_block, struct loop *);
>>>>
>>>> Index: gcc/tree-inline.c
>>>> ===================================================================
>>>> --- gcc/tree-inline.c        (revision 193902)
>>>> +++ gcc/tree-inline.c        (working copy)
>>>> @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.
>>>>   #include "value-prof.h"
>>>>   #include "tree-pass.h"
>>>>   #include "target.h"
>>>> +#include "gimplify-ctx.h"
>>>
>>> I don't follow.  It seems that factoring into gimplify-ctx.h does
>>> not actually buy much.  The files using it are just including
>>> *another* file.  Whereas previously, they were getting that
>>> content from gimple.h.
>>>
>>> Unless we can stop including gimple.h from these files, I don't
>>> see a lot of gain in this factoring.  Am I missing something?
>>
>> There at least 70 files that include gimple.h, and only 5 that need
>> gimple-ctx.h.  By splitting it out, at least 65 files will not need
>> to parse the gimplify_ctx struct, the gimple_temp_hash_elt struct,
>> the gimplify_hasher template struct, and may not need to include
>> hash-table.h.
>>
>> It's all about avoiding superfluous compilation in other files.
>
> But it's backward - gimple.h is the core file as it provides GIMPLE.
> The gimplifier and its context certainly requires to know about
> GIMPLE.
>
> Btw, if we still want to split it I'd rather have gimplify.h (and also
> put all exports from gimplify.c there, not only gimplify_ctx).  Still
> I don't think it would buy us much.

We talked offline about this with Lawrence.  I was not too convinced
about adding this new header file, it seemed forced but I was
struggling with a better alternative.  Perhaps gimplify.h is a better
way, but I'm not sure either.

We decided that since it's in the branch, it may not matter much for
now.  However, another thing occurred to me in the meantime: merges.
The new file will probably cause merge problems.  If we are not
completely convinced that it's a good change, we are making our life
harder for no gain.

Lawrence, you're going to hate me, but would you mind just leaving the
ctx structure in gimple.h for now?  Sorry!  I think it's going to be
easier to just leave it there for now until we come up with a good
split for the constructs in that file.


Diego.
Lawrence Crowl - Dec. 4, 2012, 7:11 p.m.
On 12/4/12, Diego Novillo <dnovillo@google.com> wrote:
> On Tue, Dec 4, 2012 at 4:23 AM, Richard Biener
> <richard.guenther@gmail.com> wrote:
>> On Mon, Dec 3, 2012 at 9:14 PM, Lawrence Crowl <crowl@googlers.com>
>> wrote:
>>> On 12/3/12, Diego Novillo <dnovillo@google.com> wrote:
>>>> On 2012-12-01 20:44 , Lawrence Crowl wrote:
>>>>> Index: gcc/gimple-fold.c
>>>>> ===================================================================
>>>>> --- gcc/gimple-fold.c        (revision 193902)
>>>>> +++ gcc/gimple-fold.c        (working copy)
>>>>> @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.
>>>>>   #include "tree-ssa-propagate.h"
>>>>>   #include "target.h"
>>>>>   #include "gimple-fold.h"
>>>>> +#include "gimplify-ctx.h"
>>>>>
>>>>>   /* Return true when DECL can be referenced from current unit.
>>>>>      FROM_DECL (if non-null) specify constructor of variable DECL was
>>>>> taken from.
>>>>> Index: gcc/tree-mudflap.c
>>>>> ===================================================================
>>>>> --- gcc/tree-mudflap.c       (revision 193902)
>>>>> +++ gcc/tree-mudflap.c       (working copy)
>>>>> @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.
>>>>>   #include "ggc.h"
>>>>>   #include "cgraph.h"
>>>>>   #include "gimple.h"
>>>>> +#include "gimplify-ctx.h"
>>>>>
>>>>>   extern void add_bb_to_loop (basic_block, struct loop *);
>>>>>
>>>>> Index: gcc/tree-inline.c
>>>>> ===================================================================
>>>>> --- gcc/tree-inline.c        (revision 193902)
>>>>> +++ gcc/tree-inline.c        (working copy)
>>>>> @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.
>>>>>   #include "value-prof.h"
>>>>>   #include "tree-pass.h"
>>>>>   #include "target.h"
>>>>> +#include "gimplify-ctx.h"
>>>>
>>>> I don't follow.  It seems that factoring into gimplify-ctx.h does
>>>> not actually buy much.  The files using it are just including
>>>> *another* file.  Whereas previously, they were getting that
>>>> content from gimple.h.
>>>>
>>>> Unless we can stop including gimple.h from these files, I don't
>>>> see a lot of gain in this factoring.  Am I missing something?
>>>
>>> There at least 70 files that include gimple.h, and only 5 that need
>>> gimple-ctx.h.  By splitting it out, at least 65 files will not need
>>> to parse the gimplify_ctx struct, the gimple_temp_hash_elt struct,
>>> the gimplify_hasher template struct, and may not need to include
>>> hash-table.h.
>>>
>>> It's all about avoiding superfluous compilation in other files.
>>
>> But it's backward - gimple.h is the core file as it provides GIMPLE.
>> The gimplifier and its context certainly requires to know about
>> GIMPLE.
>>
>> Btw, if we still want to split it I'd rather have gimplify.h (and also
>> put all exports from gimplify.c there, not only gimplify_ctx).  Still
>> I don't think it would buy us much.
>
> We talked offline about this with Lawrence.  I was not too convinced
> about adding this new header file, it seemed forced but I was
> struggling with a better alternative.  Perhaps gimplify.h is a better
> way, but I'm not sure either.
>
> We decided that since it's in the branch, it may not matter much for
> now.  However, another thing occurred to me in the meantime: merges.
> The new file will probably cause merge problems.  If we are not
> completely convinced that it's a good change, we are making our life
> harder for no gain.
>
> Lawrence, you're going to hate me, but would you mind just leaving the
> ctx structure in gimple.h for now?  Sorry!  I think it's going to be
> easier to just leave it there for now until we come up with a good
> split for the constructs in that file.

Okay, I'll do that.

Patch

Index: gcc/ChangeLog

2012-11-30  Lawrence Crowl  <crowl@google.com>

	* gimple.h (struct gimplify_ctx): Move to gimplify-ctx.h.
	(push_gimplify_context): Likewise.
	(pop_gimplify_context): Likewise.

	* gimplify-ctx.h: New.
	(struct gimple_temp_hash_elt): Move from gimplify.c.
	(class gimplify_hasher): New.
	(struct gimplify_ctx): Move from gimple.h.
	(htab_t gimplify_ctx::temp_htab):
	Change type to hash_table.  Update dependent calls and types.

	* gimple-fold.c: Include gimplify-ctx.h.

	* gimplify.c: Include gimplify-ctx.h.
	(struct gimple_temp_hash_elt): Move to gimplify-ctx.h.
	(htab_t gimplify_ctx::temp_htab):
	Update dependent calls and types for new type hash_table.
	(gimple_tree_hash): Move into gimplify_hasher in gimplify-ctx.h.
	(gimple_tree_eq): Move into gimplify_hasher in gimplify-ctx.h.

	* omp-low.c: Include gimplify-ctx.h.

	* tree-inline.c: Include gimplify-ctx.h.

	* tree-mudflap.c: Include gimplify-ctx.h.

	* Makefile.in: Update to changes above.

Index: gcc/omp-low.c
===================================================================
--- gcc/omp-low.c	(revision 193902)
+++ gcc/omp-low.c	(working copy)
@@ -29,6 +29,7 @@  along with GCC; see the file COPYING3.
 #include "tree.h"
 #include "rtl.h"
 #include "gimple.h"
+#include "gimplify-ctx.h"
 #include "tree-iterator.h"
 #include "tree-inline.h"
 #include "langhooks.h"
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c	(revision 193902)
+++ gcc/gimplify.c	(working copy)
@@ -44,6 +44,7 @@  along with GCC; see the file COPYING3.
 #include "splay-tree.h"
 #include "vec.h"
 #include "gimple.h"
+#include "gimplify-ctx.h"

 #include "langhooks-def.h"	/* FIXME: for lhd_set_decl_assembler_name */
 #include "tree-pass.h"		/* FIXME: only for PROP_gimple_any */
@@ -88,15 +89,6 @@  static struct gimplify_ctx *gimplify_ctx
 static struct gimplify_omp_ctx *gimplify_omp_ctxp;


-/* Formal (expression) temporary table handling: multiple occurrences of
-   the same scalar expression are evaluated into the same temporary.  */
-
-typedef struct gimple_temp_hash_elt
-{
-  tree val;   /* Key */
-  tree temp;  /* Value */
-} elt_t;
-
 /* Forward declaration.  */
 static enum gimplify_status gimplify_compound_expr (tree *,
gimple_seq *, bool);

@@ -131,40 +123,6 @@  mark_addressable (tree x)
     }
 }

-/* Return a hash value for a formal temporary table entry.  */
-
-static hashval_t
-gimple_tree_hash (const void *p)
-{
-  tree t = ((const elt_t *) p)->val;
-  return iterative_hash_expr (t, 0);
-}
-
-/* Compare two formal temporary table entries.  */
-
-static int
-gimple_tree_eq (const void *p1, const void *p2)
-{
-  tree t1 = ((const elt_t *) p1)->val;
-  tree t2 = ((const elt_t *) p2)->val;
-  enum tree_code code = TREE_CODE (t1);
-
-  if (TREE_CODE (t2) != code
-      || TREE_TYPE (t1) != TREE_TYPE (t2))
-    return 0;
-
-  if (!operand_equal_p (t1, t2, 0))
-    return 0;
-
-#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 (gimple_tree_hash (p1) == gimple_tree_hash (p2));
-#endif
-
-  return 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.
@@ -242,8 +200,8 @@  pop_gimplify_context (gimple body)
   else
     record_vars (c->temps);

-  if (c->temp_htab)
-    htab_delete (c->temp_htab);
+  if (c->temp_htab.is_created ())
+    c->temp_htab.dispose ();
 }

 /* Push a GIMPLE_BIND tuple onto the stack of bindings.  */
@@ -586,23 +544,22 @@  lookup_tmp_var (tree val, bool is_formal
   else
     {
       elt_t elt, *elt_p;
-      void **slot;
+      elt_t **slot;

       elt.val = val;
-      if (gimplify_ctxp->temp_htab == NULL)
-        gimplify_ctxp->temp_htab
-	  = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
-      slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
+      if (!gimplify_ctxp->temp_htab.is_created ())
+        gimplify_ctxp->temp_htab.create (1000);
+      slot = gimplify_ctxp->temp_htab.find_slot (&elt, INSERT);
       if (*slot == NULL)
 	{
 	  elt_p = XNEW (elt_t);
 	  elt_p->val = val;
 	  elt_p->temp = ret = create_tmp_from_val (val, is_formal);
-	  *slot = (void *) elt_p;
+	  *slot = elt_p;
 	}
       else
 	{
-	  elt_p = (elt_t *) *slot;
+	  elt_p = *slot;
           ret = elt_p->temp;
 	}
     }
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c	(revision 193902)
+++ gcc/gimple-fold.c	(working copy)
@@ -30,6 +30,7 @@  along with GCC; see the file COPYING3.
 #include "tree-ssa-propagate.h"
 #include "target.h"
 #include "gimple-fold.h"
+#include "gimplify-ctx.h"

 /* Return true when DECL can be referenced from current unit.
    FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
Index: gcc/tree-mudflap.c
===================================================================
--- gcc/tree-mudflap.c	(revision 193902)
+++ gcc/tree-mudflap.c	(working copy)
@@ -43,6 +43,7 @@  along with GCC; see the file COPYING3.
 #include "ggc.h"
 #include "cgraph.h"
 #include "gimple.h"
+#include "gimplify-ctx.h"

 extern void add_bb_to_loop (basic_block, struct loop *);

Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c	(revision 193902)
+++ gcc/tree-inline.c	(working copy)
@@ -48,6 +48,7 @@  along with GCC; see the file COPYING3.
 #include "value-prof.h"
 #include "tree-pass.h"
 #include "target.h"
+#include "gimplify-ctx.h"

 #include "rtl.h"	/* FIXME: For asm_str_count.  */

Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 193902)
+++ gcc/Makefile.in	(working copy)
@@ -877,6 +877,7 @@  BASIC_BLOCK_H = basic-block.h $(PREDICT_
 GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \
 	$(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \
 	tree-ssa-alias.h $(INTERNAL_FN_H)
+GIMPLIFY_CTX_H = gimplify-ctx.h $(TREE_H) $(HASH_TABLE_H)
 TRANS_MEM_H = trans-mem.h
 GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
 COVERAGE_H = coverage.h $(GCOV_IO_H)
@@ -2214,7 +2215,7 @@  tree-dump.o: tree-dump.c $(CONFIG_H) $(S
 tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(RTL_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \
    $(HASHTAB_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \
-   intl.h $(FUNCTION_H) $(GIMPLE_H) \
+   intl.h $(FUNCTION_H) $(GIMPLE_H) $(GIMPLIFY_CTX_H) \
    debug.h $(DIAGNOSTIC_H) $(EXCEPT_H) $(TREE_FLOW_H) tree-iterator.h
tree-mudflap.h \
    $(IPA_PROP_H) value-prof.h $(TREE_PASS_H) $(TARGET_H) \
    $(TREE_PRETTY_PRINT_H)
@@ -2512,14 +2513,15 @@  tree-optimize.o : tree-optimize.c $(TREE
    $(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H)

 gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
-   $(DIAGNOSTIC_H) $(TREE_INLINE_H) langhooks.h \
+   $(GIMPLIFY_CTX_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) langhooks.h \
    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
    coretypes.h $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) \
    $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H)
$(DIAGNOSTIC_CORE_H) $(OPTABS_H) \
    $(SPLAY_TREE_H) $(VEC_H) tree-iterator.h $(TREE_PASS_H)
$(TREE_PRETTY_PRINT_H)
 gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h
-gimple-fold.o : gimple-fold.c $(TREE_FLOW_H) $(CONFIG_H) coretypes.h
dumpfile.h \
+gimple-fold.o : gimple-fold.c $(TREE_FLOW_H) $(CONFIG_H) coretypes.h \
+   $(GIMPLIFY_CTX_H) dumpfile.h \
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(GGC_H) \
    $(FUNCTION_H) $(TM_H) $(BASIC_BLOCK_H) langhooks.h \
    tree-ssa-propagate.h $(FLAGS_H) $(TARGET_H) gimple-fold.h
@@ -2529,7 +2531,8 @@  gimple-low.o : gimple-low.c $(CONFIG_H)
    $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(TREE_PASS_H) \
    $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) tree-iterator.h langhooks.h
 omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
-   $(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_CORE_H) \
+   $(RTL_H) $(GIMPLE_H) $(GIMPLIFY_CTX_H) $(TREE_INLINE_H) langhooks.h \
+   $(DIAGNOSTIC_CORE_H) \
    $(TREE_FLOW_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \
    $(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \
    $(CFGLOOP_H) tree-iterator.h gt-omp-low.h
@@ -2634,8 +2637,9 @@  gimple-pretty-print.o : gimple-pretty-pr
    $(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_FLOW_H) \
    $(TM_H) $(GIMPLE_H) value-prof.h \
    $(TRANS_MEM_H) $(GIMPLE_PRETTY_PRINT_H)
-tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
-   $(GIMPLE_H) $(DIAGNOSTIC_H) $(DEMANGLE_H) $(HASHTAB_H) langhooks.h
tree-mudflap.h \
+tree-mudflap.o : tree-mudflap.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
+   $(TREE_INLINE_H) $(GIMPLE_H) $(GIMPLIFY_CTX_H) $(DIAGNOSTIC_H) \
+   $(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
    $(TM_H) coretypes.h $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \
    gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \
    $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h
Index: gcc/gimplify-ctx.h
===================================================================
--- gcc/gimplify-ctx.h	(revision 0)
+++ gcc/gimplify-ctx.h	(revision 0)
@@ -0,0 +1,101 @@ 
+/* Gimplify_ctx structure definitions.
+
+   Copyright 2012 Free Software Foundation, Inc.
+   Contributed by Lawrence Crowl <crowl@google.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/>.  */
+
+#ifndef GCC_GIMPLIFY_CTX_H
+#define GCC_GIMPLIFY_CTX_H
+
+#include "tree.h"
+#include "hash-table.h"
+
+/* Formal (expression) temporary table handling: multiple occurrences of
+   the same scalar expression are evaluated into the same temporary.  */
+
+typedef struct gimple_temp_hash_elt
+{
+  tree val;   /* Key */
+  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 0;
+
+  if (!operand_equal_p (t1, t2, 0))
+    return 0;
+
+#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 (gimple_tree_hash (p1) == gimple_tree_hash (p2));
+#endif
+
+  return 1;
+}
+
+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 void push_gimplify_context (struct gimplify_ctx *);
+extern void pop_gimplify_context (gimple);
+
+#endif  /* GCC_GIMPLIFY_CTX_H */
Index: gcc/gimple.h
===================================================================
--- gcc/gimple.h	(revision 193902)
+++ gcc/gimple.h	(working copy)
@@ -936,27 +936,6 @@  enum gimplify_status {
   GS_ALL_DONE	= 1	/* The expression is fully gimplified.  */
 };

-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?  */
-  htab_t 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).  */
@@ -981,8 +960,6 @@  extern void gimplify_type_sizes (tree, g
 extern void gimplify_one_sizepos (tree *, gimple_seq *);
 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.  */