re PR tree-optimization/15991 (phi nodes with identical arguments still remain at t50.tailc)

PR tree-optimization/15991
	* tree-cfg.c (tree_block_label): Export.
	* tree-flow-inline.h (bsi_after_labels): New function.
	* tree-flow.h (bsi_after_labels, tree_block_label): Declare.
	* tree-ssa.c (propagate_into_addr): New function.
	(replace_immediate_uses): Handle propagation of pointer constants.
	(raise_value): Do not restrict propagation of pointer constants.
	* tree-ssanames.c (duplicate_ssa_name): New function.
	* tree.h (duplicate_ssa_name): Declare.

From-SVN: r83297
This commit is contained in:
Zdenek Dvorak 2004-06-17 19:47:47 +02:00 committed by Zdenek Dvorak
parent f2b5cf977e
commit d7621d3c74
7 changed files with 149 additions and 23 deletions

View file

@ -1,3 +1,15 @@
2004-06-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
PR tree-optimization/15991
* tree-cfg.c (tree_block_label): Export.
* tree-flow-inline.h (bsi_after_labels): New function.
* tree-flow.h (bsi_after_labels, tree_block_label): Declare.
* tree-ssa.c (propagate_into_addr): New function.
(replace_immediate_uses): Handle propagation of pointer constants.
(raise_value): Do not restrict propagation of pointer constants.
* tree-ssanames.c (duplicate_ssa_name): New function.
* tree.h (duplicate_ssa_name): Declare.
2004-06-17 David Ayers <d.ayers@inode.at>
* c-parse.in: Unify Objective-C token names.

View file

@ -74,7 +74,6 @@ static void free_blocks_annotations (void);
static void clear_blocks_annotations (void);
static void make_blocks (tree);
static void factor_computed_gotos (void);
static tree tree_block_label (basic_block bb);
/* Edges. */
static void make_edges (void);
@ -3973,7 +3972,7 @@ thread_jumps (void)
/* Return a non-special label in the head of basic block BLOCK.
Create one if it doesn't exist. */
static tree
tree
tree_block_label (basic_block bb)
{
block_stmt_iterator i, s = bsi_start (bb);

View file

@ -629,6 +629,53 @@ bsi_start (basic_block bb)
return bsi;
}
/* Return a block statement iterator that points to the last label in
block BB. */
static inline block_stmt_iterator
bsi_after_labels (basic_block bb)
{
block_stmt_iterator bsi;
tree_stmt_iterator next;
bsi.bb = bb;
if (!bb->stmt_list)
{
#ifdef ENABLE_CHECKING
if (bb->index >= 0)
abort ();
#endif
bsi.tsi.ptr = NULL;
bsi.tsi.container = NULL;
return bsi;
}
bsi.tsi = tsi_start (bb->stmt_list);
if (tsi_end_p (bsi.tsi))
return bsi;
/* Ensure that there are some labels. The rationale is that we want
to insert after the bsi that is returned, and these insertions should
be placed at the start of the basic block. This would not work if the
first statement was not label; rather fail here than enable the user
proceed in wrong way. */
if (TREE_CODE (tsi_stmt (bsi.tsi)) != LABEL_EXPR)
abort ();
next = bsi.tsi;
tsi_next (&next);
while (!tsi_end_p (next)
&& TREE_CODE (tsi_stmt (next)) == LABEL_EXPR)
{
bsi.tsi = next;
tsi_next (&next);
}
return bsi;
}
/* Return a block statement iterator that points to the end of basic
block BB. */
static inline block_stmt_iterator

View file

