Commit 55b34b5f by Richard Guenther Committed by Richard Biener

tree-ssa-alias.h (refs_may_alias_p_1): Declare.

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.

Co-Authored-By: Andrey Belevantsev <abel@ispras.ru>

From-SVN: r149624
parent 1700c2e7
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> 2009-07-13 DJ Delorie <dj@redhat.com>
* config/mep/mep.h (CC1_SPEC): Tweak parameters to trigger * config/mep/mep.h (CC1_SPEC): Tweak parameters to trigger
......
...@@ -2565,7 +2565,7 @@ rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ ...@@ -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) \ 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) \ $(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) \ 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) \ $(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) \ $(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) \ ...@@ -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) \ $(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) \ $(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 \ $(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) \ real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.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) \ 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) \ ...@@ -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 \ $(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) \ $(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) \ 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 \ 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) \ $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \
$(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H) $(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H)
......
...@@ -46,6 +46,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -46,6 +46,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h" #include "tree-pass.h"
#include "ipa-type-escape.h" #include "ipa-type-escape.h"
#include "df.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: /* The aliasing API provided here solves related but different problems:
...@@ -249,6 +252,98 @@ DEF_VEC_ALLOC_P(alias_set_entry,gc); ...@@ -249,6 +252,98 @@ DEF_VEC_ALLOC_P(alias_set_entry,gc);
/* The splay-tree used to store the various alias set entries. */ /* The splay-tree used to store the various alias set entries. */
static GTY (()) VEC(alias_set_entry,gc) *alias_sets; 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 /* Returns a pointer to the alias set entry for ALIAS_SET, if there is
such an entry, or NULL otherwise. */ such an entry, or NULL otherwise. */
...@@ -2191,8 +2286,10 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, ...@@ -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) if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
return 1; return 1;
return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
varies); return 0;
return rtx_refs_may_alias_p (x, mem, true);
} }
/* Canonical true dependence: X is read after store in MEM takes place. /* 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, ...@@ -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) if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
return 1; return 1;
return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
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 /* 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) ...@@ -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, = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
rtx_addr_varies_p); rtx_addr_varies_p);
return (!(fixed_scalar == mem && !aliases_everything_p (x)) if ((fixed_scalar == mem && !aliases_everything_p (x))
&& !(fixed_scalar == x && !aliases_everything_p (mem))); || (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. */ /* Anti dependence: X is written after read in MEM takes place. */
......
...@@ -784,6 +784,133 @@ stack_var_size_cmp (const void *a, const void *b) ...@@ -784,6 +784,133 @@ stack_var_size_cmp (const void *a, const void *b)
return 0; 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 /* 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. partitioning algorithm. Partitions A and B are known to be non-conflicting.
Merge them into a single partition A. Merge them into a single partition A.
...@@ -903,6 +1030,8 @@ partition_stack_vars (void) ...@@ -903,6 +1030,8 @@ partition_stack_vars (void)
break; break;
} }
} }
update_alias_info_with_stack_vars ();
} }
/* A debugging aid for expand_used_vars. Dump the generated partitions. */ /* A debugging aid for expand_used_vars. Dump the generated partitions. */
......
...@@ -197,7 +197,6 @@ static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int, ...@@ -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 hashval_t reg_attrs_htab_hash (const void *);
static int reg_attrs_htab_eq (const void *, const void *); static int reg_attrs_htab_eq (const void *, const void *);
static reg_attrs *get_reg_attrs (tree, int); 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 rtx gen_const_vector (enum machine_mode, int);
static void copy_rtx_if_shared_1 (rtx *orig); 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) ...@@ -1429,40 +1428,6 @@ operand_subword_force (rtx op, unsigned int offset, enum machine_mode mode)
return result; 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 /* Returns 1 if both MEM_EXPR can be considered equal
and 0 otherwise. */ and 0 otherwise. */
...@@ -1478,23 +1443,7 @@ mem_expr_equal_p (const_tree expr1, const_tree expr2) ...@@ -1478,23 +1443,7 @@ mem_expr_equal_p (const_tree expr1, const_tree expr2)
if (TREE_CODE (expr1) != TREE_CODE (expr2)) if (TREE_CODE (expr1) != TREE_CODE (expr2))
return 0; return 0;
if (TREE_CODE (expr1) == COMPONENT_REF) return operand_equal_p (expr1, expr2, 0);
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 OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN /* 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, ...@@ -1732,7 +1681,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
else if (TREE_CODE (t) == COMPONENT_REF else if (TREE_CODE (t) == COMPONENT_REF
&& ! DECL_BIT_FIELD (TREE_OPERAND (t, 1))) && ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
{ {
expr = component_ref_for_mem_expr (t); expr = t;
offset = const0_rtx; offset = const0_rtx;
apply_bitpos = bitpos; apply_bitpos = bitpos;
/* ??? Any reason the field size would be different than /* ??? Any reason the field size would be different than
...@@ -1789,7 +1738,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, ...@@ -1789,7 +1738,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
} }
else if (TREE_CODE (t2) == COMPONENT_REF) else if (TREE_CODE (t2) == COMPONENT_REF)
{ {
expr = component_ref_for_mem_expr (t2); expr = t2;
offset = NULL;
if (host_integerp (off_tree, 1)) if (host_integerp (off_tree, 1))
{ {
offset = GEN_INT (tree_low_cst (off_tree, 1)); offset = GEN_INT (tree_low_cst (off_tree, 1));
......
...@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h" #include "expr.h"
#include "cfglayout.h" #include "cfglayout.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "tree-flow.h"
#include "timevar.h" #include "timevar.h"
#include "cgraph.h" #include "cgraph.h"
#include "coverage.h" #include "coverage.h"
...@@ -4422,6 +4423,8 @@ rest_of_clean_state (void) ...@@ -4422,6 +4423,8 @@ rest_of_clean_state (void)
free_bb_for_insn (); free_bb_for_insn ();
delete_tree_ssa ();
if (targetm.binds_local_p (current_function_decl)) if (targetm.binds_local_p (current_function_decl))
{ {
unsigned int pref = crtl->preferred_stack_boundary; unsigned int pref = crtl->preferred_stack_boundary;
......
...@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h" #include "flags.h"
#include "hard-reg-set.h" #include "hard-reg-set.h"
#include "basic-block.h" #include "basic-block.h"
#include "diagnostic.h"
#endif #endif
static FILE *outfile; static FILE *outfile;
...@@ -72,60 +73,11 @@ int flag_simple = 0; ...@@ -72,60 +73,11 @@ int flag_simple = 0;
int dump_for_graph; int dump_for_graph;
#ifndef GENERATOR_FILE #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 void
print_mem_expr (FILE *outfile, const_tree expr) print_mem_expr (FILE *outfile, const_tree expr)
{ {
if (TREE_CODE (expr) == COMPONENT_REF) fputc (' ', outfile);
{ print_generic_expr (outfile, CONST_CAST_TREE (expr), 0);
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);
}
} }
#endif #endif
......
...@@ -729,7 +729,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -729,7 +729,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
size_tree = DECL_SIZE (TREE_OPERAND (exp, 1)); size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
else if (TREE_CODE (exp) == BIT_FIELD_REF) else if (TREE_CODE (exp) == BIT_FIELD_REF)
size_tree = TREE_OPERAND (exp, 1); size_tree = TREE_OPERAND (exp, 1);
else else if (!VOID_TYPE_P (TREE_TYPE (exp)))
{ {
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
if (mode == BLKmode) if (mode == BLKmode)
......
...@@ -63,6 +63,10 @@ struct GTY(()) gimple_df { ...@@ -63,6 +63,10 @@ struct GTY(()) gimple_df {
/* The PTA solution for the CALLUSED artificial variable. */ /* The PTA solution for the CALLUSED artificial variable. */
struct pt_solution callused; 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. */ /* Free list of SSA_NAMEs. */
tree free_ssanames; tree free_ssanames;
......
...@@ -226,10 +226,6 @@ execute_free_datastructures (void) ...@@ -226,10 +226,6 @@ execute_free_datastructures (void)
free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_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. */ /* And get rid of annotations we no longer need. */
delete_tree_cfg_annotations (); delete_tree_cfg_annotations ();
......
...@@ -724,7 +724,7 @@ indirect_refs_may_alias_p (tree ref1, tree ptr1, ...@@ -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. */ /* 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) refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
{ {
tree base1, base2; tree base1, base2;
......
...@@ -92,6 +92,7 @@ extern tree ao_ref_base (ao_ref *); ...@@ -92,6 +92,7 @@ extern tree ao_ref_base (ao_ref *);
extern alias_set_type ao_ref_alias_set (ao_ref *); extern alias_set_type ao_ref_alias_set (ao_ref *);
extern bool ptr_deref_may_alias_global_p (tree); extern bool ptr_deref_may_alias_global_p (tree);
extern bool refs_may_alias_p (tree, 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_anti_dependent_p (tree, tree);
extern bool refs_output_dependent_p (tree, tree); extern bool refs_output_dependent_p (tree, tree);
extern bool ref_maybe_used_by_stmt_p (gimple, 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 *); ...@@ -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 *, extern bool pt_solutions_same_restrict_base (struct pt_solution *,
struct pt_solution *); struct pt_solution *);
extern void pt_solution_reset (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 *); extern void dump_pta_stats (FILE *);
......
...@@ -4886,6 +4886,28 @@ pt_solution_reset (struct pt_solution *pt) ...@@ -4886,6 +4886,28 @@ pt_solution_reset (struct pt_solution *pt)
pt->anything = true; 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. */ /* Return true if the points-to solution *PT is empty. */
static bool static bool
......
...@@ -802,52 +802,9 @@ init_tree_ssa (struct function *fn) ...@@ -802,52 +802,9 @@ init_tree_ssa (struct function *fn)
void void
delete_tree_ssa (void) delete_tree_ssa (void)
{ {
size_t i;
basic_block bb;
gimple_stmt_iterator gsi;
referenced_var_iterator rvi; referenced_var_iterator rvi;
tree var; 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. */ /* Remove annotations from every referenced local variable. */
FOR_EACH_REFERENCED_VAR (var, rvi) FOR_EACH_REFERENCED_VAR (var, rvi)
{ {
...@@ -873,6 +830,9 @@ delete_tree_ssa (void) ...@@ -873,6 +830,9 @@ delete_tree_ssa (void)
cfun->gimple_df->default_defs = NULL; cfun->gimple_df->default_defs = NULL;
pt_solution_reset (&cfun->gimple_df->escaped); pt_solution_reset (&cfun->gimple_df->escaped);
pt_solution_reset (&cfun->gimple_df->callused); 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->modified_noreturn_calls = NULL;
cfun->gimple_df = NULL; cfun->gimple_df = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment