This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] [alias, middle-end] Alias and data dependency export


Hello,

Richard Guenther wrote:
On Wed, 3 Jun 2009, Andrey Belevantsev wrote:

Richard Guenther wrote:
I think we should instead benchmark getting rid of TMR_ORIGINAL
completely.  We should be able to initialize mem_attrs from the
other fields of the TMR.  But that can be done as a followup if
the special casing is not too ugly for now (was there supposed to
be a patch attached?).
The special casing is in the lines of

*************** ptr_deref_may_alias_decl_p (tree ptr, tr
*** 175,189 ****
        || TREE_CODE (ptr) == INTEGER_CST)
      return true;

!   gcc_assert (TREE_CODE (ptr) == SSA_NAME
! 	      && (TREE_CODE (decl) == VAR_DECL
! 		  || TREE_CODE (decl) == PARM_DECL
! 		  || TREE_CODE (decl) == RESULT_DECL));

    /* Non-aliased variables can not be pointed to.  */
    if (!may_be_aliased (decl))
      return false;

    /* If we do not have useful points-to information for this pointer
       we cannot disambiguate anything else.  */
    pi = SSA_NAME_PTR_INFO (ptr);
--- 175,194 ----
        || TREE_CODE (ptr) == INTEGER_CST)
      return true;

!   gcc_assert (TREE_CODE (decl) == VAR_DECL
!               || TREE_CODE (decl) == PARM_DECL
!               || TREE_CODE (decl) == RESULT_DECL);

    /* Non-aliased variables can not be pointed to.  */
    if (!may_be_aliased (decl))
      return false;

+   if (TREE_CODE (ptr) != SSA_NAME)
+     {
+       gcc_assert (current_ir_type () != IR_GIMPLE);
+       return true;
+     }
+
    /* If we do not have useful points-to information for this pointer
       we cannot disambiguate anything else.  */
    pi = SSA_NAME_PTR_INFO (ptr);

and similarly for ptr_derefs_may_alias_p.

This could be avoided by not generating MEM_ORIG_EXPR from TMR_ORIGINAL at all if they have INDIRECT_REF_P as base (with the same effect, aliasing everything).
I have added this hunk in the patch, but it may not be needed as I now filter trees before feeding them to the oracle anyways. The current patch doesn't change the oracle at all, which is what you probably wanted ;)

The current patch I have is attached.  This is the cut-down version without
ddg export (I have just edited the diff though to ease review, so the full
compilable patch with ddg export is also attached for reference).
As described above, again I have attached two patches: full patch with ddg-export and hand-edited diff with removed ddg-export.


The partitioning is handled there as the last thing in partiotion_stack_vars, see update_alias_info_with_stack_vars. The bases are rewritten during expand, seems like the problems I had were because of wrong ordering of the call to my code. Other stuff you mentioned is fixed as well.
This still applies.


Some unsolved problems that may be done as a followup:


1.  The patch of not adding stack vars for SSA_NAMEs breaks a stack protector
test, ssp-2.c.  What happens that in the following function:
This is solved after discussion of the above patch on gcc-patches@ -- as this change breaks stack protector, is it not desirable, so I don't have to change anything in the alias-export patch, as SSA_NAMEs are filtered there already.


2. MEM_EXPR/MEM_ORIG_EXPR problem.  As we determined that the former is used
for debugging, it seems that both should stay, but the usage of MEM_EXPR
should be audited, and its application for debugging and for aliasing should
be separated: debugging-related code goes to MEM_EXPR/MEM_OFFSET, while
aliasing-related stuff (including nonoverlapping_memrefs_p, which probably can
be simplified given the tree oracle) goes to MEM_ORIG_EXPR.  Then we can
rename the fields to whatever we want to reflect this.
This remains to be done (we have kind of agreed that it is possible to do this as a followup).

The patch still bootstraps and regtests on x86-64 including ada, I see builtin-math-6.c failed in comparison with latest test results, but this doesn't look like it's related (I will recheck of course).

Also, I will be traveling until next Monday with no email access.

Andrey

2009-06-30  Andrey Belevantsev  <abel@ispras.ru>
        Dmitry Melnik  <dm@ispras.ru>
        Alexander Monakov  <amonakov@ispras.ru>
        Dmitry Zhurikhin  <zhur@ispras.ru>

* Makefile.in (OBJS-common): Add alias-export.o.
(tree-ssa.o): Depend on alias-export.h.
(tree-ssa-alias.o): Likewise.
(emit-rtl.o): Likewise.
(alias.o): Likewise.
(final.o): Likewise.
* alias-export.c: New file.
* alias-export.h: New file.
* rtl.h (struct mem_attrs): New field orig_expr.
(MEM_ORIG_EXPR): New access macro.
* tree-ssa-uncprop.c (pass_uncprop): Set TODO_rebuild_alias.
* tree-ssa.c (delete_tree_ssa): Remove the FIXME loop.
* tree-ssa-alias.c: (ptr_deref_may_alias_decl_p): Adjust assert to include RTL case.
(ptr_derefs_may_alias_p): Adjust assert to include RTL case.
* cfgexpand.c: Include alias-export.h.
(union_stack_vars): Promote TREE_ADDRESSABLE to the merged partition
representative.
(update_alias_info_with_stack_vars): New.
(partition_stack_vars): Call it.
(gimple_expand_cfg): Also set MEM_ORIG_EXPR to NULL.
* expr.c (expand_expr_real_1): When expanding TARGET_MEM_REF,
set MEM_ORIG_EXPR to its TMR_ORIGINAL.
* function.c (assign_parms_unsplit_complex): Also set MEM_ORIG_EXPR
for parm.
* emit-rtl.c: Include alias-export.h.
(mem_attrs_htab_hash, get_mem_attrs, set_mem_attrs_from_reg,
set_mem_alias_set, set_mem_align, set_mem_expr, set_mem_offset,
set_mem_size, change_address, offset_address,
widen_memory_access, get_spill_slot_decl,
set_mem_attrs_for_spill): Account for MEM_ORIG_EXPR.
(set_mem_orig_expr): New.
(set_mem_attributes_minus_bitpos): Record MEM_ORIG_EXPR.
(adjust_address_1): When we make a wider address, nullify MEM_ORIG_EXPR.
* emit-rtl.h (set_mem_orig_expr): Export.
* final.c: Include alias-export.h.
(rest_of_clean_state): Free exported information. Call delete_tree_ssa from here.
* alias.c: Include alias-export.h.
(query_alias_export_info): New.
(true_dependence): Use query_alias_export_info.
(canon_true_dependence, write_dependence_p): Likewise.
* dbgcnt.def (alias_export): New counter.
* builtins.c (get_memory_rtx): Also set MEM_ORIG_EXPR to NULL.
diff -cprdN -x .svn -x TAGS trunk/gcc/Makefile.in alias-export/gcc/Makefile.in
*** trunk/gcc/Makefile.in	Tue Jun 30 15:09:53 2009
--- alias-export/gcc/Makefile.in	Tue Jun 30 15:34:03 2009
*************** OBJS-common = \
*** 1112,1117 ****
--- 1112,1118 ----
  	insn-recog.o \
  	$(GGC) \
  	alias.o \
+ 	alias-export.o \
  	alloc-pool.o \
  	auto-inc-dec.o \
  	bb-reorder.o \
*************** convert.o: convert.c $(CONFIG_H) $(SYSTE
*** 2120,2125 ****
--- 2121,2133 ----
  
  double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
  
+ alias-export.o : alias-export.c alias-export.h 	\
+    $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \
+    $(FUNCTION_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(GGC_H) output.h $(TREE_FLOW_H) \
+    $(RTL_H) $(TREE_PASS_H) $(FLAGS_H) tree-ssa-alias.h vec.h bitmap.h \
+    pointer-set.h dbgcnt.h $(CFGLOOP_H) tree-data-ref.h tree-scalar-evolution.h \
+    $(DIAGNOSTIC_H) statistics.h
+ 
  langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) $(TOPLEV_H) $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \
     langhooks.h $(TARGET_H) $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) \
*************** tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $
*** 2157,2163 ****
     $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
     $(TREE_DUMP_H) langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
     $(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \
!    $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H)
  tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
--- 2165,2171 ----
     $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
     $(TREE_DUMP_H) langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
     $(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \
!    $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) alias-export.h
  tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
*************** tree-ssa-loop-ivopts.o : tree-ssa-loop-i
*** 2349,2355 ****
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
     $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
!    tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h $(TARGET_H)
  tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(GIMPLE_H) \
     output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H)
--- 2357,2363 ----
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
     $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
!    tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h $(TARGET_H) alias-export.h
  tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(GIMPLE_H) \
     output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H)
*************** tree-ssa-alias.o : tree-ssa-alias.c $(TR
*** 2371,2377 ****
     $(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h \
     $(TREE_DUMP_H) $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     hard-reg-set.h $(GIMPLE_H) vec.h \
!    $(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h
  tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
     $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) \
--- 2379,2385 ----
     $(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h \
     $(TREE_DUMP_H) $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     hard-reg-set.h $(GIMPLE_H) vec.h \
!    $(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h alias-export.h
  tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
     $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) \
*************** emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SY
*** 2653,2659 ****
     $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
     $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
     $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
!    $(REAL_H) $(DF_H)
  real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
  dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	$(TREE_H) \
--- 2661,2667 ----
     $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
     $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
     $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
!    $(REAL_H) $(DF_H) alias-export.h pointer-set.h
  real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
  dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	$(TREE_H) \
*************** loop-unswitch.o : loop-unswitch.c $(CONF
*** 2918,2924 ****
  loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) $(PARAMS_H) \
     output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \
!    $(OBSTACK_H)
  dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(TOPLEV_H) \
     $(TIMEVAR_H) graphds.h vecprim.h pointer-set.h
--- 2926,2932 ----
  loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) $(PARAMS_H) \
     output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \
!    $(OBSTACK_H) alias-export.h 
  dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(TOPLEV_H) \
     $(TIMEVAR_H) graphds.h vecprim.h pointer-set.h
*************** reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H
*** 2977,2983 ****
  alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \
     $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \
!    langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \
     $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H)
  stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \
--- 2985,2991 ----
  alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \
     $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \
!    langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) alias-export.h \
     $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H)
  stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \
*************** modulo-sched.o : modulo-sched.c $(DDG_H)
*** 3034,3040 ****
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(EXCEPT_H) $(RECOG_H) \
     $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(PARAMS_H) \
     cfghooks.h $(GCOV_IO_H) hard-reg-set.h $(TM_H) $(TIMEVAR_H) $(TREE_PASS_H) \
!    $(DF_H) $(DBGCNT_H)
  haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
     $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) output.h \
--- 3042,3048 ----
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(EXCEPT_H) $(RECOG_H) \
     $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(PARAMS_H) \
     cfghooks.h $(GCOV_IO_H) hard-reg-set.h $(TM_H) $(TIMEVAR_H) $(TREE_PASS_H) \
!    $(DF_H) $(DBGCNT_H) alias-export.h
  haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
     $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) output.h \
*************** sel-sched.o : sel-sched.c $(CONFIG_H) $(
*** 3060,3066 ****
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
     $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) $(TREE_PASS_H)  \
     $(SCHED_INT_H) $(GGC_H) $(TREE_H) $(LANGHOOKS_DEF_H) \
!    $(SEL_SCHED_IR_H) $(SEL_SCHED_DUMP_H) sel-sched.h
  sel-sched-dump.o : sel-sched-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
--- 3068,3074 ----
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
     $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) $(TREE_PASS_H)  \
     $(SCHED_INT_H) $(GGC_H) $(TREE_H) $(LANGHOOKS_DEF_H) \
!    $(SEL_SCHED_IR_H) $(SEL_SCHED_DUMP_H) sel-sched.h alias-export.h
  sel-sched-dump.o : sel-sched-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
*************** final.o : final.c $(CONFIG_H) $(SYSTEM_H
*** 3077,3083 ****
     $(EXCEPT_H) debug.h xcoffout.h $(TOPLEV_H) reload.h dwarf2out.h \
     $(TREE_PASS_H) $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) \
     $(CFGLAYOUT_H) dbxout.h $(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) \
!    $(DF_H) vecprim.h $(GGC_H) $(CFGLOOP_H) $(PARAMS_H)
  recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) output.h reload.h \
--- 3085,3091 ----
     $(EXCEPT_H) debug.h xcoffout.h $(TOPLEV_H) reload.h dwarf2out.h \
     $(TREE_PASS_H) $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) \
     $(CFGLAYOUT_H) dbxout.h $(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) \
!    $(DF_H) vecprim.h $(GGC_H) $(CFGLOOP_H) $(PARAMS_H) alias-export.h
  recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) output.h reload.h \
diff -cprdN -x .svn -x TAGS trunk/gcc/alias-export.c alias-export/gcc/alias-export.c
*** trunk/gcc/alias-export.c	Thu Jan  1 03:00:00 1970
--- alias-export/gcc/alias-export.c	Thu Jun  4 17:57:05 2009
***************
*** 0 ****
--- 1,630 ----
+ /* Export of alias/data dependency information to RTL.  
+    Copyright (C) 2009 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/>.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "tree.h"
+ #include "tm_p.h"
+ #include "basic-block.h"
+ #include "timevar.h"
+ #include "diagnostic.h"
+ #include "ggc.h"
+ #include "output.h"
+ #include "function.h"
+ #include "tree-dump.h"
+ #include "gimple.h"
+ #include "tree-flow.h"
+ #include "tree-pass.h"
+ #include "tree-ssa-alias.h"
+ #include "vec.h"
+ #include "bitmap.h"
+ #include "alias-export.h"
+ #include "emit-rtl.h"
+ #include "rtl.h"
+ #include "pointer-set.h"
+ #include "dbgcnt.h"
+ #include "cfgloop.h"
+ #include "tree-data-ref.h"
+ #include "tree-scalar-evolution.h"
+ #include "statistics.h"
+ 
+ /* The map of decls to stack partitions.  */
+ static struct pointer_map_t *decls_to_partitions = NULL;
+ 
+ /* The map of decls to artificial ssa-names that point to all partition 
+    of the decl.  */
+ static struct pointer_map_t *decls_to_pointers = NULL;
+ 
+ /* Alias export statistics counter.  */
+ static unsigned int alias_export_disambiguations = 0;
+ 
+ 
+ /* If some of PID->PT.VARS variables got partitioned, add all partition 
+    vars to that bitmap.  */
+ static void
+ add_partitioned_vars_to_ptset (struct pt_solution *pi)
+ {
+   if (pi->vars)
+     {
+       bitmap_iterator bi;
+       unsigned i;
+       bitmap *part, temp = NULL;
+       
+       EXECUTE_IF_SET_IN_BITMAP (pi->vars, 0, i, bi)
+         if ((part = (bitmap *) pointer_map_contains (decls_to_partitions,
+                                                      referenced_var (i))))
+           {
+             if (!temp)
+               temp = BITMAP_GGC_ALLOC ();
+             bitmap_ior_into (temp, *part);
+           }
+       if (temp)
+         {
+           bitmap_ior_into (temp, pi->vars);
+           pi->vars = temp;
+         }
+     }
+ }
+ 
+ /* Fixup stack-partitioned base var in EXPR.  */
+ static tree
+ rewrite_partitioned_mem_expr (tree expr)
+ {
+   tree *pbase, *pname;
+   
+   if (!decls_to_pointers)
+     return expr;
+   
+   pbase = &expr;
+   while (handled_component_p (*pbase))
+     pbase = &TREE_OPERAND (*pbase, 0);
+   if (DECL_P (*pbase)
+       && (pname = (tree *) pointer_map_contains (decls_to_pointers, *pbase)))
+     *pbase = build1 (INDIRECT_REF, TREE_TYPE (*pbase), *pname);
+ 
+   return expr;
+ }
+ 
+ /* Record the final points-to set for EXPR and unshare it.  Returns 
+    the unshared expression or NULL_TREE, if EXPR cannot be used for 
+    alias/ddg export later.  */
+ tree
+ unshare_and_record_pta_info (tree expr)
+ {
+   tree old_expr;
+ 
+   /* No point saving anything for unhandled stuff.  */
+   if (! (SSA_VAR_P (expr)
+          || handled_component_p (expr)
+          || INDIRECT_REF_P (expr)))
+     return NULL_TREE;
+ 
+   /* Unshare the tree and do replacement in ddg info.  */
+   old_expr = expr;
+   expr = unshare_expr (expr);
+   if (flag_ddg_export)
+     replace_var_in_datarefs (old_expr, expr);
+ 
+   expr = rewrite_partitioned_mem_expr (expr);
+   return expr;
+ }
+ 
+ /* Save stack partitions.  DECL is in the partition represented by 
+    PART bitmap.  NAME is a pointer that points to all partition.  */
+ void
+ record_stack_var_partition_for (tree decl, bitmap part, tree name)
+ {
+   if (! decls_to_partitions)
+     {
+       decls_to_partitions = pointer_map_create ();
+       decls_to_pointers = pointer_map_create ();
+     }
+   *((bitmap *) pointer_map_insert (decls_to_partitions, decl)) = part;
+   *((tree *) pointer_map_insert (decls_to_pointers, decl)) = name;
+ }
+ 
+ /* Update pta info so that stack partitioning is reflected in it.  */
+ void
+ update_pta_with_stack_partitions (void)
+ {
+   unsigned i;
+ 
+   if (! decls_to_partitions)
+     return;
+   
+   for (i = 1; i < num_ssa_names; i++)
+     {
+       tree name = ssa_name (i);
+       struct ptr_info_def *pid;
+ 
+       if (name && ((pid = SSA_NAME_PTR_INFO (name)) != NULL))
+         add_partitioned_vars_to_ptset (&pid->pt);
+     }
+ 
+   add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped);
+   add_partitioned_vars_to_ptset (&cfun->gimple_df->callused);
+ }
+ 
+ /* Functions to be called when needed to use exported information.  */
+ 
+ /* Returns false if we shouldn't pass REF to the oracle.  Now only checks
+    that INDIRECT_REFs have sensible bases.  */
+ static bool 
+ handled_by_oracle_p (tree ref)
+ {
+   tree base = get_base_address (ref);
+   return (base
+           && (! INDIRECT_REF_P (base)
+               || TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME));
+ }
+ 
+ /* Main function to ask saved information about if REF1 and REF2 may
+    alias or not.  MEM1 and MEM2 are corresponding mems.  */
+ bool
+ alias_export_may_alias_p (tree ref1, tree ref2)
+ {
+   if (! dbg_cnt (alias_export))
+     return true;
+   if (! handled_by_oracle_p (ref1) || ! handled_by_oracle_p (ref2))
+     return true;
+   if (! refs_may_alias_p (ref1, ref2))
+     {
+       alias_export_disambiguations++;
+       return false;
+     }
+   return true;
+ }
+ 
+ /* Free exported info.  */
+ void
+ free_alias_export_info (void)
+ {
+   statistics_counter_event (cfun, "Alias export disambiguations", 
+                             alias_export_disambiguations);
+   alias_export_disambiguations = 0;
+ 
+   if (decls_to_partitions)
+     {
+       pointer_map_destroy (decls_to_partitions);
+       decls_to_partitions = NULL;
+       pointer_map_destroy (decls_to_pointers);
+       decls_to_pointers = NULL;
+     }
+ }
+ 
diff -cprdN -x .svn -x TAGS trunk/gcc/alias-export.h alias-export/gcc/alias-export.h
*** trunk/gcc/alias-export.h	Thu Jan  1 03:00:00 1970
--- alias-export/gcc/alias-export.h	Tue Jun  2 19:31:25 2009
***************
*** 0 ****
--- 1,35 ----
+ /* Export of alias information to RTL.  
+    Copyright (C) 2009 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_ALIAS_EXPORT_H
+ #define GCC_ALIAS_EXPORT_H
+ 
+ extern bool alias_export_may_alias_p (tree, tree);
+ extern tree unshare_and_record_pta_info (tree);
+ extern void record_stack_var_partition_for (tree, bitmap, tree);
+ extern void update_pta_with_stack_partitions (void);
+ extern void free_alias_export_info (void);
+ #endif /* GCC_ALIAS_EXPORT_H */
diff -cprdN -x .svn -x TAGS trunk/gcc/alias.c alias-export/gcc/alias.c
*** trunk/gcc/alias.c	Tue Jun 30 15:09:52 2009
--- alias-export/gcc/alias.c	Tue Jun 30 15:26:08 2009
*************** along with GCC; see the file COPYING3.  
*** 46,51 ****
--- 46,52 ----
  #include "tree-pass.h"
  #include "ipa-type-escape.h"
  #include "df.h"
+ #include "alias-export.h"
  
  /* The aliasing API provided here solves related but different problems:
  
*************** DEF_VEC_ALLOC_P(alias_set_entry,gc);
*** 249,254 ****
--- 250,279 ----
  /* The splay-tree used to store the various alias set entries.  */
  static GTY (()) VEC(alias_set_entry,gc) *alias_sets;
  
+ 
+ /* Check MEM_ORIG_EXPRs of two MEMs and if they are present query saved alias/ddg
+    information whether they may alias or not.  */
+ static bool
+ query_alias_export_info (const_rtx x, const_rtx mem)
+ {
+   tree x_orig_expr = MEM_ORIG_EXPR (x);
+   tree mem_orig_expr = MEM_ORIG_EXPR (mem);
+   bool ret = true;
+ 
+   if (x_orig_expr != NULL 
+       && mem_orig_expr != NULL
+       && x_orig_expr != mem_orig_expr)
+     {
+       if (flag_alias_export == 1)
+         ret = alias_export_may_alias_p (x_orig_expr, mem_orig_expr);
+     }
+ 
+   return ret;
+ }
+ 
  /* Returns a pointer to the alias set entry for ALIAS_SET, if there is
     such an entry, or NULL otherwise.  */
  
*************** true_dependence (const_rtx mem, enum mac
*** 2175,2181 ****
    mem_addr = canon_rtx (mem_addr);
  
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
! 			    SIZE_FOR_MODE (x), x_addr, 0))
      return 0;
  
    if (aliases_everything_p (x))
--- 2203,2212 ----
    mem_addr = canon_rtx (mem_addr);
  
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
!                             SIZE_FOR_MODE (x), x_addr, 0))
!     return 0;
! 
!   if (! query_alias_export_info (x, mem))
      return 0;
  
    if (aliases_everything_p (x))
*************** canon_true_dependence (const_rtx mem, en
*** 2239,2245 ****
  
    x_addr = canon_rtx (x_addr);
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
! 			    SIZE_FOR_MODE (x), x_addr, 0))
      return 0;
  
    if (aliases_everything_p (x))
--- 2270,2279 ----
  
    x_addr = canon_rtx (x_addr);
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
!                             SIZE_FOR_MODE (x), x_addr, 0))
!     return 0;
! 
!   if (! query_alias_export_info (x, mem))
      return 0;
  
    if (aliases_everything_p (x))
*************** write_dependence_p (const_rtx mem, const
*** 2308,2315 ****
    x_addr = canon_rtx (x_addr);
    mem_addr = canon_rtx (mem_addr);
  
!   if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
! 			   SIZE_FOR_MODE (x), x_addr, 0))
      return 0;
  
    fixed_scalar
--- 2342,2352 ----
    x_addr = canon_rtx (x_addr);
    mem_addr = canon_rtx (mem_addr);
  
!   if (! memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
!                             SIZE_FOR_MODE (x), x_addr, 0))
!     return 0;
! 
!   if (! query_alias_export_info (x, mem))
      return 0;
  
    fixed_scalar
diff -cprdN -x .svn -x TAGS trunk/gcc/builtins.c alias-export/gcc/builtins.c
*** trunk/gcc/builtins.c	Tue Jun 30 15:09:50 2009
--- alias-export/gcc/builtins.c	Tue Jun 30 15:19:43 2009
*************** get_memory_rtx (tree exp, tree len)
*** 1230,1235 ****
--- 1230,1236 ----
  	}
        set_mem_alias_set (mem, 0);
        set_mem_size (mem, NULL_RTX);
+       set_mem_orig_expr (mem, NULL_TREE);
      }
  
    return mem;
diff -cprdN -x .svn -x TAGS trunk/gcc/cfgexpand.c alias-export/gcc/cfgexpand.c
*** trunk/gcc/cfgexpand.c	Mon Jun 22 12:03:55 2009
--- alias-export/gcc/cfgexpand.c	Tue Jun 30 15:33:20 2009
*************** along with GCC; see the file COPYING3.  
*** 42,47 ****
--- 42,48 ----
  #include "tree-inline.h"
  #include "value-prof.h"
  #include "target.h"
+ #include "alias-export.h"
  #include "ssaexpand.h"
  
  
*************** stack_var_size_cmp (const void *a, const
*** 784,789 ****
--- 785,841 ----
    return 0;
  }
  
+ /* Update points-to sets based on partition info, so we can use them on RTL.
+    The bitmaps representing stack partitions will be saved until expand,
+    where partitioned decls used as bases in memory expressions will be 
+    rewritten.  */
+ 
+ static void
+ update_alias_info_with_stack_vars (void)
+ {
+   size_t i, j;
+ 
+   for (i = 0; i < stack_vars_num; i++)
+     {
+       bitmap temp = NULL;
+       tree name, var, type;
+       struct ptr_info_def *pid;
+ 
+       /* Not interested in partitions with single variable.  */
+       if (stack_vars[i].representative != i
+           || stack_vars[i].next == EOC)
+         continue;
+ 
+       /* Create bitmaps representing partitions.  They will be used for 
+          points-to sets later, so use GGC alloc.  */
+       temp = BITMAP_GGC_ALLOC ();
+       for (j = i; j != EOC; j = stack_vars[j].next)
+         if (DECL_P (stack_vars[j].decl)
+             && referenced_var_lookup_safe (DECL_UID (stack_vars[j].decl)))
+           bitmap_set_bit (temp, DECL_UID (stack_vars[j].decl));
+       if (bitmap_empty_p (temp))
+         continue;
+ 
+       /* Create an SSA_NAME that points to the partition for later 
+          base rewriting.  */
+       type = build_pointer_type (TREE_TYPE (stack_vars[i].decl));
+       var = create_tmp_var (type, NULL);
+       add_referenced_var (var);
+       name = make_ssa_name (var, NULL);
+       pid = get_ptr_info (name);
+       pid->pt.vars = temp;
+ 
+       for (j = i; j != EOC; j = stack_vars[j].next)
+         if (DECL_P (stack_vars[j].decl)
+             && bitmap_bit_p (temp, DECL_UID (stack_vars[j].decl)))
+           record_stack_var_partition_for (stack_vars[j].decl, temp, name);
+     }
+ 
+   /* Make all points-to sets that contain one of partition members
+      contain all partition.  */
+   update_pta_with_stack_partitions ();
+ }
+ 
  /* A subroutine of partition_stack_vars.  The UNION portion of a UNION/FIND
     partitioning algorithm.  Partitions A and B are known to be non-conflicting.
     Merge them into a single partition A.
*************** static void
*** 796,811 ****
--- 848,867 ----
  union_stack_vars (size_t a, size_t b, HOST_WIDE_INT offset)
  {
    size_t i, last;
+   bool adressable;
  
    /* Update each element of partition B with the given offset,
       and merge them into partition A.  */
+   adressable = false;
    for (last = i = b; i != EOC; last = i, i = stack_vars[i].next)
      {
        stack_vars[i].offset += offset;
        stack_vars[i].representative = a;
+       adressable |= TREE_ADDRESSABLE (stack_vars[i].decl);
      }
    stack_vars[last].next = stack_vars[a].next;
    stack_vars[a].next = b;
+   TREE_ADDRESSABLE (stack_vars[a].decl) |= adressable;
  
    /* Update the required alignment of partition A to account for B.  */
    if (stack_vars[a].alignb < stack_vars[b].alignb)
*************** partition_stack_vars (void)
*** 903,908 ****
--- 959,967 ----
  	    break;
  	}
      }
+ 
+   if (flag_alias_export)
+     update_alias_info_with_stack_vars ();
  }
  
  /* A debugging aid for expand_used_vars.  Dump the generated partitions.  */
*************** gimple_expand_cfg (void)
*** 2492,2498 ****
    crtl->preferred_stack_boundary = STACK_BOUNDARY;
    cfun->cfg->max_jumptable_ents = 0;
  
- 
    /* Expand the variables recorded during gimple lowering.  */
    expand_used_vars ();
  
--- 2551,2556 ----
*************** gimple_expand_cfg (void)
*** 2533,2542 ****
  	 to select one of the potentially many RTLs for one DECL.  Instead
  	 of doing that we simply reset the MEM_EXPR of the RTL in question,
  	 then nobody can get at it and hence nobody can call DECL_RTL on it.  */
!       if (!DECL_RTL_SET_P (var))
! 	{
! 	  if (MEM_P (SA.partition_to_pseudo[i]))
! 	    set_mem_expr (SA.partition_to_pseudo[i], NULL);
  	}
      }
  
--- 2591,2601 ----
  	 to select one of the potentially many RTLs for one DECL.  Instead
  	 of doing that we simply reset the MEM_EXPR of the RTL in question,
  	 then nobody can get at it and hence nobody can call DECL_RTL on it.  */
!       if (!DECL_RTL_SET_P (var)
!           && MEM_P (SA.partition_to_pseudo[i]))
!         {
!           set_mem_expr (SA.partition_to_pseudo[i], NULL);
!           set_mem_orig_expr (SA.partition_to_pseudo[i], NULL);
  	}
      }
  
diff -cprdN -x .svn -x TAGS trunk/gcc/common.opt alias-export/gcc/common.opt
*** trunk/gcc/common.opt	Mon Jun 22 12:00:22 2009
--- alias-export/gcc/common.opt	Tue Jun 30 15:33:33 2009
*************** fexpensive-optimizations
*** 506,511 ****
--- 506,519 ----
  Common Report Var(flag_expensive_optimizations) Optimization
  Perform a number of minor, expensive optimizations
  
+ falias-export
+ Common Report Var(flag_alias_export) Optimization Init(1)
+ Save alias information on Tree-SSA to be used on RTL
+ 
  fexcess-precision=
  Common Joined RejectNegative
  -fexcess-precision=[fast|standard]	Specify handling of excess floating-point precision
diff -cprdN -x .svn -x TAGS trunk/gcc/dbgcnt.def alias-export/gcc/dbgcnt.def
*** trunk/gcc/dbgcnt.def	Tue Apr 28 11:40:36 2009
--- alias-export/gcc/dbgcnt.def	Thu May  7 12:24:04 2009
*************** echo ubound: $ub
*** 141,146 ****
--- 141,147 ----
  */
  
  /* Debug counter definitions.  */
+ DEBUG_COUNTER (alias_export)
  DEBUG_COUNTER (auto_inc_dec)
  DEBUG_COUNTER (ccp)
  DEBUG_COUNTER (cfg_cleanup)
diff -cprdN -x .svn -x TAGS trunk/gcc/emit-rtl.c alias-export/gcc/emit-rtl.c
*** trunk/gcc/emit-rtl.c	Tue Jun 30 15:09:52 2009
--- alias-export/gcc/emit-rtl.c	Tue Jun 30 15:26:27 2009
*************** along with GCC; see the file COPYING3.  
*** 58,63 ****
--- 58,64 ----
  #include "langhooks.h"
  #include "tree-pass.h"
  #include "df.h"
+ #include "alias-export.h"
  
  /* Commonly used modes.  */
  
*************** static int const_fixed_htab_eq (const vo
*** 192,199 ****
  static rtx lookup_const_fixed (rtx);
  static hashval_t mem_attrs_htab_hash (const void *);
  static int mem_attrs_htab_eq (const void *, const void *);
! static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int,
! 				 enum machine_mode);
  static hashval_t reg_attrs_htab_hash (const void *);
  static int reg_attrs_htab_eq (const void *, const void *);
  static reg_attrs *get_reg_attrs (tree, int);
--- 193,200 ----
  static rtx lookup_const_fixed (rtx);
  static hashval_t mem_attrs_htab_hash (const void *);
  static int mem_attrs_htab_eq (const void *, const void *);
! static mem_attrs *get_mem_attrs (alias_set_type, tree, tree, rtx, rtx, 
! 				 unsigned int, enum machine_mode);
  static hashval_t reg_attrs_htab_hash (const void *);
  static int reg_attrs_htab_eq (const void *, const void *);
  static reg_attrs *get_reg_attrs (tree, int);
*************** mem_attrs_htab_hash (const void *x)
*** 295,301 ****
    return (p->alias ^ (p->align * 1000)
  	  ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
  	  ^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
! 	  ^ (size_t) iterative_hash_expr (p->expr, 0));
  }
  
  /* Returns nonzero if the value represented by X (which is really a
--- 296,304 ----
    return (p->alias ^ (p->align * 1000)
  	  ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
  	  ^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
! 	  ^ (size_t) iterative_hash_expr (p->expr, 
!                                           iterative_hash_expr (p->orig_expr, 
!                                                                0)));
  }
  
  /* Returns nonzero if the value represented by X (which is really a
*************** mem_attrs_htab_eq (const void *x, const 
*** 312,318 ****
  	  && p->size == q->size && p->align == q->align
  	  && (p->expr == q->expr
  	      || (p->expr != NULL_TREE && q->expr != NULL_TREE
! 		  && operand_equal_p (p->expr, q->expr, 0))));
  }
  
  /* Allocate a new mem_attrs structure and insert it into the hash table if
--- 315,324 ----
  	  && p->size == q->size && p->align == q->align
  	  && (p->expr == q->expr
  	      || (p->expr != NULL_TREE && q->expr != NULL_TREE
! 		  && operand_equal_p (p->expr, q->expr, 0)))
!           && (p->orig_expr == q->orig_expr
!               || (p->orig_expr != NULL_TREE && q->orig_expr != NULL_TREE
!                   && operand_equal_p (p->orig_expr, q->orig_expr, 0))));
  }
  
  /* Allocate a new mem_attrs structure and insert it into the hash table if
*************** mem_attrs_htab_eq (const void *x, const 
*** 320,327 ****
     MEM of mode MODE.  */
  
  static mem_attrs *
! get_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
! 	       unsigned int align, enum machine_mode mode)
  {
    mem_attrs attrs;
    void **slot;
--- 326,333 ----
     MEM of mode MODE.  */
  
  static mem_attrs *
! get_mem_attrs (alias_set_type alias, tree expr, tree orig_expr, rtx offset, 
! 	       rtx size, unsigned int align, enum machine_mode mode)
  {
    mem_attrs attrs;
    void **slot;
*************** get_mem_attrs (alias_set_type alias, tre
*** 329,335 ****
    /* If everything is the default, we can just return zero.
       This must match what the corresponding MEM_* macros return when the
       field is not present.  */
!   if (alias == 0 && expr == 0 && offset == 0
        && (size == 0
  	  || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
        && (STRICT_ALIGNMENT && mode != BLKmode
--- 335,341 ----
    /* If everything is the default, we can just return zero.
       This must match what the corresponding MEM_* macros return when the
       field is not present.  */
!   if (alias == 0 && expr == 0 && orig_expr == 0 && offset == 0
        && (size == 0
  	  || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
        && (STRICT_ALIGNMENT && mode != BLKmode
*************** get_mem_attrs (alias_set_type alias, tre
*** 338,343 ****
--- 344,350 ----
  
    attrs.alias = alias;
    attrs.expr = expr;
+   attrs.orig_expr = orig_expr;
    attrs.offset = offset;
    attrs.size = size;
    attrs.align = align;
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1588,1593 ****
--- 1595,1601 ----
  {
    alias_set_type alias = MEM_ALIAS_SET (ref);
    tree expr = MEM_EXPR (ref);
+   tree orig_expr = NULL_TREE;
    rtx offset = MEM_OFFSET (ref);
    rtx size = MEM_SIZE (ref);
    unsigned int align = MEM_ALIGN (ref);
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1653,1658 ****
--- 1661,1668 ----
        tree base;
        bool align_computed = false;
  
+       orig_expr = t;
+ 
        if (TREE_THIS_VOLATILE (t))
  	MEM_VOLATILE_P (ref) = 1;
  
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1837,1847 ****
  	 we're overlapping.  */
        offset = NULL;
        expr = NULL;
      }
- 
-   /* Now set the attributes we computed above.  */
    MEM_ATTRS (ref)
!     = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref));
  
    /* If this is already known to be a scalar or aggregate, we are done.  */
    if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
--- 1847,1865 ----
  	 we're overlapping.  */
        offset = NULL;
        expr = NULL;
+       orig_expr = NULL;
+     }
+   
+   /* Now set the attributes we computed above, but unshare orig_expr first.  */
+   if (orig_expr)
+     {
+       if (flag_alias_export)
+         orig_expr = unshare_and_record_pta_info (orig_expr);
+       else
+         orig_expr = NULL_TREE;
      }
    MEM_ATTRS (ref)
!     = get_mem_attrs (alias, expr, orig_expr, offset, size, align, GET_MODE (ref));
  
    /* If this is already known to be a scalar or aggregate, we are done.  */
    if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
*************** set_mem_alias_set (rtx mem, alias_set_ty
*** 1871,1879 ****
    gcc_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
  #endif
  
!   MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
! 				   MEM_SIZE (mem), MEM_ALIGN (mem),
! 				   GET_MODE (mem));
  }
  
  /* Set the alignment of MEM to ALIGN bits.  */
--- 1889,1897 ----
    gcc_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
  #endif
  
!   MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_ORIG_EXPR (mem),
! 				   MEM_OFFSET (mem), MEM_SIZE (mem), 
! 				   MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Set the alignment of MEM to ALIGN bits.  */
*************** void
*** 1882,1889 ****
  set_mem_align (rtx mem, unsigned int align)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_OFFSET (mem), MEM_SIZE (mem), align,
! 				   GET_MODE (mem));
  }
  
  /* Set the expr for MEM to EXPR.  */
--- 1900,1907 ----
  set_mem_align (rtx mem, unsigned int align)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_ORIG_EXPR (mem), MEM_OFFSET (mem), 
! 				   MEM_SIZE (mem), align, GET_MODE (mem));
  }
  
  /* Set the expr for MEM to EXPR.  */
*************** set_mem_align (rtx mem, unsigned int ali
*** 1891,1899 ****
  void
  set_mem_expr (rtx mem, tree expr)
  {
    MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
! 		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Set the offset of MEM to OFFSET.  */
--- 1909,1941 ----
  void
  set_mem_expr (rtx mem, tree expr)
  {
+   tree orig_expr = MEM_ORIG_EXPR (mem);
+ 
+   /* If MEM_EXPR changes, clear MEM_ORIG_EXPR.  If we still can preserve it,
+      we insert set_mem_orig_expr call right after this function call.  */
+   if (!expr || !mem_expr_equal_p (MEM_EXPR (mem), expr))
+     orig_expr = NULL_TREE;
+   
    MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), expr, orig_expr,
! 		     MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem), 
! 		     GET_MODE (mem));
! }
! 
! 
! /* Set the original expr for MEM to ORIG_EXPR.  */
! 
! void
! set_mem_orig_expr (rtx mem, tree orig_expr)
! {
!   if (orig_expr 
!       && currently_expanding_to_rtl
!       && (flag_alias_export || flag_ddg_export))
!     orig_expr = unshare_and_record_pta_info (orig_expr);
!   MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem), orig_expr,
! 		     MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem), 
! 		     GET_MODE (mem));
  }
  
  /* Set the offset of MEM to OFFSET.  */
*************** set_mem_expr (rtx mem, tree expr)
*** 1901,1909 ****
  void
  set_mem_offset (rtx mem, rtx offset)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   offset, MEM_SIZE (mem), MEM_ALIGN (mem),
! 				   GET_MODE (mem));
  }
  
  /* Set the size of MEM to SIZE.  */
--- 1943,1958 ----
  void
  set_mem_offset (rtx mem, rtx offset)
  {
+   tree orig_expr = MEM_ORIG_EXPR (mem);
+ 
+   /* If MEM_EXPR changes, clear MEM_ORIG_EXPR.  If we still can preserve it,
+      we insert set_mem_orig_expr call right after this function call.  */
+   if (offset != MEM_OFFSET (mem))
+     orig_expr = NULL_TREE;
+ 
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   orig_expr, offset, MEM_SIZE (mem),
! 				   MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Set the size of MEM to SIZE.  */
*************** void
*** 1912,1919 ****
  set_mem_size (rtx mem, rtx size)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_OFFSET (mem), size, MEM_ALIGN (mem),
! 				   GET_MODE (mem));
  }
  
  /* Return a memory reference like MEMREF, but with its mode changed to MODE
--- 1961,1968 ----
  set_mem_size (rtx mem, rtx size)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_ORIG_EXPR (mem), MEM_OFFSET (mem), 
! 				   size, MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Return a memory reference like MEMREF, but with its mode changed to MODE
*************** change_address (rtx memref, enum machine
*** 1980,1986 ****
      }
  
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
  
    return new_rtx;
  }
--- 2029,2035 ----
      }
  
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, 0, size, align, mmode);
  
    return new_rtx;
  }
*************** adjust_address_1 (rtx memref, enum machi
*** 2063,2069 ****
      size = plus_constant (MEM_SIZE (memref), -offset);
  
    MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
! 				   memoffset, size, memalign, GET_MODE (new_rtx));
  
    /* At some point, we should validate that this offset is within the object,
       if all the appropriate values are known.  */
--- 2112,2122 ----
      size = plus_constant (MEM_SIZE (memref), -offset);
  
    MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
!                                        (offset != 0 || size == NULL
!                                         || GET_MODE_SIZE (mode) > INTVAL (size))
!                                        ? NULL_TREE
!                                        : MEM_ORIG_EXPR (memref), 
!                                        memoffset, size, memalign, GET_MODE (new_rtx));
  
    /* At some point, we should validate that this offset is within the object,
       if all the appropriate values are known.  */
*************** offset_address (rtx memref, rtx offset, 
*** 2119,2126 ****
    /* Update the alignment to reflect the offset.  Reset the offset, which
       we don't know.  */
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
! 		     MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
  		     GET_MODE (new_rtx));
    return new_rtx;
  }
--- 2172,2180 ----
    /* Update the alignment to reflect the offset.  Reset the offset, which
       we don't know.  */
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 
! 		     MEM_ORIG_EXPR (memref), 0, 0, 
!                      MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
  		     GET_MODE (new_rtx));
    return new_rtx;
  }
*************** widen_memory_access (rtx memref, enum ma
*** 2223,2231 ****
  
    /* The widened memory may alias other stuff, so zap the alias set.  */
    /* ??? Maybe use get_alias_set on any remaining expression.  */
! 
!   MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
! 				   MEM_ALIGN (new_rtx), mode);
  
    return new_rtx;
  }
--- 2277,2285 ----
  
    /* The widened memory may alias other stuff, so zap the alias set.  */
    /* ??? Maybe use get_alias_set on any remaining expression.  */
!   MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, NULL_TREE, memoffset, 
!                                        GEN_INT (size), MEM_ALIGN (new_rtx), 
!                                        mode);
  
    return new_rtx;
  }
*************** get_spill_slot_decl (bool force_build_p)
*** 2252,2258 ****
  
    rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
    MEM_NOTRAP_P (rd) = 1;
!   MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, const0_rtx,
  				  NULL_RTX, 0, BLKmode);
    SET_DECL_RTL (d, rd);
  
--- 2306,2312 ----
  
    rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
    MEM_NOTRAP_P (rd) = 1;
!   MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, NULL_TREE, const0_rtx,
  				  NULL_RTX, 0, BLKmode);
    SET_DECL_RTL (d, rd);
  
*************** set_mem_attrs_for_spill (rtx mem)
*** 2284,2290 ****
        && CONST_INT_P (XEXP (addr, 1)))
      offset = XEXP (addr, 1);
  
!   MEM_ATTRS (mem) = get_mem_attrs (alias, expr, offset,
  				   MEM_SIZE (mem), MEM_ALIGN (mem),
  				   GET_MODE (mem));
    MEM_NOTRAP_P (mem) = 1;
--- 2338,2344 ----
        && CONST_INT_P (XEXP (addr, 1)))
      offset = XEXP (addr, 1);
  
!   MEM_ATTRS (mem) = get_mem_attrs (alias, expr, NULL_TREE, offset,
  				   MEM_SIZE (mem), MEM_ALIGN (mem),
  				   GET_MODE (mem));
    MEM_NOTRAP_P (mem) = 1;
diff -cprdN -x .svn -x TAGS trunk/gcc/emit-rtl.h alias-export/gcc/emit-rtl.h
*** trunk/gcc/emit-rtl.h	Wed Apr  8 13:59:49 2009
--- alias-export/gcc/emit-rtl.h	Tue Apr 14 15:40:33 2009
*************** extern void set_mem_align (rtx, unsigned
*** 29,34 ****
--- 29,37 ----
  /* Set the expr for MEM to EXPR.  */
  extern void set_mem_expr (rtx, tree);
  
+ /* Set the original expr for MEM to ORIG_EXPR.  */
+ extern void set_mem_orig_expr (rtx, tree);
+ 
  /* Set the offset for MEM to OFFSET.  */
  extern void set_mem_offset (rtx, rtx);
  
diff -cprdN -x .svn -x TAGS trunk/gcc/expr.c alias-export/gcc/expr.c
*** trunk/gcc/expr.c	Tue Jun 30 15:09:51 2009
--- alias-export/gcc/expr.c	Tue Jun 30 15:22:32 2009
*************** expand_expr_real_1 (tree exp, rtx target
*** 7642,7647 ****
--- 7642,7655 ----
  	op0 = memory_address (mode, op0);
  	temp = gen_rtx_MEM (mode, op0);
  	set_mem_attributes (temp, TMR_ORIGINAL (exp), 0);
+         /* If TMR_ORIGINAL has INDIRECT_REF as base, we don't 
+            want it to be in MEM_ORIG_EXPR, as this will not add
+            any information to the oracle.  
+            This however may hamper data dependency export when we will 
+            compute dependencies for pointer accesses.  */
+         if (TMR_ORIGINAL (exp)
+             && INDIRECT_REF_P (get_base_address (TMR_ORIGINAL (exp))))
+           set_mem_orig_expr (temp, NULL);
        }
        return temp;
  
diff -cprdN -x .svn -x TAGS trunk/gcc/final.c alias-export/gcc/final.c
*** trunk/gcc/final.c	Tue Jun 30 15:09:50 2009
--- alias-export/gcc/final.c	Tue Jun 30 15:19:40 2009
*************** along with GCC; see the file COPYING3.  
*** 72,77 ****
--- 72,78 ----
  #include "expr.h"
  #include "cfglayout.h"
  #include "tree-pass.h"
+ #include "tree-flow.h"
  #include "timevar.h"
  #include "cgraph.h"
  #include "coverage.h"
*************** along with GCC; see the file COPYING3.  
*** 79,84 ****
--- 80,86 ----
  #include "vecprim.h"
  #include "ggc.h"
  #include "cfgloop.h"
+ #include "alias-export.h"
  #include "params.h"
  
  #ifdef XCOFF_DEBUGGING_INFO
*************** rest_of_clean_state (void)
*** 4422,4427 ****
--- 4424,4436 ----
  
    free_bb_for_insn ();
  
+   delete_tree_ssa ();
+ 
+   if (flag_alias_export)
+     free_alias_export_info ();
+ 
    if (targetm.binds_local_p (current_function_decl))
      {
        unsigned int pref = crtl->preferred_stack_boundary;
diff -cprdN -x .svn -x TAGS trunk/gcc/function.c alias-export/gcc/function.c
*** trunk/gcc/function.c	Tue Jun 30 15:09:52 2009
--- alias-export/gcc/function.c	Tue Jun 30 15:26:00 2009
*************** assign_parms_unsplit_complex (struct ass
*** 3095,3101 ****
  	  /* Set MEM_EXPR to the original decl, i.e. to PARM,
  	     instead of the copy of decl, i.e. FNARGS.  */
  	  if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm)))