@ -416,6 +416,7 @@ typedef struct {
static inline block_stmt_iterator bsi_start (basic_block);
static inline block_stmt_iterator bsi_last (basic_block);
static inline block_stmt_iterator bsi_after_labels (basic_block);
static inline bool bsi_end_p (block_stmt_iterator);
static inline void bsi_next (block_stmt_iterator *);
static inline void bsi_prev (block_stmt_iterator *);
@ -486,6 +487,7 @@ extern void notice_special_calls (tree);
extern void clear_special_calls (void);
extern void compute_dominance_frontiers (bitmap *);
extern void verify_stmts (void);
extern tree tree_block_label (basic_block bb);
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
/* In tree-pretty-print.c. */

View file

@ -705,6 +705,52 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data)
}
}
/* Replaces VAR with REPL in memory reference expression *X in
statement STMT. */
static void
propagate_into_addr (tree stmt, tree var, tree *x, tree repl)
{
tree new_var, ass_stmt, addr_var;
basic_block bb;
block_stmt_iterator bsi;
/* There is nothing special to handle in the other cases. */
if (TREE_CODE (repl) != ADDR_EXPR)
return;
addr_var = TREE_OPERAND (repl, 0);
while (TREE_CODE (*x) == ARRAY_REF
|| TREE_CODE (*x) == COMPONENT_REF
|| TREE_CODE (*x) == BIT_FIELD_REF)
x = &TREE_OPERAND (*x, 0);
if (TREE_CODE (*x) != INDIRECT_REF
|| TREE_OPERAND (*x, 0) != var)
return;
modify_stmt (stmt);
if (TREE_TYPE (*x) == TREE_TYPE (addr_var))
{
*x = addr_var;
mark_new_vars_to_rename (stmt, vars_to_rename);
return;
}
/* Frontends sometimes produce expressions like *&a instead of a[0].
Create a temporary variable to handle this case. */
ass_stmt = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, repl);
new_var = duplicate_ssa_name (var, ass_stmt);
TREE_OPERAND (*x, 0) = new_var;
TREE_OPERAND (ass_stmt, 0) = new_var;
bb = bb_for_stmt (stmt);
tree_block_label (bb);
bsi = bsi_after_labels (bb);
bsi_insert_after (&bsi, ass_stmt, BSI_NEW_STMT);
mark_new_vars_to_rename (stmt, vars_to_rename);
}
/* Replaces immediate uses of VAR by REPL. */
@ -718,6 +764,7 @@ replace_immediate_uses (tree var, tree repl)
dataflow_t df;
tree stmt;
stmt_ann_t ann;
bool mark_new_vars;
df = get_immediate_uses (SSA_NAME_DEF_STMT (var));
n = num_immediate_uses (df);
@ -742,12 +789,22 @@ replace_immediate_uses (tree var, tree repl)
}
get_stmt_operands (stmt);
mark_new_vars = false;
if (is_gimple_reg (SSA_NAME_VAR (var)))
{
if (TREE_CODE (stmt) == MODIFY_EXPR)
{
propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 0), repl);
propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 1), repl);
}
uses = USE_OPS (ann);
for (j = 0; j < (int) NUM_USES (uses); j++)
if (USE_OP (uses, j) == var)
propagate_value (USE_OP_PTR (uses, j), repl);
{
propagate_value (USE_OP_PTR (uses, j), repl);
mark_new_vars = POINTER_TYPE_P (TREE_TYPE (repl));
}
}
else
{
@ -762,15 +819,15 @@ replace_immediate_uses (tree var, tree repl)
propagate_value (V_MAY_DEF_OP_PTR (v_may_defs, j), repl);
}
modify_stmt (stmt);
/* If REPL is a pointer, it may have different memory tags associated
with it. For instance, VAR may have had a name tag while REPL
only had a type tag. In these cases, the virtual operands (if
any) in the statement will refer to different symbols which need
to be renamed. */
if (POINTER_TYPE_P (TREE_TYPE (repl)))
if (mark_new_vars)
mark_new_vars_to_rename (stmt, vars_to_rename);
else
modify_stmt (stmt);
}
}
@ -788,23 +845,6 @@ raise_value (tree phi, tree val, tree *eq_to)
if (eq_to[ver] == var)
return;
switch (TREE_CODE (val))
{
case SSA_NAME:
case REAL_CST:
case COMPLEX_CST:
break;
case INTEGER_CST:
if (TREE_CODE (TREE_TYPE (var)) != POINTER_TYPE)
break;
default:
/* Do not propagate pointer constants. This might require folding
things like *&foo and rewriting the ssa, which is not worth the
trouble. */
val = var;
}
if (eq_to[ver])
{
if (operand_equal_p (eq_to[ver], val, 0))

View file

@ -191,4 +191,29 @@ release_ssa_name (tree var)
}
}
/* Creates a duplicate of a ssa name NAME defined in statement STMT. */
tree
duplicate_ssa_name (tree name, tree stmt)
{
tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
struct ptr_info_def *new_ptr_info;
if (!old_ptr_info)
return new_name;
new_ptr_info = ggc_alloc (sizeof (struct ptr_info_def));
*new_ptr_info = *old_ptr_info;
if (old_ptr_info->pt_vars)
{
new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
bitmap_copy (new_ptr_info->pt_vars, old_ptr_info->pt_vars);
}
SSA_NAME_PTR_INFO (new_name) = new_ptr_info;
return new_name;
}
#include "gt-tree-ssanames.h"

View file

@ -2537,6 +2537,7 @@ extern void phinodes_print_statistics (void);
extern void init_ssanames (void);
extern void fini_ssanames (void);
extern tree make_ssa_name (tree, tree);
extern tree duplicate_ssa_name (tree, tree);
extern void release_ssa_name (tree);
#ifdef GATHER_STATISTICS
extern void ssanames_print_statistics (void);