Commit b45d2719 by Richard Guenther Committed by Richard Biener

tree-ssa-alias.c (ao_ref_init): New function.

2009-05-28  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-alias.c (ao_ref_init): New function.
	(ao_ref_base): Likewise.
	(ao_ref_base_alias_set): Likewise.
	(ao_ref_alias_set): Likewise.
	(refs_may_alias_p_1): Change signature.
	(refs_may_alias_p): Adjust.
	(refs_anti_dependent_p): Likewise.
	(refs_output_dependent_p): Likewise.
	(call_may_clobber_ref_p_1): Change signature.
	(call_may_clobber_ref_p): Adjust.
	(stmt_may_clobber_ref_p_1): New function split out from ...
	(stmt_may_clobber_ref_p): ... here.
	(maybe_skip_until): Adjust signature.
	(get_continuation_for_phi): Likewise.
	(walk_non_aliased_vuses): Likewise.
	* tree-ssa-alias.h (struct ao_ref_s): New structure type.
	(ao_ref_init): Declare.
	(ao_ref_base): Likewise.
	(ao_ref_alias_set): Likewise.
	(stmt_may_clobber_ref_p_1): Likewise.
	(walk_non_aliased_vuses): Adjust.
	* tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): New function.
	(get_ref_from_reference_ops): remove.
	(vn_reference_lookup_2): Adjust signature.
	(vn_reference_lookup_3): Do not re-build trees.  Handle unions.
	(vn_reference_lookup_pieces): Adjust signature, do not re-build
	trees.
	(vn_reference_lookup): Adjust.
	(vn_reference_insert): Likewise.
	(vn_reference_insert_pieces): Adjust signature.
	(visit_reference_op_call): Adjust.
	* tree-ssa-pre.c (get_expr_type): Simplify.
	(phi_translate_1): Adjust.
	(compute_avail): Likewise.
	(translate_vuse_through_block): Do not re-build trees.
	(value_dies_in_block_x): Likewise.
	* tree-ssa-sccvn.h (struct vn_reference_s): Add type and alias-set
	fields.
	(vn_reference_lookup_pieces): Adjust declaration.
	(vn_reference_insert_pieces): Likewise.

	* gcc.dg/tree-ssa/ssa-fre-26.c: New testcase.
	* gcc.c-torture/execute/20090527-1.c: Likewise.

