This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][alias-improvements] Random bugfixes
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 25 Nov 2008 21:26:37 +0100 (CET)
- Subject: [PATCH][alias-improvements] Random bugfixes
This fixes bugs I ran into while removing all traces of the old alias
code. Split out because the can be separately merged. The "fix" for
PR37869 is more a workaround, but that bug causes miscompiles on
the branch otherwise.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Richard.
2008-11-25 Richard Guenther <rguenther@suse.de>
* tree-data-ref.c (dr_may_alias_p): Use the alias-oracle.
* tree-tailcall.c (tree_optimize_tail_calls_1): Also split the
edge from the entry block if we have degenerate PHI nodes in
the first basic block.
* gimple.c (gimple_set_bb): Fix off-by-one error.
* tree-cfg.c (move_block_to_fn): Likewise.
PR tree-optimization/37869
* tree-ssa-structalias.c (struct variable_info): Add
is_nonpointer_var flag.
(new_var_info): Clear it.
(perform_var_substitution): Set it.
(find_what_p_points_to): Use it.
Index: alias-improvements/gcc/gimple.c
===================================================================
*** alias-improvements.orig/gcc/gimple.c 2008-11-25 18:31:51.000000000 +0100
--- alias-improvements/gcc/gimple.c 2008-11-25 18:34:31.000000000 +0100
*************** gimple_set_bb (gimple stmt, basic_block
*** 1901,1907 ****
LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++;
if (old_len <= (unsigned) uid)
{
! unsigned new_len = 3 * uid / 2;
VEC_safe_grow_cleared (basic_block, gc, label_to_block_map,
new_len);
--- 1901,1907 ----
LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++;
if (old_len <= (unsigned) uid)
{
! unsigned new_len = 3 * uid / 2 + 1;
VEC_safe_grow_cleared (basic_block, gc, label_to_block_map,
new_len);
Index: alias-improvements/gcc/tree-data-ref.c
===================================================================
*** alias-improvements.orig/gcc/tree-data-ref.c 2008-11-25 18:31:51.000000000 +0100
--- alias-improvements/gcc/tree-data-ref.c 2008-11-25 18:35:50.000000000 +0100
*************** dr_may_alias_p (const struct data_refere
*** 1244,1256 ****
if (disjoint_objects_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b)))
return false;
if (!addr_a || !addr_b)
return true;
! /* If the references are based on different static objects, they cannot alias
! (PTA should be able to disambiguate such accesses, but often it fails to,
! since currently we cannot distinguish between pointer and offset in pointer
! arithmetics). */
if (TREE_CODE (addr_a) == ADDR_EXPR
&& TREE_CODE (addr_b) == ADDR_EXPR)
return TREE_OPERAND (addr_a, 0) == TREE_OPERAND (addr_b, 0);
--- 1244,1259 ----
if (disjoint_objects_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b)))
return false;
+ /* Query the alias oracle. */
+ if (!refs_may_alias_p (DR_REF (a), DR_REF (b)))
+ return false;
+
if (!addr_a || !addr_b)
return true;
! /* If the references are based on different static objects, they cannot
! alias (PTA should be able to disambiguate such accesses, but often
! it fails to). */
if (TREE_CODE (addr_a) == ADDR_EXPR
&& TREE_CODE (addr_b) == ADDR_EXPR)
return TREE_OPERAND (addr_a, 0) == TREE_OPERAND (addr_b, 0);
Index: alias-improvements/gcc/tree-ssa-structalias.c
===================================================================
*** alias-improvements.orig/gcc/tree-ssa-structalias.c 2008-11-25 18:31:51.000000000 +0100
--- alias-improvements/gcc/tree-ssa-structalias.c 2008-11-25 18:34:31.000000000 +0100
*************** struct variable_info
*** 230,235 ****
--- 230,238 ----
variable. This is used for C++ placement new. */
unsigned int no_tbaa_pruning : 1;
+ /* If found to be a non-pointer variable. */
+ unsigned int is_nonpointer_var : 1;
+
/* Variable id this was collapsed to due to type unsafety. Zero if
this variable was not collapsed. This should be unused completely
after build_succ_graph, or something is broken. */
*************** new_var_info (tree t, unsigned int id, c
*** 377,382 ****
--- 380,386 ----
ret->is_special_var = false;
ret->is_unknown_size_var = false;
ret->is_full_var = false;
+ ret->is_nonpointer_var = false;
var = t;
if (TREE_CODE (var) == SSA_NAME)
var = SSA_NAME_VAR (var);
*************** perform_var_substitution (constraint_gra
*** 2175,2180 ****
--- 2179,2185 ----
"%s is a non-pointer variable, eliminating edges.\n",
get_varinfo (node)->name);
stats.nonpointer_vars++;
+ get_varinfo (i)->is_nonpointer_var = true;
clear_edges_for_node (graph, node);
}
}
*************** find_what_p_points_to (tree p)
*** 4752,4757 ****
--- 4757,4767 ----
if (vi->is_artificial_var)
return false;
+ /* ??? Some real variables get eliminated as non-pointers.
+ Workaround this. See PR37869. */
+ if (vi->is_nonpointer_var)
+ return false;
+
/* See if this is a field or a structure. */
if (vi->size != vi->fullsize)
{
Index: alias-improvements/gcc/tree-tailcall.c
===================================================================
*** alias-improvements.orig/gcc/tree-tailcall.c 2008-11-25 18:31:51.000000000 +0100
--- alias-improvements/gcc/tree-tailcall.c 2008-11-25 18:34:31.000000000 +0100
*************** tree_optimize_tail_calls_1 (bool opt_tai
*** 913,920 ****
if (!phis_constructed)
{
! /* Ensure that there is only one predecessor of the block. */
! if (!single_pred_p (first))
first = split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
/* Copy the args if needed. */
--- 913,922 ----
if (!phis_constructed)
{
! /* Ensure that there is only one predecessor of the block
! or if there are existing degenerate PHI nodes. */
! if (!single_pred_p (first)
! || !gimple_seq_empty_p (phi_nodes (first)))
first = split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
/* Copy the args if needed. */
Index: alias-improvements/gcc/tree-cfg.c
===================================================================
*** alias-improvements.orig/gcc/tree-cfg.c 2008-11-25 18:31:11.000000000 +0100
--- alias-improvements/gcc/tree-cfg.c 2008-11-25 18:54:28.000000000 +0100
*************** move_block_to_fn (struct function *dest_
*** 5706,5712 ****
old_len = VEC_length (basic_block, cfg->x_label_to_block_map);
if (old_len <= (unsigned) uid)
{
! new_len = 3 * uid / 2;
VEC_safe_grow_cleared (basic_block, gc,
cfg->x_label_to_block_map, new_len);
}
--- 5713,5719 ----
old_len = VEC_length (basic_block, cfg->x_label_to_block_map);
if (old_len <= (unsigned) uid)
{
! new_len = 3 * uid / 2 + 1;
VEC_safe_grow_cleared (basic_block, gc,
cfg->x_label_to_block_map, new_len);
}