! 	    set_mem_expr (DECL_INCOMING_RTL (parm), parm);
  	}
  
        fnargs = TREE_CHAIN (fnargs);
--- 3095,3104 ----
  	  /* Set MEM_EXPR to the original decl, i.e. to PARM,
  	     instead of the copy of decl, i.e. FNARGS.  */
  	  if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm)))
! 	    {
! 	      set_mem_expr (DECL_INCOMING_RTL (parm), parm);
! 	      set_mem_orig_expr (DECL_INCOMING_RTL (parm), parm);
! 	    }
  	}
  
        fnargs = TREE_CHAIN (fnargs);
diff -cprdN -x .svn -x TAGS trunk/gcc/rtl.h alias-export/gcc/rtl.h
*** trunk/gcc/rtl.h	Mon Jun 22 12:00:22 2009
--- alias-export/gcc/rtl.h	Tue Jun 30 15:33:45 2009
*************** typedef struct GTY(()) mem_attrs
*** 146,151 ****
--- 146,152 ----
    rtx size;			/* Size in bytes, as a CONST_INT.  */
    alias_set_type alias;		/* Memory alias set.  */
    unsigned int align;		/* Alignment of MEM in bits.  */
+   tree orig_expr;		/* Explicit original tree expression.  */
  } mem_attrs;
  
  /* Structure used to describe the attributes of a REG in similar way as
*************** do {						\
*** 1226,1231 ****
--- 1227,1237 ----
   : (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode			\
      ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))
  
+ /* For a MEM rtx, the decl it is known to refer to, if it is known to
+    refer to part of a DECL.  It may also be a COMPONENT_REF.  */
+ #define MEM_ORIG_EXPR(RTX)						\
+ (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->orig_expr)
+ 
  /* For a REG rtx, the decl it is known to refer to, if it is known to
     refer to part of a DECL.  */
  #define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
*************** extern void simplify_using_condition (rt
*** 2343,2348 ****
--- 2349,2355 ----
  
  /* In final.c  */
  extern unsigned int compute_alignments (void);
+ 
  
  struct rtl_hooks
  {
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-dfa.c alias-export/gcc/tree-dfa.c
*** trunk/gcc/tree-dfa.c	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/tree-dfa.c	Wed Jun  3 16:22:32 2009
*************** referenced_var_lookup (unsigned int uid)
*** 502,507 ****
--- 502,521 ----
    return h;
  }
  
+ /* Same as above, but return NULL in case the variable associated with UID
+    is not in the referenced_vars at all.  */
+ 
+ tree 
+ referenced_var_lookup_safe (unsigned int uid)
+ {
+   tree h;
+   struct tree_decl_minimal in;
+   in.uid = uid;
+   h = (tree) htab_find_with_hash (gimple_referenced_vars (cfun), &in, uid);
+   return h;
+ }
+ 
+ 
  /* Check if TO is in the referenced_vars hash table and insert it if not.  
     Return true if it required insertion.  */
  
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-flow.h alias-export/gcc/tree-flow.h
*** trunk/gcc/tree-flow.h	Wed Jun 10 19:50:07 2009
--- alias-export/gcc/tree-flow.h	Tue Jun 30 15:33:58 2009
*************** typedef struct
*** 396,401 ****
--- 396,402 ----
         (ITER).i++)
  
  extern tree referenced_var_lookup (unsigned int);
+ extern tree referenced_var_lookup_safe (unsigned int);
  extern bool referenced_var_check_and_insert (tree);
  #define num_referenced_vars htab_elements (gimple_referenced_vars (cfun))
  #define referenced_var(i) referenced_var_lookup (i)
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-optimize.c alias-export/gcc/tree-optimize.c
*** trunk/gcc/tree-optimize.c	Tue Apr 28 11:40:36 2009
--- alias-export/gcc/tree-optimize.c	Fri May 29 10:54:24 2009
*************** execute_free_datastructures (void)
*** 226,235 ****
    free_dominance_info (CDI_DOMINATORS);
    free_dominance_info (CDI_POST_DOMINATORS);
  
-   /* Remove the ssa structures.  */
-   if (cfun->gimple_df)
-     delete_tree_ssa ();
- 
    /* And get rid of annotations we no longer need.  */
    delete_tree_cfg_annotations ();
  
--- 226,231 ----
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-ssa-uncprop.c alias-export/gcc/tree-ssa-uncprop.c
*** trunk/gcc/tree-ssa-uncprop.c	Tue Jun 30 15:09:51 2009
--- alias-export/gcc/tree-ssa-uncprop.c	Tue Jun 30 15:19:56 2009
*************** struct gimple_opt_pass pass_uncprop = 
*** 600,606 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_ssa	/* todo_flags_finish */
   }
  };
  
--- 600,607 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_ssa
!   | TODO_rebuild_alias                 /* todo_flags_finish */
   }
  };
  
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-ssa.c alias-export/gcc/tree-ssa.c
*** trunk/gcc/tree-ssa.c	Mon Jun 22 12:00:22 2009
--- alias-export/gcc/tree-ssa.c	Tue Jun 30 15:33:41 2009
*************** along with GCC; see the file COPYING3.  
*** 44,49 ****
--- 44,50 ----
  #include "hashtab.h"
  #include "tree-dump.h"
  #include "tree-pass.h"
+ #include "alias-export.h"
  #include "toplev.h"
  
  /* Pointer map of variable mappings, keyed by edge.  */
*************** void
*** 803,810 ****
  delete_tree_ssa (void)
  {
    size_t i;
-   basic_block bb;
-   gimple_stmt_iterator gsi;
    referenced_var_iterator rvi;
    tree var;
  
--- 804,809 ----
*************** delete_tree_ssa (void)
*** 817,851 ****
  	  SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
  	  SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
  	}
!       release_ssa_name (var);
!     }
! 
!   /* FIXME.  This may not be necessary.  We will release all this
!      memory en masse in free_ssa_operands.  This clearing used to be
!      necessary to avoid problems with the inliner, but it may not be
!      needed anymore.  */
!   FOR_EACH_BB (bb)
!     {
!       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
! 	{
! 	  gimple stmt = gsi_stmt (gsi);
! 
! 	  if (gimple_has_ops (stmt))
! 	    {
! 	      gimple_set_def_ops (stmt, NULL);
! 	      gimple_set_use_ops (stmt, NULL);
! 	    }
! 
! 	  if (gimple_has_mem_ops (stmt))
! 	    {
! 	      gimple_set_vdef (stmt, NULL_TREE);
! 	      gimple_set_vuse (stmt, NULL_TREE);
! 	    }
! 
! 	  gimple_set_modified (stmt, true);
! 	}
!       if (!(bb->flags & BB_RTL))
! 	set_phi_nodes (bb, NULL);
      }
  
    /* Remove annotations from every referenced local variable.  */
--- 816,823 ----
  	  SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
  	  SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
  	}
!       if (! var || TREE_CODE (var) != SSA_NAME)
!         release_ssa_name (var);
      }
  
    /* Remove annotations from every referenced local variable.  */
diff -cprdN -x .svn -x TAGS trunk/gcc/Makefile.in alias-export/gcc/Makefile.in
*** trunk/gcc/Makefile.in	Tue Jun 30 15:09:53 2009
--- alias-export/gcc/Makefile.in	Tue Jun 30 15:34:03 2009
*************** OBJS-common = \
*** 1112,1117 ****
--- 1112,1118 ----
  	insn-recog.o \
  	$(GGC) \
  	alias.o \
+ 	alias-export.o \
  	alloc-pool.o \
  	auto-inc-dec.o \
  	bb-reorder.o \
*************** convert.o: convert.c $(CONFIG_H) $(SYSTE
*** 2120,2125 ****
--- 2121,2133 ----
  
  double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
  
+ alias-export.o : alias-export.c alias-export.h 	\
+    $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \
+    $(FUNCTION_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(GGC_H) output.h $(TREE_FLOW_H) \
+    $(RTL_H) $(TREE_PASS_H) $(FLAGS_H) tree-ssa-alias.h vec.h bitmap.h \
+    pointer-set.h dbgcnt.h $(CFGLOOP_H) tree-data-ref.h tree-scalar-evolution.h \
+    $(DIAGNOSTIC_H) statistics.h
+ 
  langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) $(TOPLEV_H) $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \
     langhooks.h $(TARGET_H) $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) \
*************** tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $
*** 2157,2163 ****
     $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
     $(TREE_DUMP_H) langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
     $(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \
!    $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H)
  tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
--- 2165,2171 ----
     $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
     $(TREE_DUMP_H) langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
     $(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \
!    $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) alias-export.h
  tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
*************** tree-ssa-loop-ivopts.o : tree-ssa-loop-i
*** 2349,2355 ****
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
     $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
!    tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h $(TARGET_H)
  tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(GIMPLE_H) \
     output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H)
--- 2357,2363 ----
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
     $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
!    tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h $(TARGET_H) alias-export.h
  tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(GIMPLE_H) \
     output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H)
*************** tree-ssa-alias.o : tree-ssa-alias.c $(TR
*** 2371,2377 ****
     $(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h \
     $(TREE_DUMP_H) $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     hard-reg-set.h $(GIMPLE_H) vec.h \
!    $(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h
  tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
     $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) \
--- 2379,2385 ----
     $(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h \
     $(TREE_DUMP_H) $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     hard-reg-set.h $(GIMPLE_H) vec.h \
!    $(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h alias-export.h
  tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
     $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) \
*************** emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SY
*** 2653,2659 ****
     $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
     $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
     $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
!    $(REAL_H) $(DF_H)
  real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
  dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	$(TREE_H) \
--- 2661,2667 ----
     $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
     $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
     $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h $(TREE_PASS_H) gt-emit-rtl.h \
!    $(REAL_H) $(DF_H) alias-export.h pointer-set.h
  real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
  dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	$(TREE_H) \
*************** loop-unswitch.o : loop-unswitch.c $(CONF
*** 2918,2924 ****
  loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) $(PARAMS_H) \
     output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \
!    $(OBSTACK_H)
  dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(TOPLEV_H) \
     $(TIMEVAR_H) graphds.h vecprim.h pointer-set.h
--- 2926,2932 ----
  loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) $(PARAMS_H) \
     output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \
!    $(OBSTACK_H) alias-export.h 
  dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(TOPLEV_H) \
     $(TIMEVAR_H) graphds.h vecprim.h pointer-set.h
*************** reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H
*** 2977,2983 ****
  alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \
     $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \
!    langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \
     $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H)
  stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \
--- 2985,2991 ----
  alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \
     $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \
!    langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) alias-export.h \
     $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H)
  stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \
*************** modulo-sched.o : modulo-sched.c $(DDG_H)
*** 3034,3040 ****
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(EXCEPT_H) $(RECOG_H) \
     $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(PARAMS_H) \
     cfghooks.h $(GCOV_IO_H) hard-reg-set.h $(TM_H) $(TIMEVAR_H) $(TREE_PASS_H) \
!    $(DF_H) $(DBGCNT_H)
  haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
     $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) output.h \
--- 3042,3048 ----
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(EXCEPT_H) $(RECOG_H) \
     $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(PARAMS_H) \
     cfghooks.h $(GCOV_IO_H) hard-reg-set.h $(TM_H) $(TIMEVAR_H) $(TREE_PASS_H) \
!    $(DF_H) $(DBGCNT_H) alias-export.h
  haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
     $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) output.h \
*************** sel-sched.o : sel-sched.c $(CONFIG_H) $(
*** 3060,3066 ****
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
     $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) $(TREE_PASS_H)  \
     $(SCHED_INT_H) $(GGC_H) $(TREE_H) $(LANGHOOKS_DEF_H) \
!    $(SEL_SCHED_IR_H) $(SEL_SCHED_DUMP_H) sel-sched.h
  sel-sched-dump.o : sel-sched-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
--- 3068,3074 ----
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
     $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) $(TREE_PASS_H)  \
     $(SCHED_INT_H) $(GGC_H) $(TREE_H) $(LANGHOOKS_DEF_H) \
!    $(SEL_SCHED_IR_H) $(SEL_SCHED_DUMP_H) sel-sched.h alias-export.h
  sel-sched-dump.o : sel-sched-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
*************** final.o : final.c $(CONFIG_H) $(SYSTEM_H
*** 3077,3083 ****
     $(EXCEPT_H) debug.h xcoffout.h $(TOPLEV_H) reload.h dwarf2out.h \
     $(TREE_PASS_H) $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) \
     $(CFGLAYOUT_H) dbxout.h $(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) \
!    $(DF_H) vecprim.h $(GGC_H) $(CFGLOOP_H) $(PARAMS_H)
  recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) output.h reload.h \
--- 3085,3091 ----
     $(EXCEPT_H) debug.h xcoffout.h $(TOPLEV_H) reload.h dwarf2out.h \
     $(TREE_PASS_H) $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) \
     $(CFGLAYOUT_H) dbxout.h $(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) \
!    $(DF_H) vecprim.h $(GGC_H) $(CFGLOOP_H) $(PARAMS_H) alias-export.h
  recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
     $(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
     $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) output.h reload.h \
