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


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.

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. Also, the patch/changelog doesn't have code I would submit separately).

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.

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:

void
overflow()
{
  int i = 0;
  char foo[30];

  /* Overflow buffer.  */
  for (i = 0; i < 50; i++)
      foo[i] = 42;
}

with the patch the loop counter (i) is placed on stack after the foo array, instead of before it, so it gets overwritten by the loop and it never terminates. The stack protector marker stays in the same place though, I have no idea whether this is correct or not, and what should be changed in stack protector to make the patch work. Meanwhile, I just check for SSA_NAMEs in update_alias_info_with_stack_vars.

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.

Andrey


2009-06-03 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.
(walk_mems_2): Also query ddg export info.
(true_dependence): Use query_alias_export_info.
(canon_true_dependence, write_dependence_p): Likewise.
* common.opt (falias-export, fddg-export): New options.
* dbgcnt.def (alias_export, ddg_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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/Makefile.in	Wed Jun  3 16:22:46 2009
*************** OBJS-common = \
*** 1079,1084 ****
--- 1079,1085 ----
  	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
*** 2088,2093 ****
--- 2089,2101 ----
  
  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) $
*** 2125,2131 ****
     $(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) \
--- 2133,2139 ----
     $(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
*** 2317,2323 ****
     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)
--- 2325,2331 ----
     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
*** 2339,2345 ****
     $(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) \
--- 2347,2353 ----
     $(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
*** 2621,2627 ****
     $(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) \
--- 2629,2635 ----
     $(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
*** 2890,2896 ****
  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
--- 2898,2904 ----
  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
*** 2949,2955 ****
  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) \
--- 2957,2963 ----
  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)
*** 3006,3012 ****
     $(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 \
--- 3014,3020 ----
     $(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) $(
*** 3032,3038 ****
     $(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) \
--- 3040,3046 ----
     $(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
*** 3049,3055 ****
     $(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 \
--- 3057,3063 ----
     $(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	Tue Jun  2 19:31:38 2009
***************
*** 0 ****
--- 1,619 ----
+ /* 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.  */
+ 
+ /* 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 (! 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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/alias.c	Wed Jun  3 16:22:24 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);
*** 250,255 ****
--- 251,280 ----
  /* 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)
*** 347,353 ****
  {
    if (MEM_P (*x))
      {
!       if (alias_sets_conflict_p (MEM_ALIAS_SET(*x), MEM_ALIAS_SET(mem)))
          return 1;
          
        return -1;  
--- 372,381 ----
  {
    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
*** 2274,2280 ****
    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))
--- 2302,2311 ----
    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
*** 2338,2344 ****
  
    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))
--- 2369,2378 ----
  
    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
*** 2407,2414 ****
    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
--- 2441,2451 ----
    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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/builtins.c	Wed Jun  3 16:19:24 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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/cfgexpand.c	Wed Jun  3 16:22:34 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
*** 762,767 ****
--- 763,819 ----
    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
*** 774,789 ****
--- 826,845 ----
  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)
*** 881,886 ****
--- 937,945 ----
  	    break;
  	}
      }
+ 
+   if (flag_alias_export)
+     update_alias_info_with_stack_vars ();
  }
  
  /* A debugging aid for expand_used_vars.  Dump the generated partitions.  */
*************** discover_nonconstant_array_refs_r (tree 
*** 2321,2328 ****
        if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
  	  t = get_base_address (t);
! 	  if (t && DECL_P (t))
! 	    TREE_ADDRESSABLE (t) = 1;
  	}
  
        *walk_subtrees = 0;
--- 2380,2388 ----
        if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
  	  t = get_base_address (t);
! 	  if (t && DECL_P (t)
!               && DECL_MODE (t) != BLKmode)
!             TREE_ADDRESSABLE (t) = 1;
  	}
  
        *walk_subtrees = 0;
*************** gimple_expand_cfg (void)
*** 2465,2471 ****
    crtl->preferred_stack_boundary = STACK_BOUNDARY;
    cfun->cfg->max_jumptable_ents = 0;
  
- 
    /* Expand the variables recorded during gimple lowering.  */
    expand_used_vars ();
  
--- 2525,2530 ----
*************** gimple_expand_cfg (void)
*** 2500,2509 ****
  	 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);
  	}
      }
  
--- 2559,2569 ----
  	 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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/common.opt	Wed Jun  3 16:22:37 2009
*************** fexpensive-optimizations
*** 494,499 ****
--- 494,507 ----
  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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/emit-rtl.c	Wed Jun  3 16:22:33 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)
*** 2251,2257 ****
  
    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);
  
--- 2305,2311 ----
  
    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)
*** 2283,2289 ****
        && GET_CODE (XEXP (addr, 1)) == CONST_INT)
      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;
--- 2337,2343 ----
        && GET_CODE (XEXP (addr, 1)) == CONST_INT)
      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	Fri May 29 11:12:29 2009
--- alias-export/gcc/expr.c	Fri May 29 11:50:05 2009
*************** expand_expr_real_1 (tree exp, rtx target
*** 7613,7618 ****
--- 7613,7621 ----
  	op0 = memory_address (mode, op0);
  	temp = gen_rtx_MEM (mode, op0);
  	set_mem_attributes (temp, TMR_ORIGINAL (exp), 0);
+ 
+         if (! MEM_ORIG_EXPR (temp))
+           set_mem_orig_expr (temp, TMR_ORIGINAL (exp));
        }
        return temp;
  
diff -cprdN -x .svn -x TAGS trunk/gcc/final.c alias-export/gcc/final.c
*** trunk/gcc/final.c	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/final.c	Wed Jun  3 16:19:21 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)
*** 4336,4341 ****
--- 4338,4350 ----
  
    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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/function.c	Wed Jun  3 16:22:22 2009
*************** assign_parms_unsplit_complex (struct ass
*** 3093,3099 ****
  	  /* 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);
--- 3093,3102 ----
  	  /* 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	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/rtl.h	Wed Jun  3 16:22:40 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 {						\
*** 1220,1225 ****
--- 1221,1231 ----
   : (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
*** 2337,2342 ****
--- 2343,2349 ----
  
  /* 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	Fri May 29 11:12:29 2009
--- alias-export/gcc/tree-flow.h	Tue Jun  2 18:58:55 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-alias.c alias-export/gcc/tree-ssa-alias.c
*** trunk/gcc/tree-ssa-alias.c	Wed Jun  3 16:05:39 2009
--- alias-export/gcc/tree-ssa-alias.c	Wed Jun  3 16:21:52 2009
*************** along with GCC; see the file COPYING3.  
*** 49,54 ****
--- 49,55 ----
  #include "pointer-set.h"
  #include "alloc-pool.h"
  #include "tree-ssa-alias.h"
+ #include "alias-export.h"
  
  /* Broad overview of how alias analysis on gimple works:
  
*************** dump_alias_stats (FILE *s)
*** 135,141 ****
  	   + alias_stats.call_may_clobber_ref_p_may_alias);
  }
  
- 
  /* Return true, if dereferencing PTR may alias with a global variable.  */
  
  bool
--- 136,141 ----
*************** 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);
*************** ptr_derefs_may_alias_p (tree ptr1, tree 
*** 211,218 ****
        || TREE_CODE (ptr2) == INTEGER_CST)
      return true;
  
!   gcc_assert (TREE_CODE (ptr1) == SSA_NAME
! 	      && TREE_CODE (ptr2) == SSA_NAME);
  
    /* We may end up with two empty points-to solutions for two same pointers.
       In this case we still want to say both pointers alias, so shortcut
--- 216,227 ----
        || TREE_CODE (ptr2) == INTEGER_CST)
      return true;
  
!   if (TREE_CODE (ptr1) != SSA_NAME
!       || TREE_CODE (ptr2) != SSA_NAME)
!     {
!       gcc_assert (current_ir_type () != IR_GIMPLE);
!       return true;
!     }
  
    /* We may end up with two empty points-to solutions for two same pointers.
       In this case we still want to say both pointers alias, so shortcut
*************** ptr_derefs_may_alias_p (tree ptr1, tree 
*** 224,229 ****
--- 233,239 ----
       we cannot disambiguate anything else.  */
    pi1 = SSA_NAME_PTR_INFO (ptr1);
    pi2 = SSA_NAME_PTR_INFO (ptr2);
+ 
    if (!pi1 || !pi2)
      return true;
  
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 621,627 ****
      return false;
    if (!ptr_deref_may_alias_decl_p (ptr1, base2))
      return false;
! 
    /* Disambiguations that rely on strict aliasing rules follow.  */
    if (!flag_strict_aliasing)
      return true;
--- 631,637 ----
      return false;
    if (!ptr_deref_may_alias_decl_p (ptr1, base2))
      return false;
!   
    /* Disambiguations that rely on strict aliasing rules follow.  */
    if (!flag_strict_aliasing)
      return true;
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	Wed May  6 17:32:34 2009
--- alias-export/gcc/tree-ssa-uncprop.c	Tue Apr 28 14:36:20 2009
*************** struct gimple_opt_pass pass_uncprop = 
*** 606,612 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_ssa	/* todo_flags_finish */
   }
  };
  
--- 606,613 ----
    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	Fri May 29 11:12:29 2009
--- alias-export/gcc/tree-ssa.c	Wed Jun  3 16:00:49 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.  */

Attachment: alias-ddg-export-2009-06-03.diff.gz
Description: application/gzip


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