From-SVN: r147953
parent 554223b6
2009-05-28 Richard Guenther <rguenther@suse.de>
* tree-ssa-alias.c (ao_ref_init): New function.
(ao_ref_base): Likewise.
(ao_ref_base_alias_set): Likewise.
(ao_ref_alias_set): Likewise.
(refs_may_alias_p_1): Change signature.
(refs_may_alias_p): Adjust.
(refs_anti_dependent_p): Likewise.
(refs_output_dependent_p): Likewise.
(call_may_clobber_ref_p_1): Change signature.
(call_may_clobber_ref_p): Adjust.
(stmt_may_clobber_ref_p_1): New function split out from ...
(stmt_may_clobber_ref_p): ... here.
(maybe_skip_until): Adjust signature.
(get_continuation_for_phi): Likewise.
(walk_non_aliased_vuses): Likewise.
* tree-ssa-alias.h (struct ao_ref_s): New structure type.
(ao_ref_init): Declare.
(ao_ref_base): Likewise.
(ao_ref_alias_set): Likewise.
(stmt_may_clobber_ref_p_1): Likewise.
(walk_non_aliased_vuses): Adjust.
* tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): New function.
(get_ref_from_reference_ops): remove.
(vn_reference_lookup_2): Adjust signature.
(vn_reference_lookup_3): Do not re-build trees. Handle unions.
(vn_reference_lookup_pieces): Adjust signature, do not re-build
trees.
(vn_reference_lookup): Adjust.
(vn_reference_insert): Likewise.
(vn_reference_insert_pieces): Adjust signature.
(visit_reference_op_call): Adjust.
* tree-ssa-pre.c (get_expr_type): Simplify.
(phi_translate_1): Adjust.
(compute_avail): Likewise.
(translate_vuse_through_block): Do not re-build trees.
(value_dies_in_block_x): Likewise.
* tree-ssa-sccvn.h (struct vn_reference_s): Add type and alias-set
fields.
(vn_reference_lookup_pieces): Adjust declaration.
(vn_reference_insert_pieces): Likewise.
2009-05-28 Benjamin Kosnik <bkoz@redhat.com> 2009-05-28 Benjamin Kosnik <bkoz@redhat.com>
* tree-ssa-copy.c (replace_exp_1): Move op for warning-free use * tree-ssa-copy.c (replace_exp_1): Move op for warning-free use
......
2009-05-28 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/ssa-fre-26.c: New testcase.
* gcc.c-torture/execute/20090527-1.c: Likewise.
2009-05-28 Dodji Seketeli <dodji@redhat.com> 2009-05-28 Dodji Seketeli <dodji@redhat.com>
PR c++/39754 PR c++/39754
......
typedef enum { POSITION_ASIS, POSITION_UNSPECIFIED } unit_position;
typedef enum { STATUS_UNKNOWN, STATUS_UNSPECIFIED } unit_status;
typedef struct
{
unit_position position;
unit_status status;
} unit_flags;
extern void abort (void);
void
new_unit (unit_flags * flags)
{
if (flags->status == STATUS_UNSPECIFIED)
flags->status = STATUS_UNKNOWN;
if (flags->position == POSITION_UNSPECIFIED)
flags->position = POSITION_ASIS;
switch (flags->status)
{
case STATUS_UNKNOWN:
break;
default:
abort ();
}
}
int main()
{
unit_flags f;
f.status = STATUS_UNSPECIFIED;
new_unit (&f);
return 0;
}
/* { dg-do compile } */
/* { dg-options "-O -fno-tree-sra -fdump-tree-fre-details" } */
union U {
float f;
int i;
};
int foo (union U *p)
{
union U u;
p->f = 0.0;
u = *p;
return u.i;
}
/* { dg-final { scan-tree-dump "Replaced u.i with 0 in" "fre" } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
...@@ -74,7 +74,39 @@ struct GTY(()) pt_solution ...@@ -74,7 +74,39 @@ struct GTY(()) pt_solution
}; };
/* Simplified and cached information about a memory reference tree.
Used by the alias-oracle internally and externally in alternate
interfaces. */
typedef struct ao_ref_s
{
/* The original full memory reference tree or NULL_TREE if that is
not available. */
tree ref;
/* The following fields are the decomposed reference as returned
by get_ref_base_and_extent. */
/* The base object of the memory reference or NULL_TREE if all of
the following fields are not yet computed. */
tree base;
/* The offset relative to the base. */
HOST_WIDE_INT offset;
/* The size of the access. */
HOST_WIDE_INT size;
/* The maximum possible extent of the access or -1 if unconstrained. */
HOST_WIDE_INT max_size;
/* The alias set of the access or -1 if not yet computed. */
alias_set_type ref_alias_set;
/* The alias set of the base object or -1 if not yet computed. */
alias_set_type base_alias_set;
} ao_ref;
/* In tree-ssa-alias.c */ /* In tree-ssa-alias.c */
extern void ao_ref_init (ao_ref *, tree);
extern tree ao_ref_base (ao_ref *);
extern alias_set_type ao_ref_alias_set (ao_ref *);
extern enum escape_type is_escape_site (gimple); extern enum escape_type is_escape_site (gimple);
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);
...@@ -82,9 +114,10 @@ extern bool refs_anti_dependent_p (tree, tree); ...@@ -82,9 +114,10 @@ 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);
extern bool stmt_may_clobber_ref_p (gimple, tree); extern bool stmt_may_clobber_ref_p (gimple, tree);
extern void *walk_non_aliased_vuses (tree, tree, extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *);
void *(*)(tree, tree, void *), extern void *walk_non_aliased_vuses (ao_ref *, tree,
void *(*)(tree *, tree, void *), void *); void *(*)(ao_ref *, tree, void *),
void *(*)(ao_ref *, tree, void *), void *);
extern unsigned int walk_aliased_vdefs (tree, tree, extern unsigned int walk_aliased_vdefs (tree, tree,
bool (*)(tree, tree, void *), void *, bool (*)(tree, tree, void *), void *,
bitmap *); bitmap *);
......
...@@ -1252,12 +1252,12 @@ do_unary: ...@@ -1252,12 +1252,12 @@ do_unary:
static tree static tree
translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands, translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands,
tree vuse, alias_set_type set, tree type, tree vuse,
basic_block phiblock, basic_block phiblock,
basic_block block) basic_block block)
{ {
gimple phi = SSA_NAME_DEF_STMT (vuse); gimple phi = SSA_NAME_DEF_STMT (vuse);
tree ref; ao_ref ref;
if (gimple_bb (phi) != phiblock) if (gimple_bb (phi) != phiblock)
return vuse; return vuse;
...@@ -1268,13 +1268,13 @@ translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands, ...@@ -1268,13 +1268,13 @@ translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands,
return PHI_ARG_DEF (phi, e->dest_idx); return PHI_ARG_DEF (phi, e->dest_idx);
} }
if (!(ref = get_ref_from_reference_ops (operands))) if (!ao_ref_init_from_vn_reference (&ref, set, type, operands))
return NULL_TREE; return NULL_TREE;
/* Use the alias-oracle to find either the PHI node in this block, /* Use the alias-oracle to find either the PHI node in this block,
the first VUSE used in this block that is equivalent to vuse or the first VUSE used in this block that is equivalent to vuse or
the first VUSE which definition in this block kills the value. */ the first VUSE which definition in this block kills the value. */
while (!stmt_may_clobber_ref_p (phi, ref)) while (!stmt_may_clobber_ref_p_1 (phi, &ref))
{ {
vuse = gimple_vuse (phi); vuse = gimple_vuse (phi);
phi = SSA_NAME_DEF_STMT (vuse); phi = SSA_NAME_DEF_STMT (vuse);
...@@ -1317,23 +1317,7 @@ get_expr_type (const pre_expr e) ...@@ -1317,23 +1317,7 @@ get_expr_type (const pre_expr e)
case CONSTANT: case CONSTANT:
return TREE_TYPE (PRE_EXPR_CONSTANT (e)); return TREE_TYPE (PRE_EXPR_CONSTANT (e));
case REFERENCE: case REFERENCE:
{ return PRE_EXPR_REFERENCE (e)->type;
vn_reference_op_t vro;
gcc_assert (PRE_EXPR_REFERENCE (e)->operands);
vro = VEC_index (vn_reference_op_s,
PRE_EXPR_REFERENCE (e)->operands,
0);
/* We don't store type along with COMPONENT_REF because it is
always the same as FIELD_DECL's type. */
if (!vro->type)
{
gcc_assert (vro->opcode == COMPONENT_REF);
return TREE_TYPE (vro->op0);
}
return vro->type;
}
case NARY: case NARY:
return PRE_EXPR_NARY (e)->type; return PRE_EXPR_NARY (e)->type;
} }
...@@ -1661,6 +1645,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1661,6 +1645,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
if (vuse) if (vuse)
{ {
newvuse = translate_vuse_through_block (newoperands, newvuse = translate_vuse_through_block (newoperands,
ref->set, ref->type,
vuse, phiblock, pred); vuse, phiblock, pred);
if (newvuse == NULL_TREE) if (newvuse == NULL_TREE)
{ {
...@@ -1675,7 +1660,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1675,7 +1660,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
unsigned int new_val_id; unsigned int new_val_id;
pre_expr constant; pre_expr constant;
tree result = vn_reference_lookup_pieces (newvuse, tree result = vn_reference_lookup_pieces (newvuse, ref->set,
ref->type,
newoperands, newoperands,
&newref, true); &newref, true);
if (newref) if (newref)
...@@ -1706,7 +1692,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1706,7 +1692,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
new_val_id = get_next_value_id (); new_val_id = get_next_value_id ();
VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions, VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
get_max_value_id() + 1); get_max_value_id() + 1);
newref = vn_reference_insert_pieces (newvuse, newref = vn_reference_insert_pieces (newvuse, ref->set,
ref->type,
newoperands, newoperands,
result, new_val_id); result, new_val_id);
newoperands = NULL; newoperands = NULL;
...@@ -1884,10 +1871,10 @@ value_dies_in_block_x (pre_expr expr, basic_block block) ...@@ -1884,10 +1871,10 @@ value_dies_in_block_x (pre_expr expr, basic_block block)
tree vuse = PRE_EXPR_REFERENCE (expr)->vuse; tree vuse = PRE_EXPR_REFERENCE (expr)->vuse;
vn_reference_t refx = PRE_EXPR_REFERENCE (expr); vn_reference_t refx = PRE_EXPR_REFERENCE (expr);
gimple def; gimple def;
tree ref = NULL_TREE;
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
unsigned id = get_expression_id (expr); unsigned id = get_expression_id (expr);
bool res = false; bool res = false;
ao_ref ref;
if (!vuse) if (!vuse)
return false; return false;
...@@ -1902,6 +1889,7 @@ value_dies_in_block_x (pre_expr expr, basic_block block) ...@@ -1902,6 +1889,7 @@ value_dies_in_block_x (pre_expr expr, basic_block block)
top of the basic block, a statement uses VUSE there can be no kill top of the basic block, a statement uses VUSE there can be no kill
inbetween that use and the original statement that loaded {e, VUSE}, inbetween that use and the original statement that loaded {e, VUSE},
so we can stop walking. */ so we can stop walking. */
ref.base = NULL_TREE;
for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
tree def_vuse, def_vdef; tree def_vuse, def_vdef;
...@@ -1924,16 +1912,15 @@ value_dies_in_block_x (pre_expr expr, basic_block block) ...@@ -1924,16 +1912,15 @@ value_dies_in_block_x (pre_expr expr, basic_block block)
} }
/* Init ref only if we really need it. */ /* Init ref only if we really need it. */
if (ref == NULL_TREE) if (ref.base == NULL_TREE
&& !ao_ref_init_from_vn_reference (&ref, refx->set, refx->type,
refx->operands))
{ {
if (!(ref = get_ref_from_reference_ops (refx->operands))) res = true;
{ break;
res = true;
break;
}
} }
/* If the statement may clobber expr, it dies. */ /* If the statement may clobber expr, it dies. */
if (stmt_may_clobber_ref_p (def, ref)) if (stmt_may_clobber_ref_p_1 (def, &ref))
{ {
res = true; res = true;
break; break;
...@@ -3793,7 +3780,8 @@ compute_avail (void) ...@@ -3793,7 +3780,8 @@ compute_avail (void)
continue; continue;
copy_reference_ops_from_call (stmt, &ops); copy_reference_ops_from_call (stmt, &ops);
vn_reference_lookup_pieces (gimple_vuse (stmt), vn_reference_lookup_pieces (gimple_vuse (stmt), 0,
gimple_expr_type (stmt),
ops, &ref, false); ops, &ref, false);
VEC_free (vn_reference_op_s, heap, ops); VEC_free (vn_reference_op_s, heap, ops);
if (!ref) if (!ref)
......
...@@ -92,6 +92,8 @@ typedef struct vn_reference_s ...@@ -92,6 +92,8 @@ typedef struct vn_reference_s
unsigned int value_id; unsigned int value_id;
hashval_t hashcode; hashval_t hashcode;
tree vuse; tree vuse;
alias_set_type set;
tree type;
VEC (vn_reference_op_s, heap) *operands; VEC (vn_reference_op_s, heap) *operands;
tree result; tree result;
} *vn_reference_t; } *vn_reference_t;
...@@ -177,13 +179,14 @@ void vn_reference_fold_indirect (VEC (vn_reference_op_s, heap) **, ...@@ -177,13 +179,14 @@ void vn_reference_fold_indirect (VEC (vn_reference_op_s, heap) **,
unsigned int *); unsigned int *);
void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **); void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **);
void copy_reference_ops_from_call (gimple, VEC(vn_reference_op_s, heap) **); void copy_reference_ops_from_call (gimple, VEC(vn_reference_op_s, heap) **);
tree get_ref_from_reference_ops (VEC(vn_reference_op_s, heap) *ops); bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree,
tree vn_reference_lookup_pieces (tree, VEC (vn_reference_op_s, heap) *);
tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *, VEC (vn_reference_op_s, heap) *,
vn_reference_t *, bool); vn_reference_t *, bool);
tree vn_reference_lookup (tree, tree, bool, vn_reference_t *); tree vn_reference_lookup (tree, tree, bool, vn_reference_t *);
vn_reference_t vn_reference_insert (tree, tree, tree); vn_reference_t vn_reference_insert (tree, tree, tree);
vn_reference_t vn_reference_insert_pieces (tree, vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *, VEC (vn_reference_op_s, heap) *,
tree, unsigned int); tree, unsigned int);
......
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