diff -cprdN -x .svn -x TAGS trunk/gcc/alias-export.c alias-export/gcc/alias-export.c
*** trunk/gcc/alias-export.c	Thu Jan  1 03:00:00 1970
--- alias-export/gcc/alias-export.c	Thu Jun  4 17:57:05 2009
***************
*** 0 ****
--- 1,630 ----
+ /* Export of alias/data dependency information to RTL.  
+    Copyright (C) 2009 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/>.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "tree.h"
+ #include "tm_p.h"
+ #include "basic-block.h"
+ #include "timevar.h"
+ #include "diagnostic.h"
+ #include "ggc.h"
+ #include "output.h"
+ #include "function.h"
+ #include "tree-dump.h"
+ #include "gimple.h"
+ #include "tree-flow.h"
+ #include "tree-pass.h"
+ #include "tree-ssa-alias.h"
+ #include "vec.h"
+ #include "bitmap.h"
+ #include "alias-export.h"
+ #include "emit-rtl.h"
+ #include "rtl.h"
+ #include "pointer-set.h"
+ #include "dbgcnt.h"
+ #include "cfgloop.h"
+ #include "tree-data-ref.h"
+ #include "tree-scalar-evolution.h"
+ #include "statistics.h"
+ 
+ /* The map of decls to stack partitions.  */
+ static struct pointer_map_t *decls_to_partitions = NULL;
+ 
+ /* The map of decls to artificial ssa-names that point to all partition 
+    of the decl.  */
+ static struct pointer_map_t *decls_to_pointers = NULL;
+ 
+ /* Alias export statistics counter.  */
+ static unsigned int alias_export_disambiguations = 0;
+ 
+ 
+ /* This structure holds exported data references and relations.  */
+ struct ddg_info_def
+ {
+   /* A hashtable for tree -> dataref mapping.  */
+   htab_t tree_to_dataref;
+ 
+   /* A hashtable for mapping dataref pairs to data dependence relation.  */
+   htab_t datarefs_pair_to_ddr;
+ 
+   /* TRUE for passes that perform code motion across loop branches, like SMS.
+      For other passes we assume it is safe to disambiguate references that are
+      dependent and distance vectors are known and non-zero.  */
+   bool pipelining_completed;
+ };
+ 
+ /* A struct holding dataref information for a given tree.  */
+ typedef struct {
+   const_tree ref;
+   data_reference_p drf;
+ } tree_dataref;
+ 
+ /* A struct for holding data dependence relations for datarefs pairs.  */
+ typedef struct {
+   data_reference_p a;
+   data_reference_p b;
+   ddr_p ddr;
+ } datarefs_pair_ddr;
+ 
+ /* Data references and data dependence relations exported from Tree-SSA
+    level for use on RTL level.  */
+ static struct ddg_info_def *ddg_info;
+ 
+ /* DDG export statistics counter.  */
+ static unsigned int ddg_export_disambiguations = 0;
+ 
+ 
+ /* If some of PID->PT.VARS variables got partitioned, add all partition 
+    vars to that bitmap.  */
+ static void
+ add_partitioned_vars_to_ptset (struct pt_solution *pi)
+ {
+   if (pi->vars)
+     {
+       bitmap_iterator bi;
+       unsigned i;
+       bitmap *part, temp = NULL;
+       
+       EXECUTE_IF_SET_IN_BITMAP (pi->vars, 0, i, bi)
+         if ((part = (bitmap *) pointer_map_contains (decls_to_partitions,
+                                                      referenced_var (i))))
+           {
+             if (!temp)
+               temp = BITMAP_GGC_ALLOC ();
+             bitmap_ior_into (temp, *part);
+           }
+       if (temp)
+         {
+           bitmap_ior_into (temp, pi->vars);
+           pi->vars = temp;
+         }
+     }
+ }
+ 
+ /* Fixup stack-partitioned base var in EXPR.  */
+ static tree
+ rewrite_partitioned_mem_expr (tree expr)
+ {
+   tree *pbase, *pname;
+   
+   if (!decls_to_pointers)
+     return expr;
+   
+   pbase = &expr;
+   while (handled_component_p (*pbase))
+     pbase = &TREE_OPERAND (*pbase, 0);
+   if (DECL_P (*pbase)
+       && (pname = (tree *) pointer_map_contains (decls_to_pointers, *pbase)))
+     *pbase = build1 (INDIRECT_REF, TREE_TYPE (*pbase), *pname);
+ 
+   return expr;
+ }
+ 
+ /* Record the final points-to set for EXPR and unshare it.  Returns 
+    the unshared expression or NULL_TREE, if EXPR cannot be used for 
+    alias/ddg export later.  */
+ tree
+ unshare_and_record_pta_info (tree expr)
+ {
+   tree old_expr;
+ 
+   /* No point saving anything for unhandled stuff.  */
+   if (! (SSA_VAR_P (expr)
+          || handled_component_p (expr)
+          || INDIRECT_REF_P (expr)))
+     return NULL_TREE;
+ 
+   /* Unshare the tree and do replacement in ddg info.  */
+   old_expr = expr;
+   expr = unshare_expr (expr);
+   if (flag_ddg_export)
+     replace_var_in_datarefs (old_expr, expr);
+ 
+   expr = rewrite_partitioned_mem_expr (expr);
+   return expr;
+ }
+ 
+ /* Save stack partitions.  DECL is in the partition represented by 
+    PART bitmap.  NAME is a pointer that points to all partition.  */
+ void
+ record_stack_var_partition_for (tree decl, bitmap part, tree name)
+ {
+   if (! decls_to_partitions)
+     {
+       decls_to_partitions = pointer_map_create ();
+       decls_to_pointers = pointer_map_create ();
+     }
+   *((bitmap *) pointer_map_insert (decls_to_partitions, decl)) = part;
+   *((tree *) pointer_map_insert (decls_to_pointers, decl)) = name;
+ }
+ 
+ /* Update pta info so that stack partitioning is reflected in it.  */
+ void
+ update_pta_with_stack_partitions (void)
+ {
+   unsigned i;
+ 
+   if (! decls_to_partitions)
+     return;
+   
+   for (i = 1; i < num_ssa_names; i++)
+     {
+       tree name = ssa_name (i);
+       struct ptr_info_def *pid;
+ 
+       if (name && ((pid = SSA_NAME_PTR_INFO (name)) != NULL))
+         add_partitioned_vars_to_ptset (&pid->pt);
+     }
+ 
+   add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped);
+   add_partitioned_vars_to_ptset (&cfun->gimple_df->callused);
+ }
+ 
+ /* Functions to be called when needed to use exported information.  */
+ 
+ /* Returns false if we shouldn't pass REF to the oracle.  Now only checks
+    that INDIRECT_REFs have sensible bases.  */
+ static bool 
+ handled_by_oracle_p (tree ref)
+ {
+   tree base = get_base_address (ref);
+   return (base
+           && (! INDIRECT_REF_P (base)
+               || TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME));
+ }
+ 
+ /* Main function to ask saved information about if REF1 and REF2 may
+    alias or not.  MEM1 and MEM2 are corresponding mems.  */
+ bool
+ alias_export_may_alias_p (tree ref1, tree ref2)
+ {
+   if (! dbg_cnt (alias_export))
+     return true;
+   if (! handled_by_oracle_p (ref1) || ! handled_by_oracle_p (ref2))
+     return true;
+   if (! refs_may_alias_p (ref1, ref2))
+     {
+       alias_export_disambiguations++;
+       return false;
+     }
+   return true;
+ }
+ 
+ /* Free exported info.  */
+ void
+ free_alias_export_info (void)
+ {
+   statistics_counter_event (cfun, "Alias export disambiguations", 
+                             alias_export_disambiguations);
+   alias_export_disambiguations = 0;
+ 
+   if (decls_to_partitions)
+     {
+       pointer_map_destroy (decls_to_partitions);
+       decls_to_partitions = NULL;
+       pointer_map_destroy (decls_to_pointers);
+       decls_to_pointers = NULL;
+     }
+ }
+ 
+ 
+ /* Data dependence export.  */
+ 
+ /* Hash a dataref T.  */
+ static hashval_t
+ htab_hash_tree (const tree_dataref *t)
+ {
+   return htab_hash_pointer (t->ref);
+ }
+ 
+ /* Equality function for struct tree_dataref.  */
+ static int
+ htab_eq_tree (const tree_dataref *t1, const tree_dataref *t2)
+ {
+   return t1->ref == t2->ref;
+ }
+ 
+ /* When freeing hashtable, free the dataref memory.  */
+ static void
+ htab_del_tree_dataref (tree_dataref *t)
+ {
+   if (t->drf)
+     free_data_ref (t->drf);
+ }
+ 
+ /* Hash function for the above.  */
+ static hashval_t
+ htab_hash_datarefs_pair (const datarefs_pair_ddr *dp)
+ {
+   return iterative_hash (&dp->a, sizeof (data_reference_p),
+ 			 htab_hash_pointer (dp->b));
+ }
+ 
+ /* Equality function for the above.  */
+ static int
+ htab_eq_datarefs_pair (const datarefs_pair_ddr *dp1,
+ 		       const datarefs_pair_ddr *dp2)
+ {
+   return dp1->a == dp2->a && dp1->b == dp2->b;
+ }
+ 
+ /* Free function for the above.  */
+ static void
+ htab_del_datarefs_pair (datarefs_pair_ddr *dp)
+ {
+   free_dependence_relation (dp->ddr);
+ }
+ 
+ /* Init the ddg_info structure holding the saved data.  */
+ static void
+ init_ddg_info (void)
+ {
+   gcc_assert (!ddg_info);
+ 
+   ddg_info = XCNEW (struct ddg_info_def);
+   ddg_info->tree_to_dataref
+    = htab_create (1, (htab_hash) htab_hash_tree, (htab_eq) htab_eq_tree,
+ 		  (htab_del) htab_del_tree_dataref);
+   ddg_info->datarefs_pair_to_ddr
+    = htab_create (1, (htab_hash) htab_hash_datarefs_pair,
+ 		  (htab_eq) htab_eq_datarefs_pair,
+ 		  (htab_del) htab_del_datarefs_pair);
+   ddg_info->pipelining_completed = false;
+ }
+ 
+ /* Save the data reference DRF in the ddg_info structure.  */
+ static void
+ record_data_reference (data_reference_p drf)
+ {
+   void **slot;
+   tree_dataref *td;
+ 
+   td = XNEW (tree_dataref);
+   td->ref = drf->ref;
+   td->drf = drf;
+ 
+   slot = htab_find_slot (ddg_info->tree_to_dataref, td, INSERT);
+   gcc_assert (!*slot);
+ 
+   *slot = td;
+ }
+ 
+ /* Save the data relation DDR in the ddg info structure.  */
+ static void
+ record_data_dependence_relation (ddr_p ddr)
+ {
+   void **slot;
+   datarefs_pair_ddr *dp;
+ 
+   dp = XNEW (datarefs_pair_ddr);
+   dp->a = ddr->a;
+   dp->b = ddr->b;
+   dp->ddr = ddr;
+ 
+   slot = htab_find_slot (ddg_info->datarefs_pair_to_ddr, dp, INSERT);
+   gcc_assert (!*slot);
+ 
+   *slot = dp;
+ }
+ 
+ /* Export ddg info for loop LOOP.  */
+ static void
+ record_ddg_info_for (struct loop *loop)
+ {
+   VEC (data_reference_p, heap) *datarefs = NULL;
+   VEC (ddr_p, heap) *ddrs = NULL;
+   unsigned int i;
+   data_reference_p drf;
+   ddr_p ddr;
+ 
+   compute_data_dependences_for_loop (loop, false, &datarefs, &ddrs);
+ 
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     {
+       dump_data_references (dump_file, datarefs);
+       dump_ddrs (dump_file, ddrs);
+     }
+ 
+   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, drf); i++)
+     {
+       /* We want to save only those data references that correspond to
+          iteration of innermost loop containing the reference.  */
+       if (!drf->ref || loop != loop_containing_stmt (drf->stmt))
+         continue;
+       record_data_reference (drf);
+     }
+ 
+   for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
+     {
+       /* As above, we want to save only those DDRs that describe
+          relation of references for innermost loop containing them.  */
+       if (!(ddr->a && ddr->b)
+           || loop != loop_containing_stmt (ddr->a->stmt))
+         continue;
+       record_data_dependence_relation (ddr);
+     }
+ 
+   VEC_free (data_reference_p, heap, datarefs);
+   VEC_free (ddr_p, heap, ddrs);
+ }
+ 
+ /* For each loop in function, save datarefs and ddrs obtained via
+    compute_dependencies_for_loop into ddg_info.  */
+ static unsigned int
+ run_ddg_export (void)
+ {
+   bool inside_tree_loop_opt_p = !!current_loops;
+   bool dom_info_was_avail_p = dom_info_available_p (CDI_DOMINATORS);
+   struct loop *loop;
+   loop_iterator li;
+ 
+   if (!inside_tree_loop_opt_p)
+     loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+ 
+   /* This can be more than actual number of loops, because number_of_loops ()
+      includes deleted loops.  */
+   if (number_of_loops () > 1)
+     {
+       if (!inside_tree_loop_opt_p)
+ 	scev_initialize ();
+       init_ddg_info ();
+ 
+       FOR_EACH_LOOP (li, loop, 0)
+         record_ddg_info_for (loop);
+ 
+       if (!inside_tree_loop_opt_p)
+ 	scev_finalize ();
+     }
+ 
+   if (!inside_tree_loop_opt_p)
+     loop_optimizer_finalize ();
+ 
+   if (!dom_info_was_avail_p)
+     free_dominance_info (CDI_DOMINATORS);
+ 
+   return 0;
+ }
+ 
+ /* Replace FROM tree to TO in ref fields of saved datarefs.  */
+ void
+ replace_var_in_datarefs (tree from, tree to)
+ {
+   void **slot;
+   tree_dataref td, *ptd;
+ 
+   if (!ddg_info)
+     return;
+ 
+   td.ref = from;
+   slot = htab_find_slot (ddg_info->tree_to_dataref, &td, NO_INSERT);
+ 
+   /* IVOPTS might want to change a memory reference for which no dataref was
+      produced.  However, it would be nice to enable this assert and see in
+      what cases it happens.  */
+   /* gcc_assert (slot); */
+   if (!slot)
+     return;
+ 
+   ptd = XNEW (tree_dataref);
+   ptd->ref = to;
+   ptd->drf = ((tree_dataref *) (*slot))->drf;
+   ((tree_dataref *) (*slot))->drf = NULL;
+   htab_clear_slot (ddg_info->tree_to_dataref, slot);
+   
+   slot = htab_find_slot (ddg_info->tree_to_dataref, ptd, INSERT);
+   gcc_assert (!*slot);
+   *slot = ptd;
+ }
+ 
+ /* Search for the dataref for T and return it if found, otherwise return
+    NULL.  */
+ 
+ static data_reference_p
+ find_dataref (const_tree t)
+ {
+   tree_dataref td, *ptd;
+ 
+   td.ref = t;
+   ptd = (tree_dataref *) htab_find (ddg_info->tree_to_dataref, &td);
+   return ptd ? ptd->drf : NULL;
+ }
+ 
+ /* Search for data dependence relation for DR1 and DR2, return it if found;
+    otherwise return NULL.  */
+ static ddr_p
+ find_ddr (data_reference_p dr1, data_reference_p dr2)
+ {
+   datarefs_pair_ddr dp, *pdp;
+ 
+   dp.a = dr1;
+   dp.b = dr2;
+   pdp = (datarefs_pair_ddr *) htab_find (ddg_info->datarefs_pair_to_ddr, &dp);
+   if (pdp)
+     return pdp->ddr;
+ 
+   dp.a = dr2;
+   dp.b = dr1;
+   pdp = (datarefs_pair_ddr *) htab_find (ddg_info->datarefs_pair_to_ddr, &dp);
+   return pdp ? pdp->ddr : NULL;
+ }
+ 
+ /* A callback for for_each_rtx to remove exported data for mems.  */
+ static int
+ walk_mems (rtx *x, void *data ATTRIBUTE_UNUSED)
+ {
+   if (MEM_P (*x) && MEM_ORIG_EXPR (*x) && find_dataref (MEM_ORIG_EXPR (*x)))
+     {
+       tree_dataref td;
+ 
+       td.ref = MEM_ORIG_EXPR (*x);
+       htab_remove_elt (ddg_info->tree_to_dataref, &td);
+ 
+       return -1;
+     }
+   
+   return 0;
+ }
+ 
+ /* Remove saved dependency data for INSN.  Used when INSN is in the loop that
+    was unrolled.  */
+ void
+ remove_exported_ddg_data (rtx insn)
+ {
+   if (!ddg_info)
+     return;
+ 
+   for_each_rtx (&PATTERN (insn), walk_mems, NULL);
+ }
+ 
+ /* Set pipelining-completed to B.  */
+ void
+ ddg_export_set_pipelining_completed (bool b)
+ {
+   if (ddg_info)
+     ddg_info->pipelining_completed = b;
+ }
+ 
+ /* Return TRUE if any of DIST_VECTS is non-zero.  */
+ static bool
+ nonzero_dist_vects (VEC (lambda_vector, heap) *dist_vects, int loops_count)
+ {
+   lambda_vector dist_v;
+   int i, j;
+ 
+   for (i = 0; VEC_iterate (lambda_vector, dist_vects, i, dist_v); i++)
+     for (j = 0; j < loops_count; j++)
+       if (dist_v[j])
+ 	return true;
+ 
+   return false;
+ }
+ 
+ /* Return TRUE if we cannot prove from exported DDG info that MEM1 and MEM2
+    are independent memory references.  When FOR_PIPELINING is true, do not
+    disambiguate references with non-zero distances.  */
+ bool
+ ddg_export_may_alias_p (tree t1, tree t2, bool for_pipelining)
+ {
+   data_reference_p drf1, drf2;
+   ddr_p ddr;
+ 
+   if (! dbg_cnt (ddg_export))
+     return true;
+ 
+   if (!ddg_info || !t1 || !t2)
+     return true;
+ 
+   drf1 = find_dataref (t1);
+   drf2 = find_dataref (t2);
+   if (!drf1 || !drf2)
+     return true;
+ 
+   ddr = find_ddr (drf1, drf2);
+   if (!ddr)
+     return true;
+ 
+   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
+     {
+       ddg_export_disambiguations++;
+       return false;
+     }
+   
+   if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE 
+       && DDR_NUM_DIST_VECTS (ddr) > 0
+       && ! for_pipelining
+       && ! ddg_info->pipelining_completed
+       && nonzero_dist_vects (DDR_DIST_VECTS (ddr), DDR_NB_LOOPS (ddr)))
+     {
+       ddg_export_disambiguations++;
+       return false;
+     }
+   
+   return true;
+ }
+ 
+ /* Free ddg export info.  */
+ void
+ free_ddg_export_info (void)
+ {
+   if (!ddg_info)
+     return;
+ 
+   statistics_counter_event (cfun, "DDG export disambiguations", 
+                             ddg_export_disambiguations);
+   ddg_export_disambiguations = 0;
+ 
+   /* TODO: DDR_LOOP_NESTs are not free'd.  */
+   htab_delete (ddg_info->datarefs_pair_to_ddr);
+   htab_delete (ddg_info->tree_to_dataref);
+ 
+   free (ddg_info);
+   ddg_info = NULL;
+ }
+ 
+ /* Gate for ddg export pass.  */
+ static bool
+ gate_ddg_export (void)
+ {
+   return flag_ddg_export != 0;
+ }
+ 
+ struct gimple_opt_pass pass_gather_ddg_info =
+ {
+  {
+   GIMPLE_PASS,
+   "ddg-export",				/* name */
+   gate_ddg_export,	                /* gate */
+   run_ddg_export,			/* execute */
+   NULL,					/* sub */
+   NULL,					/* next */
+   0,					/* static_pass_number */
+   TV_NONE,				/* tv_id */
+   0,					/* properties_required */
+   0,					/* properties_provided */
+   0,					/* properties_destroyed */
+   0,					/* todo_flags_start */
+   TODO_dump_func                        /* todo_flags_finish */
+  }
+ };
+ 
+ 
+ 
diff -cprdN -x .svn -x TAGS trunk/gcc/alias-export.h alias-export/gcc/alias-export.h
*** trunk/gcc/alias-export.h	Thu Jan  1 03:00:00 1970
--- alias-export/gcc/alias-export.h	Tue Jun  2 19:31:25 2009
***************
*** 0 ****
--- 1,35 ----
+ /* Export of alias information to RTL.  
+    Copyright (C) 2009 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_ALIAS_EXPORT_H
+ #define GCC_ALIAS_EXPORT_H
+ 
+ extern bool alias_export_may_alias_p (tree, tree);
+ extern tree unshare_and_record_pta_info (tree);
+ extern void record_stack_var_partition_for (tree, bitmap, tree);
+ extern void update_pta_with_stack_partitions (void);
+ extern void free_alias_export_info (void);
+ 
+ extern bool ddg_export_may_alias_p (tree, tree, bool);
+ extern void replace_var_in_datarefs (tree, tree);
+ extern void remove_exported_ddg_data (rtx);
+ extern void ddg_export_set_pipelining_completed (bool);
+ extern void free_ddg_export_info (void);
+ 
+ #endif /* GCC_ALIAS_EXPORT_H */
diff -cprdN -x .svn -x TAGS trunk/gcc/alias.c alias-export/gcc/alias.c
*** trunk/gcc/alias.c	Tue Jun 30 15:09:52 2009
--- alias-export/gcc/alias.c	Tue Jun 30 15:26:08 2009
*************** along with GCC; see the file COPYING3.  
*** 46,51 ****
--- 46,52 ----
  #include "tree-pass.h"
  #include "ipa-type-escape.h"
  #include "df.h"
