aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog35
-rw-r--r--gcc/Makefile.in7
-rw-r--r--gcc/alias.c114
-rw-r--r--gcc/cfgexpand.c129
-rw-r--r--gcc/emit-rtl.c58
-rw-r--r--gcc/final.c3
-rw-r--r--gcc/print-rtl.c54
-rw-r--r--gcc/tree-dfa.c2
-rw-r--r--gcc/tree-flow.h4
-rw-r--r--gcc/tree-optimize.c4
-rw-r--r--gcc/tree-ssa-alias.c2
-rw-r--r--gcc/tree-ssa-alias.h2
-rw-r--r--gcc/tree-ssa-structalias.c22
-rw-r--r--gcc/tree-ssa.c46
14 files changed, 319 insertions, 163 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cabfbe6..519c7cf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,38 @@
+2009-07-14 Richard Guenther <rguenther@suse.de>
+ Andrey Belevantsev <abel@ispras.ru>
+
+ * tree-ssa-alias.h (refs_may_alias_p_1): Declare.
+ (pt_solution_set): Likewise.
+ * tree-ssa-alias.c (refs_may_alias_p_1): Export.
+ * tree-ssa-structalias.c (pt_solution_set): New function.
+ * final.c (rest_of_clean_state): Free SSA data structures.
+ * print-rtl.c (print_decl_name): Remove.
+ (print_mem_expr): Implement in terms of print_generic_expr.
+ * alias.c (ao_ref_from_mem): New function.
+ (rtx_refs_may_alias_p): Likewise.
+ (true_dependence): Query alias-export info.
+ (canon_true_dependence): Likewise.
+ (write_dependence_p): Likewise.
+ * tree-dfa.c (get_ref_base_and_extent): For void types leave
+ size unknown.
+ * emit-rtl.c (component_ref_for_mem_expr): Remove.
+ (mem_expr_equal_p): Use operand_equal_p.
+ (set_mem_attributes_minus_bitpos): Do not use
+ component_ref_for_mem_expr.
+ * cfgexpand.c (add_partitioned_vars_to_ptset): New function.
+ (update_alias_info_with_stack_vars): Likewise.
+ (partition_stack_vars): Call update_alias_info_with_stack_vars.
+ * tree-ssa.c (delete_tree_ssa): Do not release SSA names
+ explicitly nor clear stmt operands.
+ Free the decl-to-pointer map.
+ * tree-optimize.c (execute_free_datastructures): Do not free
+ SSA data structures here.
+ * tree-flow.h (struct gimple_df): Add decls_to_pointers member.
+ * Makefile.in (emit-rtl.o): Add pointer-set.h dependency.
+ (alias.o): Add tree-ssa-alias.h, pointer-set.h and $(TREE_FLOW_H)
+ dependencies.
+ (print-rtl.o): Add $(DIAGNOSTIC_H) dependency.
+
2009-07-13 DJ Delorie <dj@redhat.com>
* config/mep/mep.h (CC1_SPEC): Tweak parameters to trigger
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9cdf6a2..9567dfe 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2565,7 +2565,7 @@ rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
- $(BCONFIG_H) $(REAL_H)
+ $(BCONFIG_H) $(REAL_H) $(DIAGNOSTIC_H)
rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
$(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
$(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
@@ -2653,7 +2653,7 @@ emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(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_H) $(DF_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) \
@@ -2978,7 +2978,8 @@ 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)
+ $(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) $(TREE_PASS_H) \
+ tree-ssa-alias.h pointer-set.h $(TREE_FLOW_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) \
$(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H)
diff --git a/gcc/alias.c b/gcc/alias.c
index 2486001..e9cc2d8 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -46,6 +46,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "ipa-type-escape.h"
#include "df.h"
+#include "tree-ssa-alias.h"
+#include "pointer-set.h"
+#include "tree-flow.h"
/* The aliasing API provided here solves related but different problems:
@@ -249,6 +252,98 @@ DEF_VEC_ALLOC_P(alias_set_entry,gc);
/* The splay-tree used to store the various alias set entries. */
static GTY (()) VEC(alias_set_entry,gc) *alias_sets;
+/* Build a decomposed reference object for querying the alias-oracle
+ from the MEM rtx and store it in *REF.
+ Returns false if MEM is not suitable for the alias-oracle. */
+
+static bool
+ao_ref_from_mem (ao_ref *ref, const_rtx mem)
+{
+ tree expr = MEM_EXPR (mem);
+ tree base;
+
+ if (!expr)
+ return false;
+
+ ao_ref_init (ref, expr);
+
+ /* Get the base of the reference and see if we have to reject or
+ adjust it. */
+ base = ao_ref_base (ref);
+ if (base == NULL_TREE)
+ return false;
+
+ /* If this is a pointer dereference of a non-SSA_NAME punt.
+ ??? We could replace it with a pointer to anything. */
+ if (INDIRECT_REF_P (base)
+ && TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME)
+ return false;
+
+ /* If this is a reference based on a partitioned decl replace the
+ base with an INDIRECT_REF of the pointer representative we
+ created during stack slot partitioning. */
+ if (TREE_CODE (base) == VAR_DECL
+ && ! TREE_STATIC (base)
+ && cfun->gimple_df->decls_to_pointers != NULL)
+ {
+ void *namep;
+ namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
+ if (namep)
+ {
+ ref->base_alias_set = get_alias_set (base);
+ ref->base = build1 (INDIRECT_REF, TREE_TYPE (base), *(tree *)namep);
+ }
+ }
+
+ ref->ref_alias_set = MEM_ALIAS_SET (mem);
+
+ /* For NULL MEM_OFFSET the MEM_EXPR may have been stripped arbitrarily
+ without recording offset or extent adjustments properly. */
+ if (MEM_OFFSET (mem) == NULL_RTX)
+ {
+ ref->offset = 0;
+ ref->max_size = -1;
+ }
+ else
+ {
+ ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT;
+ }
+
+ /* NULL MEM_SIZE should not really happen with a non-NULL MEM_EXPR,
+ but just play safe here. The size may have been adjusted together
+ with the offset, so we need to take it if it is set and not rely
+ on MEM_EXPR here (which has the size determining parts potentially
+ stripped anyway). We lose precision for max_size which is only
+ available from the remaining MEM_EXPR. */
+ if (MEM_SIZE (mem) == NULL_RTX)
+ {
+ ref->size = -1;
+ ref->max_size = -1;
+ }
+ else
+ {
+ ref->size = INTVAL (MEM_SIZE (mem)) * BITS_PER_UNIT;
+ }
+
+ return true;
+}
+
+/* Query the alias-oracle on whether the two memory rtx X and MEM may
+ alias. If TBAA_P is set also apply TBAA. Returns true if the
+ two rtxen may alias, false otherwise. */
+
+static bool
+rtx_refs_may_alias_p (const_rtx x, const_rtx mem, bool tbaa_p)
+{
+ ao_ref ref1, ref2;
+
+ if (!ao_ref_from_mem (&ref1, x)
+ || !ao_ref_from_mem (&ref2, mem))
+ return true;
+
+ return refs_may_alias_p_1 (&ref1, &ref2, tbaa_p);
+}
+
/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
such an entry, or NULL otherwise. */
@@ -2191,8 +2286,10 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x,
if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
return 1;
- return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
- varies);
+ if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
+ return 0;
+
+ return rtx_refs_may_alias_p (x, mem, true);
}
/* Canonical true dependence: X is read after store in MEM takes place.
@@ -2255,8 +2352,10 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
return 1;
- return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
- varies);
+ if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
+ return 0;
+
+ return rtx_refs_may_alias_p (x, mem, true);
}
/* Returns nonzero if a write to X might alias a previous read from
@@ -2316,8 +2415,11 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
= fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
rtx_addr_varies_p);
- return (!(fixed_scalar == mem && !aliases_everything_p (x))
- && !(fixed_scalar == x && !aliases_everything_p (mem)));
+ if ((fixed_scalar == mem && !aliases_everything_p (x))
+ || (fixed_scalar == x && !aliases_everything_p (mem)))
+ return 0;
+
+ return rtx_refs_may_alias_p (x, mem, false);
}
/* Anti dependence: X is written after read in MEM takes place. */
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index c8d19fb1..89a7363 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -784,6 +784,133 @@ stack_var_size_cmp (const void *a, const void *b)
return 0;
}
+
+/* If the points-to solution *PI points to variables that are in a partition
+ together with other variables add all partition members to the pointed-to
+ variables bitmap. */
+
+static void
+add_partitioned_vars_to_ptset (struct pt_solution *pt,
+ struct pointer_map_t *decls_to_partitions,
+ struct pointer_set_t *visited, bitmap temp)
+{
+ bitmap_iterator bi;
+ unsigned i;
+ bitmap *part;
+
+ if (pt->anything
+ || pt->vars == NULL
+ /* The pointed-to vars bitmap is shared, it is enough to
+ visit it once. */
+ || pointer_set_insert(visited, pt->vars))
+ return;
+
+ bitmap_clear (temp);
+
+ /* By using a temporary bitmap to store all members of the partitions
+ we have to add we make sure to visit each of the partitions only
+ once. */
+ EXECUTE_IF_SET_IN_BITMAP (pt->vars, 0, i, bi)
+ if ((!temp
+ || !bitmap_bit_p (temp, i))
+ && (part = (bitmap *) pointer_map_contains (decls_to_partitions,
+ (void *)(size_t) i)))
+ bitmap_ior_into (temp, *part);
+ if (!bitmap_empty_p (temp))
+ bitmap_ior_into (pt->vars, temp);
+}
+
+/* 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)
+{
+ struct pointer_map_t *decls_to_partitions = NULL;
+ size_t i, j;
+ tree var = NULL_TREE;
+
+ for (i = 0; i < stack_vars_num; i++)
+ {
+ bitmap part = NULL;
+ tree name;
+ struct ptr_info_def *pi;
+
+ /* Not interested in partitions with single variable. */
+ if (stack_vars[i].representative != i
+ || stack_vars[i].next == EOC)
+ continue;
+
+ if (!decls_to_partitions)
+ {
+ decls_to_partitions = pointer_map_create ();
+ cfun->gimple_df->decls_to_pointers = pointer_map_create ();
+ }
+
+ /* Create an SSA_NAME that points to the partition for use
+ as base during alias-oracle queries on RTL for bases that
+ have been partitioned. */
+ if (var == NULL_TREE)
+ var = create_tmp_var (ptr_type_node, NULL);
+ name = make_ssa_name (var, NULL);
+
+ /* Create bitmaps representing partitions. They will be used for
+ points-to sets later, so use GGC alloc. */
+ part = BITMAP_GGC_ALLOC ();
+ for (j = i; j != EOC; j = stack_vars[j].next)
+ {
+ tree decl = stack_vars[j].decl;
+ unsigned int uid = DECL_UID (decl);
+ /* We should never end up partitioning SSA names (though they
+ may end up on the stack). Neither should we allocate stack
+ space to something that is unused and thus unreferenced. */
+ gcc_assert (DECL_P (decl)
+ && referenced_var_lookup (uid));
+ bitmap_set_bit (part, uid);
+ *((bitmap *) pointer_map_insert (decls_to_partitions,
+ (void *)(size_t) uid)) = part;
+ *((tree *) pointer_map_insert (cfun->gimple_df->decls_to_pointers,
+ decl)) = name;
+ }
+
+ /* Make the SSA name point to all partition members. */
+ pi = get_ptr_info (name);
+ pt_solution_set (&pi->pt, part);
+ }
+
+ /* Make all points-to sets that contain one member of a partition
+ contain all members of the partition. */
+ if (decls_to_partitions)
+ {
+ unsigned i;
+ struct pointer_set_t *visited = pointer_set_create ();
+ bitmap temp = BITMAP_ALLOC (NULL);
+
+ for (i = 1; i < num_ssa_names; i++)
+ {
+ tree name = ssa_name (i);
+ struct ptr_info_def *pi;
+
+ if (name
+ && POINTER_TYPE_P (TREE_TYPE (name))
+ && ((pi = SSA_NAME_PTR_INFO (name)) != NULL))
+ add_partitioned_vars_to_ptset (&pi->pt, decls_to_partitions,
+ visited, temp);
+ }
+
+ add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped,
+ decls_to_partitions, visited, temp);
+ add_partitioned_vars_to_ptset (&cfun->gimple_df->callused,
+ decls_to_partitions, visited, temp);
+
+ pointer_set_destroy (visited);
+ pointer_map_destroy (decls_to_partitions);
+ BITMAP_FREE (temp);
+ }
+}
+
/* 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.
@@ -903,6 +1030,8 @@ partition_stack_vars (void)
break;
}
}
+
+ update_alias_info_with_stack_vars ();
}
/* A debugging aid for expand_used_vars. Dump the generated partitions. */
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index d20f2b5..5b42f4a 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -197,7 +197,6 @@ static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int,
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);
-static tree component_ref_for_mem_expr (tree);
static rtx gen_const_vector (enum machine_mode, int);
static void copy_rtx_if_shared_1 (rtx *orig);
@@ -1429,40 +1428,6 @@ operand_subword_force (rtx op, unsigned int offset, enum machine_mode mode)
return result;
}
-/* Within a MEM_EXPR, we care about either (1) a component ref of a decl,
- or (2) a component ref of something variable. Represent the later with
- a NULL expression. */
-
-static tree
-component_ref_for_mem_expr (tree ref)
-{
- tree inner = TREE_OPERAND (ref, 0);
-
- if (TREE_CODE (inner) == COMPONENT_REF)
- inner = component_ref_for_mem_expr (inner);
- else
- {
- /* Now remove any conversions: they don't change what the underlying
- object is. Likewise for SAVE_EXPR. */
- while (CONVERT_EXPR_P (inner)
- || TREE_CODE (inner) == VIEW_CONVERT_EXPR
- || TREE_CODE (inner) == SAVE_EXPR)
- inner = TREE_OPERAND (inner, 0);
-
- if (! DECL_P (inner))
- inner = NULL_TREE;
- }
-
- if (inner == TREE_OPERAND (ref, 0)
- /* Don't leak SSA-names in the third operand. */
- && (!TREE_OPERAND (ref, 2)
- || TREE_CODE (TREE_OPERAND (ref, 2)) != SSA_NAME))
- return ref;
- else
- return build3 (COMPONENT_REF, TREE_TYPE (ref), inner,
- TREE_OPERAND (ref, 1), NULL_TREE);
-}
-
/* Returns 1 if both MEM_EXPR can be considered equal
and 0 otherwise. */
@@ -1478,23 +1443,7 @@ mem_expr_equal_p (const_tree expr1, const_tree expr2)
if (TREE_CODE (expr1) != TREE_CODE (expr2))
return 0;
- if (TREE_CODE (expr1) == COMPONENT_REF)
- return
- mem_expr_equal_p (TREE_OPERAND (expr1, 0),
- TREE_OPERAND (expr2, 0))
- && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */
- TREE_OPERAND (expr2, 1));
-
- if (INDIRECT_REF_P (expr1))
- return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
- TREE_OPERAND (expr2, 0));
-
- /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already
- have been resolved here. */
- gcc_assert (DECL_P (expr1));
-
- /* Decls with different pointers can't be equal. */
- return 0;
+ return operand_equal_p (expr1, expr2, 0);
}
/* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN
@@ -1732,7 +1681,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
else if (TREE_CODE (t) == COMPONENT_REF
&& ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
{
- expr = component_ref_for_mem_expr (t);
+ expr = t;
offset = const0_rtx;
apply_bitpos = bitpos;
/* ??? Any reason the field size would be different than
@@ -1789,7 +1738,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
}
else if (TREE_CODE (t2) == COMPONENT_REF)
{
- expr = component_ref_for_mem_expr (t2);
+ expr = t2;
+ offset = NULL;
if (host_integerp (off_tree, 1))
{
offset = GEN_INT (tree_low_cst (off_tree, 1));
diff --git a/gcc/final.c b/gcc/final.c
index 2508443..e84c2ca 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "cfglayout.h"
#include "tree-pass.h"
+#include "tree-flow.h"
#include "timevar.h"
#include "cgraph.h"
#include "coverage.h"
@@ -4422,6 +4423,8 @@ rest_of_clean_state (void)
free_bb_for_insn ();
+ delete_tree_ssa ();
+
if (targetm.binds_local_p (current_function_decl))
{
unsigned int pref = crtl->preferred_stack_boundary;
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index 7f8a6c9..fa02699 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "hard-reg-set.h"
#include "basic-block.h"
+#include "diagnostic.h"
#endif
static FILE *outfile;
@@ -72,60 +73,11 @@ int flag_simple = 0;
int dump_for_graph;
#ifndef GENERATOR_FILE
-static void
-print_decl_name (FILE *outfile, const_tree node)
-{
- if (DECL_NAME (node))
- fputs (IDENTIFIER_POINTER (DECL_NAME (node)), outfile);
- else
- {
- if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
- fprintf (outfile, "L.%d", (int) LABEL_DECL_UID (node));
- else
- {
- char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
- fprintf (outfile, "%c.%u", c, DECL_UID (node));
- }
- }
-}
-
void
print_mem_expr (FILE *outfile, const_tree expr)
{
- if (TREE_CODE (expr) == COMPONENT_REF)
- {
- if (TREE_OPERAND (expr, 0))
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- else
- fputs (" <variable>", outfile);
- fputc ('.', outfile);
- print_decl_name (outfile, TREE_OPERAND (expr, 1));
- }
- else if (TREE_CODE (expr) == INDIRECT_REF)
- {
- fputs (" (*", outfile);
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- fputs (")", outfile);
- }
- else if (TREE_CODE (expr) == ALIGN_INDIRECT_REF)
- {
- fputs (" (A*", outfile);
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- fputs (")", outfile);
- }
- else if (TREE_CODE (expr) == MISALIGNED_INDIRECT_REF)
- {
- fputs (" (M*", outfile);
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- fputs (")", outfile);
- }
- else if (TREE_CODE (expr) == RESULT_DECL)
- fputs (" <result>", outfile);
- else
- {
- fputc (' ', outfile);
- print_decl_name (outfile, expr);
- }
+ fputc (' ', outfile);
+ print_generic_expr (outfile, CONST_CAST_TREE (expr), 0);
}
#endif
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 64c5e26..1067a43 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -729,7 +729,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
else if (TREE_CODE (exp) == BIT_FIELD_REF)
size_tree = TREE_OPERAND (exp, 1);
- else
+ else if (!VOID_TYPE_P (TREE_TYPE (exp)))
{
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
if (mode == BLKmode)
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index c773310..cec5ed7 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -63,6 +63,10 @@ struct GTY(()) gimple_df {
/* The PTA solution for the CALLUSED artificial variable. */
struct pt_solution callused;
+ /* A map of decls to artificial ssa-names that point to the partition
+ of the decl. */
+ struct pointer_map_t * GTY((skip(""))) decls_to_pointers;
+
/* Free list of SSA_NAMEs. */
tree free_ssanames;
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 765e021..7a9d2bd 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -226,10 +226,6 @@ execute_free_datastructures (void)
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 ();
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 4d72187..92297fc 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -724,7 +724,7 @@ indirect_refs_may_alias_p (tree ref1, tree ptr1,
/* Return true, if the two memory references REF1 and REF2 may alias. */
-static bool
+bool
refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
{
tree base1, base2;
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 2be903f..3a08750 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -92,6 +92,7 @@ extern tree ao_ref_base (ao_ref *);
extern alias_set_type ao_ref_alias_set (ao_ref *);
extern bool ptr_deref_may_alias_global_p (tree);
extern bool refs_may_alias_p (tree, tree);
+extern bool refs_may_alias_p_1 (ao_ref *, ao_ref *, bool);
extern bool refs_anti_dependent_p (tree, tree);
extern bool refs_output_dependent_p (tree, tree);
extern bool ref_maybe_used_by_stmt_p (gimple, tree);
@@ -121,6 +122,7 @@ extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *);
extern bool pt_solutions_same_restrict_base (struct pt_solution *,
struct pt_solution *);
extern void pt_solution_reset (struct pt_solution *);
+extern void pt_solution_set (struct pt_solution *, bitmap);
extern void dump_pta_stats (FILE *);
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 303bd1f..7e7e8e4 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4886,6 +4886,28 @@ pt_solution_reset (struct pt_solution *pt)
pt->anything = true;
}
+/* Set the points-to solution *PT to point only to the variables
+ in VARS. */
+
+void
+pt_solution_set (struct pt_solution *pt, bitmap vars)
+{
+ bitmap_iterator bi;
+ unsigned i;
+
+ memset (pt, 0, sizeof (struct pt_solution));
+ pt->vars = vars;
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
+ {
+ tree var = referenced_var_lookup (i);
+ if (is_global_var (var))
+ {
+ pt->vars_contains_global = true;
+ break;
+ }
+ }
+}
+
/* Return true if the points-to solution *PT is empty. */
static bool
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index c8a48a3..7ec04f7 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -802,52 +802,9 @@ init_tree_ssa (struct function *fn)
void
delete_tree_ssa (void)
{
- size_t i;
- basic_block bb;
- gimple_stmt_iterator gsi;
referenced_var_iterator rvi;
tree var;
- /* Release any ssa_names still in use. */
- for (i = 0; i < num_ssa_names; i++)
- {
- tree var = ssa_name (i);
- if (var && TREE_CODE (var) == SSA_NAME)
- {
- 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. */
FOR_EACH_REFERENCED_VAR (var, rvi)
{
@@ -873,6 +830,9 @@ delete_tree_ssa (void)
cfun->gimple_df->default_defs = NULL;
pt_solution_reset (&cfun->gimple_df->escaped);
pt_solution_reset (&cfun->gimple_df->callused);
+ if (cfun->gimple_df->decls_to_pointers != NULL)
+ pointer_map_destroy (cfun->gimple_df->decls_to_pointers);
+ cfun->gimple_df->decls_to_pointers = NULL;
cfun->gimple_df->modified_noreturn_calls = NULL;
cfun->gimple_df = NULL;