+ #include "alias-export.h"
  
  /* The aliasing API provided here solves related but different problems:
  
*************** DEF_VEC_ALLOC_P(alias_set_entry,gc);
*** 249,254 ****
--- 250,279 ----
  /* The splay-tree used to store the various alias set entries.  */
  static GTY (()) VEC(alias_set_entry,gc) *alias_sets;
  
+ 
+ /* Check MEM_ORIG_EXPRs of two MEMs and if they are present query saved alias/ddg
+    information whether they may alias or not.  */
+ static bool
+ query_alias_export_info (const_rtx x, const_rtx mem)
+ {
+   tree x_orig_expr = MEM_ORIG_EXPR (x);
+   tree mem_orig_expr = MEM_ORIG_EXPR (mem);
+   bool ret = true;
+ 
+   if (x_orig_expr != NULL 
+       && mem_orig_expr != NULL
+       && x_orig_expr != mem_orig_expr)
+     {
+       if (flag_alias_export == 1)
+         ret = alias_export_may_alias_p (x_orig_expr, mem_orig_expr);
+       if (flag_ddg_export == 1
+           && ret)
+         ret = ddg_export_may_alias_p (x_orig_expr, mem_orig_expr, false);
+     }
+ 
+   return ret;
+ }
+ 
  /* Returns a pointer to the alias set entry for ALIAS_SET, if there is
     such an entry, or NULL otherwise.  */
  
*************** walk_mems_2 (rtx *x, rtx mem)
*** 346,352 ****
  {
    if (MEM_P (*x))
      {
!       if (alias_sets_conflict_p (MEM_ALIAS_SET(*x), MEM_ALIAS_SET(mem)))
          return 1;
          
        return -1;  
--- 371,380 ----
  {
    if (MEM_P (*x))
      {
!       if (alias_sets_conflict_p (MEM_ALIAS_SET (*x), MEM_ALIAS_SET (mem))
!           && (! flag_ddg_export
!               || ddg_export_may_alias_p (MEM_ORIG_EXPR (*x),
!                                          MEM_ORIG_EXPR (mem), true)))
          return 1;
          
        return -1;  
*************** true_dependence (const_rtx mem, enum mac
*** 2175,2181 ****
    mem_addr = canon_rtx (mem_addr);
  
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
! 			    SIZE_FOR_MODE (x), x_addr, 0))
      return 0;
  
    if (aliases_everything_p (x))
--- 2203,2212 ----
    mem_addr = canon_rtx (mem_addr);
  
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
!                             SIZE_FOR_MODE (x), x_addr, 0))
!     return 0;
! 
!   if (! query_alias_export_info (x, mem))
      return 0;
  
    if (aliases_everything_p (x))
*************** canon_true_dependence (const_rtx mem, en
*** 2239,2245 ****
  
    x_addr = canon_rtx (x_addr);
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
! 			    SIZE_FOR_MODE (x), x_addr, 0))
      return 0;
  
    if (aliases_everything_p (x))
--- 2270,2279 ----
  
    x_addr = canon_rtx (x_addr);
    if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
!                             SIZE_FOR_MODE (x), x_addr, 0))
!     return 0;
! 
!   if (! query_alias_export_info (x, mem))
      return 0;
  
    if (aliases_everything_p (x))
*************** write_dependence_p (const_rtx mem, const
*** 2308,2315 ****
    x_addr = canon_rtx (x_addr);
    mem_addr = canon_rtx (mem_addr);
  
!   if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
! 			   SIZE_FOR_MODE (x), x_addr, 0))
      return 0;
  
    fixed_scalar
--- 2342,2352 ----
    x_addr = canon_rtx (x_addr);
    mem_addr = canon_rtx (mem_addr);
  
!   if (! memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
!                             SIZE_FOR_MODE (x), x_addr, 0))
!     return 0;
! 
!   if (! query_alias_export_info (x, mem))
      return 0;
  
    fixed_scalar
diff -cprdN -x .svn -x TAGS trunk/gcc/builtins.c alias-export/gcc/builtins.c
*** trunk/gcc/builtins.c	Tue Jun 30 15:09:50 2009
--- alias-export/gcc/builtins.c	Tue Jun 30 15:19:43 2009
*************** get_memory_rtx (tree exp, tree len)
*** 1230,1235 ****
--- 1230,1236 ----
  	}
        set_mem_alias_set (mem, 0);
        set_mem_size (mem, NULL_RTX);
+       set_mem_orig_expr (mem, NULL_TREE);
      }
  
    return mem;
diff -cprdN -x .svn -x TAGS trunk/gcc/cfgexpand.c alias-export/gcc/cfgexpand.c
*** trunk/gcc/cfgexpand.c	Mon Jun 22 12:03:55 2009
--- alias-export/gcc/cfgexpand.c	Tue Jun 30 15:33:20 2009
*************** along with GCC; see the file COPYING3.  
*** 42,47 ****
--- 42,48 ----
  #include "tree-inline.h"
  #include "value-prof.h"
  #include "target.h"
+ #include "alias-export.h"
  #include "ssaexpand.h"
  
  
*************** stack_var_size_cmp (const void *a, const
*** 784,789 ****
--- 785,841 ----
    return 0;
  }
  
+ /* Update points-to sets based on partition info, so we can use them on RTL.
+    The bitmaps representing stack partitions will be saved until expand,
+    where partitioned decls used as bases in memory expressions will be 
+    rewritten.  */
+ 
+ static void
+ update_alias_info_with_stack_vars (void)
+ {
+   size_t i, j;
+ 
+   for (i = 0; i < stack_vars_num; i++)
+     {
+       bitmap temp = NULL;
+       tree name, var, type;
+       struct ptr_info_def *pid;
+ 
+       /* Not interested in partitions with single variable.  */
+       if (stack_vars[i].representative != i
+           || stack_vars[i].next == EOC)
+         continue;
+ 
+       /* Create bitmaps representing partitions.  They will be used for 
+          points-to sets later, so use GGC alloc.  */
+       temp = BITMAP_GGC_ALLOC ();
+       for (j = i; j != EOC; j = stack_vars[j].next)
+         if (DECL_P (stack_vars[j].decl)
+             && referenced_var_lookup_safe (DECL_UID (stack_vars[j].decl)))
+           bitmap_set_bit (temp, DECL_UID (stack_vars[j].decl));
+       if (bitmap_empty_p (temp))
+         continue;
+ 
+       /* Create an SSA_NAME that points to the partition for later 
+          base rewriting.  */
+       type = build_pointer_type (TREE_TYPE (stack_vars[i].decl));
+       var = create_tmp_var (type, NULL);
+       add_referenced_var (var);
+       name = make_ssa_name (var, NULL);
+       pid = get_ptr_info (name);
+       pid->pt.vars = temp;
+ 
+       for (j = i; j != EOC; j = stack_vars[j].next)
+         if (DECL_P (stack_vars[j].decl)
+             && bitmap_bit_p (temp, DECL_UID (stack_vars[j].decl)))
+           record_stack_var_partition_for (stack_vars[j].decl, temp, name);
+     }
+ 
+   /* Make all points-to sets that contain one of partition members
+      contain all partition.  */
+   update_pta_with_stack_partitions ();
+ }
+ 
  /* A subroutine of partition_stack_vars.  The UNION portion of a UNION/FIND
     partitioning algorithm.  Partitions A and B are known to be non-conflicting.
     Merge them into a single partition A.
*************** static void
*** 796,811 ****
--- 848,867 ----
  union_stack_vars (size_t a, size_t b, HOST_WIDE_INT offset)
  {
    size_t i, last;
+   bool adressable;
  
    /* Update each element of partition B with the given offset,
       and merge them into partition A.  */
+   adressable = false;
    for (last = i = b; i != EOC; last = i, i = stack_vars[i].next)
      {
        stack_vars[i].offset += offset;
        stack_vars[i].representative = a;
+       adressable |= TREE_ADDRESSABLE (stack_vars[i].decl);
      }
    stack_vars[last].next = stack_vars[a].next;
    stack_vars[a].next = b;
+   TREE_ADDRESSABLE (stack_vars[a].decl) |= adressable;
  
    /* Update the required alignment of partition A to account for B.  */
    if (stack_vars[a].alignb < stack_vars[b].alignb)
*************** partition_stack_vars (void)
*** 903,908 ****
--- 959,967 ----
  	    break;
  	}
      }
+ 
+   if (flag_alias_export)
+     update_alias_info_with_stack_vars ();
  }
  
  /* A debugging aid for expand_used_vars.  Dump the generated partitions.  */
*************** gimple_expand_cfg (void)
*** 2492,2498 ****
    crtl->preferred_stack_boundary = STACK_BOUNDARY;
    cfun->cfg->max_jumptable_ents = 0;
  
- 
    /* Expand the variables recorded during gimple lowering.  */
    expand_used_vars ();
  
--- 2551,2556 ----
*************** gimple_expand_cfg (void)
*** 2533,2542 ****
  	 to select one of the potentially many RTLs for one DECL.  Instead
  	 of doing that we simply reset the MEM_EXPR of the RTL in question,
  	 then nobody can get at it and hence nobody can call DECL_RTL on it.  */
!       if (!DECL_RTL_SET_P (var))
! 	{
! 	  if (MEM_P (SA.partition_to_pseudo[i]))
! 	    set_mem_expr (SA.partition_to_pseudo[i], NULL);
  	}
      }
  
--- 2591,2601 ----
  	 to select one of the potentially many RTLs for one DECL.  Instead
  	 of doing that we simply reset the MEM_EXPR of the RTL in question,
  	 then nobody can get at it and hence nobody can call DECL_RTL on it.  */
!       if (!DECL_RTL_SET_P (var)
!           && MEM_P (SA.partition_to_pseudo[i]))
!         {
!           set_mem_expr (SA.partition_to_pseudo[i], NULL);
!           set_mem_orig_expr (SA.partition_to_pseudo[i], NULL);
  	}
      }
  
diff -cprdN -x .svn -x TAGS trunk/gcc/common.opt alias-export/gcc/common.opt
*** trunk/gcc/common.opt	Mon Jun 22 12:00:22 2009
--- alias-export/gcc/common.opt	Tue Jun 30 15:33:33 2009
*************** fexpensive-optimizations
*** 506,511 ****
--- 506,519 ----
  Common Report Var(flag_expensive_optimizations) Optimization
  Perform a number of minor, expensive optimizations
  
+ falias-export
+ Common Report Var(flag_alias_export) Optimization Init(1)
+ Save alias information on Tree-SSA to be used on RTL
+ 
+ fddg-export
+ Common Report Var(flag_ddg_export) Optimization Init(1)
+ Save alias information on Tree-SSA to be used on RTL
+ 
  fexcess-precision=
  Common Joined RejectNegative
  -fexcess-precision=[fast|standard]	Specify handling of excess floating-point precision
diff -cprdN -x .svn -x TAGS trunk/gcc/dbgcnt.def alias-export/gcc/dbgcnt.def
*** trunk/gcc/dbgcnt.def	Tue Apr 28 11:40:36 2009
--- alias-export/gcc/dbgcnt.def	Thu May  7 12:24:04 2009
*************** echo ubound: $ub
*** 141,146 ****
--- 141,147 ----
  */
  
  /* Debug counter definitions.  */
+ DEBUG_COUNTER (alias_export)
  DEBUG_COUNTER (auto_inc_dec)
  DEBUG_COUNTER (ccp)
  DEBUG_COUNTER (cfg_cleanup)
*************** DEBUG_COUNTER (cprop)
*** 149,154 ****
--- 150,156 ----
  DEBUG_COUNTER (dce)
  DEBUG_COUNTER (dce_fast)
  DEBUG_COUNTER (dce_ud)
+ DEBUG_COUNTER (ddg_export)
  DEBUG_COUNTER (delete_trivial_dead)
  DEBUG_COUNTER (df_byte_scan)
  DEBUG_COUNTER (dse)
diff -cprdN -x .svn -x TAGS trunk/gcc/emit-rtl.c alias-export/gcc/emit-rtl.c
*** trunk/gcc/emit-rtl.c	Tue Jun 30 15:09:52 2009
--- alias-export/gcc/emit-rtl.c	Tue Jun 30 15:26:27 2009
*************** along with GCC; see the file COPYING3.  
*** 58,63 ****
--- 58,64 ----
  #include "langhooks.h"
  #include "tree-pass.h"
  #include "df.h"
+ #include "alias-export.h"
  
  /* Commonly used modes.  */
  
*************** static int const_fixed_htab_eq (const vo
*** 192,199 ****
  static rtx lookup_const_fixed (rtx);
  static hashval_t mem_attrs_htab_hash (const void *);
  static int mem_attrs_htab_eq (const void *, const void *);
! static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int,
! 				 enum machine_mode);
  static hashval_t reg_attrs_htab_hash (const void *);
  static int reg_attrs_htab_eq (const void *, const void *);
  static reg_attrs *get_reg_attrs (tree, int);
--- 193,200 ----
  static rtx lookup_const_fixed (rtx);
  static hashval_t mem_attrs_htab_hash (const void *);
  static int mem_attrs_htab_eq (const void *, const void *);
! static mem_attrs *get_mem_attrs (alias_set_type, tree, tree, rtx, rtx, 
! 				 unsigned int, enum machine_mode);
  static hashval_t reg_attrs_htab_hash (const void *);
  static int reg_attrs_htab_eq (const void *, const void *);
  static reg_attrs *get_reg_attrs (tree, int);
*************** mem_attrs_htab_hash (const void *x)
*** 295,301 ****
    return (p->alias ^ (p->align * 1000)
  	  ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
  	  ^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
! 	  ^ (size_t) iterative_hash_expr (p->expr, 0));
  }
  
  /* Returns nonzero if the value represented by X (which is really a
--- 296,304 ----
    return (p->alias ^ (p->align * 1000)
  	  ^ ((p->offset ? INTVAL (p->offset) : 0) * 50000)
  	  ^ ((p->size ? INTVAL (p->size) : 0) * 2500000)
! 	  ^ (size_t) iterative_hash_expr (p->expr, 
!                                           iterative_hash_expr (p->orig_expr, 
!                                                                0)));
  }
  
  /* Returns nonzero if the value represented by X (which is really a
*************** mem_attrs_htab_eq (const void *x, const 
*** 312,318 ****
  	  && p->size == q->size && p->align == q->align
  	  && (p->expr == q->expr
  	      || (p->expr != NULL_TREE && q->expr != NULL_TREE
! 		  && operand_equal_p (p->expr, q->expr, 0))));
  }
  
  /* Allocate a new mem_attrs structure and insert it into the hash table if
--- 315,324 ----
  	  && p->size == q->size && p->align == q->align
  	  && (p->expr == q->expr
  	      || (p->expr != NULL_TREE && q->expr != NULL_TREE
! 		  && operand_equal_p (p->expr, q->expr, 0)))
!           && (p->orig_expr == q->orig_expr
!               || (p->orig_expr != NULL_TREE && q->orig_expr != NULL_TREE
!                   && operand_equal_p (p->orig_expr, q->orig_expr, 0))));
  }
  
  /* Allocate a new mem_attrs structure and insert it into the hash table if
*************** mem_attrs_htab_eq (const void *x, const 
*** 320,327 ****
     MEM of mode MODE.  */
  
  static mem_attrs *
! get_mem_attrs (alias_set_type alias, tree expr, rtx offset, rtx size,
! 	       unsigned int align, enum machine_mode mode)
  {
    mem_attrs attrs;
    void **slot;
--- 326,333 ----
     MEM of mode MODE.  */
  
  static mem_attrs *
! get_mem_attrs (alias_set_type alias, tree expr, tree orig_expr, rtx offset, 
! 	       rtx size, unsigned int align, enum machine_mode mode)
  {
    mem_attrs attrs;
    void **slot;
*************** get_mem_attrs (alias_set_type alias, tre
*** 329,335 ****
    /* If everything is the default, we can just return zero.
       This must match what the corresponding MEM_* macros return when the
       field is not present.  */
!   if (alias == 0 && expr == 0 && offset == 0
        && (size == 0
  	  || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
        && (STRICT_ALIGNMENT && mode != BLKmode
--- 335,341 ----
    /* If everything is the default, we can just return zero.
       This must match what the corresponding MEM_* macros return when the
       field is not present.  */
!   if (alias == 0 && expr == 0 && orig_expr == 0 && offset == 0
        && (size == 0
  	  || (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
        && (STRICT_ALIGNMENT && mode != BLKmode
*************** get_mem_attrs (alias_set_type alias, tre
*** 338,343 ****
--- 344,350 ----
  
    attrs.alias = alias;
    attrs.expr = expr;
+   attrs.orig_expr = orig_expr;
    attrs.offset = offset;
    attrs.size = size;
    attrs.align = align;
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1588,1593 ****
--- 1595,1601 ----
  {
    alias_set_type alias = MEM_ALIAS_SET (ref);
    tree expr = MEM_EXPR (ref);
+   tree orig_expr = NULL_TREE;
    rtx offset = MEM_OFFSET (ref);
    rtx size = MEM_SIZE (ref);
    unsigned int align = MEM_ALIGN (ref);
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1653,1658 ****
--- 1661,1668 ----
        tree base;
        bool align_computed = false;
  
+       orig_expr = t;
+ 
        if (TREE_THIS_VOLATILE (t))
  	MEM_VOLATILE_P (ref) = 1;
  
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1837,1847 ****
  	 we're overlapping.  */
        offset = NULL;
        expr = NULL;
      }
- 
-   /* Now set the attributes we computed above.  */
    MEM_ATTRS (ref)
!     = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref));
  
    /* If this is already known to be a scalar or aggregate, we are done.  */
    if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
--- 1847,1865 ----
  	 we're overlapping.  */
        offset = NULL;
        expr = NULL;
+       orig_expr = NULL;
+     }
+   
+   /* Now set the attributes we computed above, but unshare orig_expr first.  */
+   if (orig_expr)
+     {
+       if (flag_alias_export || flag_ddg_export)
+         orig_expr = unshare_and_record_pta_info (orig_expr);
+       else
+         orig_expr = NULL_TREE;
      }
    MEM_ATTRS (ref)
!     = get_mem_attrs (alias, expr, orig_expr, offset, size, align, GET_MODE (ref));
  
    /* If this is already known to be a scalar or aggregate, we are done.  */
    if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref))
*************** set_mem_alias_set (rtx mem, alias_set_ty
*** 1871,1879 ****
    gcc_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
  #endif
  
!   MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem),
! 				   MEM_SIZE (mem), MEM_ALIGN (mem),
! 				   GET_MODE (mem));
  }
  
  /* Set the alignment of MEM to ALIGN bits.  */
--- 1889,1897 ----
    gcc_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
  #endif
  
!   MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_ORIG_EXPR (mem),
! 				   MEM_OFFSET (mem), MEM_SIZE (mem), 
! 				   MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Set the alignment of MEM to ALIGN bits.  */
*************** void
*** 1882,1889 ****
  set_mem_align (rtx mem, unsigned int align)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_OFFSET (mem), MEM_SIZE (mem), align,
! 				   GET_MODE (mem));
  }
  
  /* Set the expr for MEM to EXPR.  */
--- 1900,1907 ----
  set_mem_align (rtx mem, unsigned int align)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_ORIG_EXPR (mem), MEM_OFFSET (mem), 
! 				   MEM_SIZE (mem), align, GET_MODE (mem));
  }
  
  /* Set the expr for MEM to EXPR.  */
*************** set_mem_align (rtx mem, unsigned int ali
*** 1891,1899 ****
  void
  set_mem_expr (rtx mem, tree expr)
  {
    MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
! 		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Set the offset of MEM to OFFSET.  */
--- 1909,1941 ----
  void
  set_mem_expr (rtx mem, tree expr)
  {
+   tree orig_expr = MEM_ORIG_EXPR (mem);
+ 
+   /* If MEM_EXPR changes, clear MEM_ORIG_EXPR.  If we still can preserve it,
+      we insert set_mem_orig_expr call right after this function call.  */
+   if (!expr || !mem_expr_equal_p (MEM_EXPR (mem), expr))
+     orig_expr = NULL_TREE;
+   
    MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), expr, orig_expr,
! 		     MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem), 
! 		     GET_MODE (mem));
! }
! 
! 
! /* Set the original expr for MEM to ORIG_EXPR.  */
! 
! void
! set_mem_orig_expr (rtx mem, tree orig_expr)
! {
!   if (orig_expr 
!       && currently_expanding_to_rtl
!       && (flag_alias_export || flag_ddg_export))
!     orig_expr = unshare_and_record_pta_info (orig_expr);
!   MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem), orig_expr,
! 		     MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem), 
! 		     GET_MODE (mem));
  }
  
  /* Set the offset of MEM to OFFSET.  */
*************** set_mem_expr (rtx mem, tree expr)
*** 1901,1909 ****
  void
  set_mem_offset (rtx mem, rtx offset)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   offset, MEM_SIZE (mem), MEM_ALIGN (mem),
! 				   GET_MODE (mem));
  }
  
  /* Set the size of MEM to SIZE.  */
--- 1943,1958 ----
  void
  set_mem_offset (rtx mem, rtx offset)
  {
+   tree orig_expr = MEM_ORIG_EXPR (mem);
+ 
+   /* If MEM_EXPR changes, clear MEM_ORIG_EXPR.  If we still can preserve it,
+      we insert set_mem_orig_expr call right after this function call.  */
+   if (offset != MEM_OFFSET (mem))
+     orig_expr = NULL_TREE;
+ 
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   orig_expr, offset, MEM_SIZE (mem),
! 				   MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Set the size of MEM to SIZE.  */
*************** void
*** 1912,1919 ****
  set_mem_size (rtx mem, rtx size)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_OFFSET (mem), size, MEM_ALIGN (mem),
! 				   GET_MODE (mem));
  }
  
  /* Return a memory reference like MEMREF, but with its mode changed to MODE
--- 1961,1968 ----
  set_mem_size (rtx mem, rtx size)
  {
    MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
! 				   MEM_ORIG_EXPR (mem), MEM_OFFSET (mem), 
! 				   size, MEM_ALIGN (mem), GET_MODE (mem));
  }
  
  /* Return a memory reference like MEMREF, but with its mode changed to MODE
*************** change_address (rtx memref, enum machine
*** 1980,1986 ****
      }
  
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
  
    return new_rtx;
  }
--- 2029,2035 ----
      }
  
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, 0, size, align, mmode);
  
    return new_rtx;
  }
*************** adjust_address_1 (rtx memref, enum machi
*** 2063,2069 ****
      size = plus_constant (MEM_SIZE (memref), -offset);
  
    MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
! 				   memoffset, size, memalign, GET_MODE (new_rtx));
  
    /* At some point, we should validate that this offset is within the object,
       if all the appropriate values are known.  */
--- 2112,2122 ----
      size = plus_constant (MEM_SIZE (memref), -offset);
  
    MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
!                                        (offset != 0 || size == NULL
!                                         || GET_MODE_SIZE (mode) > INTVAL (size))
!                                        ? NULL_TREE
!                                        : MEM_ORIG_EXPR (memref), 
!                                        memoffset, size, memalign, GET_MODE (new_rtx));
  
    /* At some point, we should validate that this offset is within the object,
       if all the appropriate values are known.  */
*************** offset_address (rtx memref, rtx offset, 
*** 2119,2126 ****
    /* Update the alignment to reflect the offset.  Reset the offset, which
       we don't know.  */
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
! 		     MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
  		     GET_MODE (new_rtx));
    return new_rtx;
  }
--- 2172,2180 ----
    /* Update the alignment to reflect the offset.  Reset the offset, which
       we don't know.  */
    MEM_ATTRS (new_rtx)
!     = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 
! 		     MEM_ORIG_EXPR (memref), 0, 0, 
!                      MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
  		     GET_MODE (new_rtx));
    return new_rtx;
  }
*************** widen_memory_access (rtx memref, enum ma
*** 2223,2231 ****
  
    /* The widened memory may alias other stuff, so zap the alias set.  */
    /* ??? Maybe use get_alias_set on any remaining expression.  */
! 
!   MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
! 				   MEM_ALIGN (new_rtx), mode);
  
    return new_rtx;
  }
--- 2277,2285 ----
  
    /* The widened memory may alias other stuff, so zap the alias set.  */
    /* ??? Maybe use get_alias_set on any remaining expression.  */
!   MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, NULL_TREE, memoffset, 
!                                        GEN_INT (size), MEM_ALIGN (new_rtx), 
!                                        mode);
  
    return new_rtx;
  }
*************** get_spill_slot_decl (bool force_build_p)
*** 2252,2258 ****
  
    rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
    MEM_NOTRAP_P (rd) = 1;
!   MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, const0_rtx,
  				  NULL_RTX, 0, BLKmode);
    SET_DECL_RTL (d, rd);
  
--- 2306,2312 ----
  
    rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
    MEM_NOTRAP_P (rd) = 1;
!   MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, NULL_TREE, const0_rtx,
  				  NULL_RTX, 0, BLKmode);
    SET_DECL_RTL (d, rd);
  
*************** set_mem_attrs_for_spill (rtx mem)
*** 2284,2290 ****
        && CONST_INT_P (XEXP (addr, 1)))
      offset = XEXP (addr, 1);
  
!   MEM_ATTRS (mem) = get_mem_attrs (alias, expr, offset,
  				   MEM_SIZE (mem), MEM_ALIGN (mem),
  				   GET_MODE (mem));
    MEM_NOTRAP_P (mem) = 1;
--- 2338,2344 ----
        && CONST_INT_P (XEXP (addr, 1)))
      offset = XEXP (addr, 1);
  
!   MEM_ATTRS (mem) = get_mem_attrs (alias, expr, NULL_TREE, offset,
  				   MEM_SIZE (mem), MEM_ALIGN (mem),
  				   GET_MODE (mem));
    MEM_NOTRAP_P (mem) = 1;
diff -cprdN -x .svn -x TAGS trunk/gcc/emit-rtl.h alias-export/gcc/emit-rtl.h
*** trunk/gcc/emit-rtl.h	Wed Apr  8 13:59:49 2009
--- alias-export/gcc/emit-rtl.h	Tue Apr 14 15:40:33 2009
*************** extern void set_mem_align (rtx, unsigned
*** 29,34 ****
--- 29,37 ----
  /* Set the expr for MEM to EXPR.  */
  extern void set_mem_expr (rtx, tree);
  
+ /* Set the original expr for MEM to ORIG_EXPR.  */
+ extern void set_mem_orig_expr (rtx, tree);
+ 
  /* Set the offset for MEM to OFFSET.  */
  extern void set_mem_offset (rtx, rtx);
  
diff -cprdN -x .svn -x TAGS trunk/gcc/expr.c alias-export/gcc/expr.c
*** trunk/gcc/expr.c	Tue Jun 30 15:09:51 2009
--- alias-export/gcc/expr.c	Tue Jun 30 15:22:32 2009
*************** expand_expr_real_1 (tree exp, rtx target
*** 7642,7647 ****
--- 7642,7655 ----
  	op0 = memory_address (mode, op0);
  	temp = gen_rtx_MEM (mode, op0);
  	set_mem_attributes (temp, TMR_ORIGINAL (exp), 0);
+         /* If TMR_ORIGINAL has INDIRECT_REF as base, we don't 
+            want it to be in MEM_ORIG_EXPR, as this will not add
+            any information to the oracle.  
+            This however may hamper data dependency export when we will 
+            compute dependencies for pointer accesses.  */
+         if (TMR_ORIGINAL (exp)
+             && INDIRECT_REF_P (get_base_address (TMR_ORIGINAL (exp))))
+           set_mem_orig_expr (temp, NULL);
        }
        return temp;
  
diff -cprdN -x .svn -x TAGS trunk/gcc/final.c alias-export/gcc/final.c
*** trunk/gcc/final.c	Tue Jun 30 15:09:50 2009
--- alias-export/gcc/final.c	Tue Jun 30 15:19:40 2009
*************** along with GCC; see the file COPYING3.  
*** 72,77 ****
--- 72,78 ----
  #include "expr.h"
  #include "cfglayout.h"
  #include "tree-pass.h"
+ #include "tree-flow.h"
  #include "timevar.h"
  #include "cgraph.h"
  #include "coverage.h"
*************** along with GCC; see the file COPYING3.  
*** 79,84 ****
--- 80,86 ----
  #include "vecprim.h"
  #include "ggc.h"
  #include "cfgloop.h"
+ #include "alias-export.h"
  #include "params.h"
  
  #ifdef XCOFF_DEBUGGING_INFO
*************** rest_of_clean_state (void)
*** 4422,4427 ****
--- 4424,4436 ----
  
    free_bb_for_insn ();
  
+   delete_tree_ssa ();
+ 
+   if (flag_alias_export)
+     free_alias_export_info ();
+   if (flag_ddg_export)
+     free_ddg_export_info ();
+ 
    if (targetm.binds_local_p (current_function_decl))
      {
        unsigned int pref = crtl->preferred_stack_boundary;
diff -cprdN -x .svn -x TAGS trunk/gcc/function.c alias-export/gcc/function.c
*** trunk/gcc/function.c	Tue Jun 30 15:09:52 2009
--- alias-export/gcc/function.c	Tue Jun 30 15:26:00 2009
*************** assign_parms_unsplit_complex (struct ass
*** 3095,3101 ****
  	  /* Set MEM_EXPR to the original decl, i.e. to PARM,
  	     instead of the copy of decl, i.e. FNARGS.  */
  	  if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm)))
! 	    set_mem_expr (DECL_INCOMING_RTL (parm), parm);
  	}
  
        fnargs = TREE_CHAIN (fnargs);
--- 3095,3104 ----
  	  /* Set MEM_EXPR to the original decl, i.e. to PARM,
  	     instead of the copy of decl, i.e. FNARGS.  */
  	  if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm)))
! 	    {
! 	      set_mem_expr (DECL_INCOMING_RTL (parm), parm);
! 	      set_mem_orig_expr (DECL_INCOMING_RTL (parm), parm);
! 	    }
  	}
  
        fnargs = TREE_CHAIN (fnargs);
diff -cprdN -x .svn -x TAGS trunk/gcc/loop-unroll.c alias-export/gcc/loop-unroll.c
*** trunk/gcc/loop-unroll.c	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/loop-unroll.c	Wed Jun  3 16:22:27 2009
*************** along with GCC; see the file COPYING3.  
*** 33,38 ****
--- 33,39 ----
  #include "expr.h"
  #include "hashtab.h"
  #include "recog.h"    
+ #include "alias-export.h"
  
  /* This pass performs loop unrolling and peeling.  We only perform these
     optimizations on innermost loops (with single exception) because
*************** apply_opt_in_copies (struct opt_info *op
*** 2218,2223 ****
--- 2219,2227 ----
                    expand_var_during_unrolling (ves, insn);
                  }
              }
+ 
+           if (flag_ddg_export)
+             remove_exported_ddg_data (insn);
            orig_insn = NEXT_INSN (orig_insn);
          }
      }
*************** apply_opt_in_copies (struct opt_info *op
*** 2254,2259 ****
--- 2258,2266 ----
            
            if (!INSN_P (orig_insn))
   	    continue;
+ 
+           if (flag_ddg_export)
+             remove_exported_ddg_data (orig_insn);
            
            ivts_templ.insn = orig_insn;
            if (opt_info->insns_to_split)
diff -cprdN -x .svn -x TAGS trunk/gcc/modulo-sched.c alias-export/gcc/modulo-sched.c
*** trunk/gcc/modulo-sched.c	Tue Jun 30 15:09:51 2009
--- alias-export/gcc/modulo-sched.c	Tue Jun 30 15:22:12 2009
*************** along with GCC; see the file COPYING3.  
*** 48,53 ****
--- 48,54 ----
  #include "timevar.h"
  #include "tree-pass.h"
  #include "dbgcnt.h"
+ #include "alias-export.h"
  
  #ifdef INSN_SCHEDULING
  
*************** rest_of_handle_sms (void)
*** 2875,2880 ****
--- 2876,2884 ----
        bb->aux = bb->next_bb;
    free_dominance_info (CDI_DOMINATORS);
    cfg_layout_finalize ();
+ 
+   if (flag_ddg_export)
+     ddg_export_set_pipelining_completed (true);
  #endif /* INSN_SCHEDULING */
    return 0;
  }
diff -cprdN -x .svn -x TAGS trunk/gcc/passes.c alias-export/gcc/passes.c
*** trunk/gcc/passes.c	Tue Jun 30 15:09:53 2009
--- alias-export/gcc/passes.c	Tue Jun 30 15:34:10 2009
*************** init_optimization_passes (void)
*** 670,675 ****
--- 670,676 ----
  	  NEXT_PASS (pass_slp_vectorize);
  	  NEXT_PASS (pass_parallelize_loops);
  	  NEXT_PASS (pass_loop_prefetch);
+ 	  NEXT_PASS (pass_gather_ddg_info);
  	  NEXT_PASS (pass_iv_optimize);
  	  NEXT_PASS (pass_tree_loop_done);
  	}
*************** init_optimization_passes (void)
*** 705,710 ****
--- 706,712 ----
        NEXT_PASS (pass_uncprop);
        NEXT_PASS (pass_local_pure_const);
      }
+ 
    NEXT_PASS (pass_cleanup_eh);
    NEXT_PASS (pass_nrv);
    NEXT_PASS (pass_mudflap_2);
diff -cprdN -x .svn -x TAGS trunk/gcc/rtl.h alias-export/gcc/rtl.h
*** trunk/gcc/rtl.h	Mon Jun 22 12:00:22 2009
--- alias-export/gcc/rtl.h	Tue Jun 30 15:33:45 2009
*************** typedef struct GTY(()) mem_attrs
*** 146,151 ****
--- 146,152 ----
    rtx size;			/* Size in bytes, as a CONST_INT.  */
    alias_set_type alias;		/* Memory alias set.  */
    unsigned int align;		/* Alignment of MEM in bits.  */
+   tree orig_expr;		/* Explicit original tree expression.  */
  } mem_attrs;
  
  /* Structure used to describe the attributes of a REG in similar way as
*************** do {						\
*** 1226,1231 ****
--- 1227,1237 ----
   : (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode			\
      ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))
  
+ /* For a MEM rtx, the decl it is known to refer to, if it is known to
+    refer to part of a DECL.  It may also be a COMPONENT_REF.  */
+ #define MEM_ORIG_EXPR(RTX)						\
+ (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->orig_expr)
+ 
  /* For a REG rtx, the decl it is known to refer to, if it is known to
     refer to part of a DECL.  */
  #define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
*************** extern void simplify_using_condition (rt
*** 2343,2348 ****
--- 2349,2355 ----
  
  /* In final.c  */
  extern unsigned int compute_alignments (void);
+ 
  
  struct rtl_hooks
  {
diff -cprdN -x .svn -x TAGS trunk/gcc/sel-sched.c alias-export/gcc/sel-sched.c
*** trunk/gcc/sel-sched.c	Tue Jun 30 15:08:38 2009
--- alias-export/gcc/sel-sched.c	Tue Jun 30 15:22:19 2009
*************** along with GCC; see the file COPYING3.  
*** 51,56 ****
--- 51,57 ----
  #include "sel-sched-dump.h"
  #include "sel-sched.h"
  #include "dbgcnt.h"
+ #include "alias-export.h"
  
  /* Implementation of selective scheduling approach.
     The below implementation follows the original approach with the following
*************** sel_global_finish (void)
*** 7322,7327 ****
--- 7323,7332 ----
  
    free_sched_pools ();
    free_dominance_info (CDI_DOMINATORS);
+ 
+   if (flag_ddg_export
+       && flag_sel_sched_pipelining)
+     ddg_export_set_pipelining_completed (true);
  }
  
  /* Return true when we need to skip selective scheduling.  Used for debugging.  */
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-dfa.c alias-export/gcc/tree-dfa.c
*** trunk/gcc/tree-dfa.c	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/tree-dfa.c	Wed Jun  3 16:22:32 2009
*************** referenced_var_lookup (unsigned int uid)
*** 502,507 ****
--- 502,521 ----
    return h;
  }
  
+ /* Same as above, but return NULL in case the variable associated with UID
+    is not in the referenced_vars at all.  */
+ 
+ tree 
+ referenced_var_lookup_safe (unsigned int uid)
+ {
+   tree h;
+   struct tree_decl_minimal in;
+   in.uid = uid;
+   h = (tree) htab_find_with_hash (gimple_referenced_vars (cfun), &in, uid);
+   return h;
+ }
+ 
+ 
  /* Check if TO is in the referenced_vars hash table and insert it if not.  
     Return true if it required insertion.  */
  
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-flow.h alias-export/gcc/tree-flow.h
*** trunk/gcc/tree-flow.h	Wed Jun 10 19:50:07 2009
--- alias-export/gcc/tree-flow.h	Tue Jun 30 15:33:58 2009
*************** typedef struct
*** 396,401 ****
--- 396,402 ----
         (ITER).i++)
  
  extern tree referenced_var_lookup (unsigned int);
+ extern tree referenced_var_lookup_safe (unsigned int);
  extern bool referenced_var_check_and_insert (tree);
  #define num_referenced_vars htab_elements (gimple_referenced_vars (cfun))
  #define referenced_var(i) referenced_var_lookup (i)
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-optimize.c alias-export/gcc/tree-optimize.c
*** trunk/gcc/tree-optimize.c	Tue Apr 28 11:40:36 2009
--- alias-export/gcc/tree-optimize.c	Fri May 29 10:54:24 2009
*************** execute_free_datastructures (void)
*** 226,235 ****
    free_dominance_info (CDI_DOMINATORS);
    free_dominance_info (CDI_POST_DOMINATORS);
  
-   /* Remove the ssa structures.  */
-   if (cfun->gimple_df)
-     delete_tree_ssa ();
- 
    /* And get rid of annotations we no longer need.  */
    delete_tree_cfg_annotations ();
  
--- 226,231 ----
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-pass.h alias-export/gcc/tree-pass.h
*** trunk/gcc/tree-pass.h	Mon Jun 22 12:00:20 2009
--- alias-export/gcc/tree-pass.h	Tue Jun 30 15:19:30 2009
*************** extern struct rtl_opt_pass pass_branch_t
*** 504,509 ****
--- 504,510 ----
  extern struct rtl_opt_pass pass_leaf_regs;
  extern struct rtl_opt_pass pass_split_before_sched2;
  extern struct rtl_opt_pass pass_sched2;
+ extern struct gimple_opt_pass pass_gather_ddg_info;
  extern struct rtl_opt_pass pass_stack_regs;
  extern struct rtl_opt_pass pass_stack_regs_run;
  extern struct rtl_opt_pass pass_df_finish;
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-ssa-loop-ivopts.c alias-export/gcc/tree-ssa-loop-ivopts.c
*** trunk/gcc/tree-ssa-loop-ivopts.c	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/tree-ssa-loop-ivopts.c	Wed Jun  3 16:20:17 2009
*************** along with GCC; see the file COPYING3.  
*** 91,96 ****
--- 91,97 ----
  #include "params.h"
  #include "langhooks.h"
  #include "tree-affine.h"
+ #include "alias-export.h"
  #include "target.h"
  
  /* The infinite cost.  */
*************** copy_ref_info (tree new_ref, tree old_re
*** 5281,5287 ****
    if (TREE_CODE (old_ref) == TARGET_MEM_REF)
      copy_mem_ref_info (new_ref, old_ref);
    else
!     TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
  }
  
  /* Rewrites USE (address that is an iv) using candidate CAND.  */
--- 5282,5295 ----
    if (TREE_CODE (old_ref) == TARGET_MEM_REF)
      copy_mem_ref_info (new_ref, old_ref);
    else
!     {
!       TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
!       /* As MEM_ORIG_EXPR binds MEM to TMR_ORIGINAL of TARGET_MEM_REF it was
!          produced from, we need to change all occurences of OLD_REF to
!          TMR_ORIGINAL (NEW_REF) in exported data.  */
!       if (flag_ddg_export)
!         replace_var_in_datarefs (old_ref, TMR_ORIGINAL (new_ref));
!     }
  }
  
  /* Rewrites USE (address that is an iv) using candidate CAND.  */
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-ssa-uncprop.c alias-export/gcc/tree-ssa-uncprop.c
*** trunk/gcc/tree-ssa-uncprop.c	Tue Jun 30 15:09:51 2009
--- alias-export/gcc/tree-ssa-uncprop.c	Tue Jun 30 15:19:56 2009
*************** struct gimple_opt_pass pass_uncprop = 
*** 600,606 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_ssa	/* todo_flags_finish */
   }
  };
  
--- 600,607 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_ssa
!   | TODO_rebuild_alias                 /* todo_flags_finish */
   }
  };
  
diff -cprdN -x .svn -x TAGS trunk/gcc/tree-ssa.c alias-export/gcc/tree-ssa.c
*** trunk/gcc/tree-ssa.c	Mon Jun 22 12:00:22 2009
--- alias-export/gcc/tree-ssa.c	Tue Jun 30 15:33:41 2009
*************** along with GCC; see the file COPYING3.  
*** 44,49 ****
--- 44,50 ----
  #include "hashtab.h"
  #include "tree-dump.h"
  #include "tree-pass.h"
+ #include "alias-export.h"
  #include "toplev.h"
  
  /* Pointer map of variable mappings, keyed by edge.  */
*************** void
*** 803,810 ****
  delete_tree_ssa (void)
  {
    size_t i;
-   basic_block bb;
-   gimple_stmt_iterator gsi;
    referenced_var_iterator rvi;
    tree var;
  
--- 804,809 ----
*************** delete_tree_ssa (void)
*** 817,851 ****
  	  SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
  	  SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
  	}
!       release_ssa_name (var);
!     }
! 
!   /* FIXME.  This may not be necessary.  We will release all this
!      memory en masse in free_ssa_operands.  This clearing used to be
!      necessary to avoid problems with the inliner, but it may not be
!      needed anymore.  */
!   FOR_EACH_BB (bb)
!     {
!       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
! 	{
! 	  gimple stmt = gsi_stmt (gsi);
! 
! 	  if (gimple_has_ops (stmt))
! 	    {
! 	      gimple_set_def_ops (stmt, NULL);
! 	      gimple_set_use_ops (stmt, NULL);
! 	    }
! 
! 	  if (gimple_has_mem_ops (stmt))
! 	    {
! 	      gimple_set_vdef (stmt, NULL_TREE);
! 	      gimple_set_vuse (stmt, NULL_TREE);
! 	    }
! 
! 	  gimple_set_modified (stmt, true);
! 	}
!       if (!(bb->flags & BB_RTL))
! 	set_phi_nodes (bb, NULL);
      }
  
    /* Remove annotations from every referenced local variable.  */
--- 816,823 ----
  	  SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
  	  SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
  	}
!       if (! var || TREE_CODE (var) != SSA_NAME)
!         release_ssa_name (var);
      }
  
    /* Remove annotations from every referenced local variable.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]