Commit d7621d3c by Zdenek Dvorak Committed by Zdenek Dvorak

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
parent f2b5cf97
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> 2004-06-17 David Ayers <d.ayers@inode.at>
* c-parse.in: Unify Objective-C token names. * c-parse.in: Unify Objective-C token names.
......
...@@ -74,7 +74,6 @@ static void free_blocks_annotations (void); ...@@ -74,7 +74,6 @@ static void free_blocks_annotations (void);
static void clear_blocks_annotations (void); static void clear_blocks_annotations (void);
static void make_blocks (tree); static void make_blocks (tree);
static void factor_computed_gotos (void); static void factor_computed_gotos (void);
static tree tree_block_label (basic_block bb);
/* Edges. */ /* Edges. */
static void make_edges (void); static void make_edges (void);
...@@ -3973,7 +3972,7 @@ thread_jumps (void) ...@@ -3973,7 +3972,7 @@ thread_jumps (void)
/* Return a non-special label in the head of basic block BLOCK. /* Return a non-special label in the head of basic block BLOCK.
Create one if it doesn't exist. */ Create one if it doesn't exist. */
static tree tree
tree_block_label (basic_block bb) tree_block_label (basic_block bb)
{ {
block_stmt_iterator i, s = bsi_start (bb); block_stmt_iterator i, s = bsi_start (bb);
......
...@@ -629,6 +629,53 @@ bsi_start (basic_block bb) ...@@ -629,6 +629,53 @@ bsi_start (basic_block bb)
return bsi; 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 /* Return a block statement iterator that points to the end of basic
block BB. */ block BB. */
static inline block_stmt_iterator static inline block_stmt_iterator
......
...@@ -416,6 +416,7 @@ typedef struct { ...@@ -416,6 +416,7 @@ typedef struct {
static inline block_stmt_iterator bsi_start (basic_block); static inline block_stmt_iterator bsi_start (basic_block);
static inline block_stmt_iterator bsi_last (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 bool bsi_end_p (block_stmt_iterator);
static inline void bsi_next (block_stmt_iterator *); static inline void bsi_next (block_stmt_iterator *);
static inline void bsi_prev (block_stmt_iterator *); static inline void bsi_prev (block_stmt_iterator *);
...@@ -486,6 +487,7 @@ extern void notice_special_calls (tree); ...@@ -486,6 +487,7 @@ extern void notice_special_calls (tree);
extern void clear_special_calls (void); extern void clear_special_calls (void);
extern void compute_dominance_frontiers (bitmap *); extern void compute_dominance_frontiers (bitmap *);
extern void verify_stmts (void); 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 *); extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
/* In tree-pretty-print.c. */ /* In tree-pretty-print.c. */
......
...@@ -705,6 +705,52 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data) ...@@ -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. */ /* Replaces immediate uses of VAR by REPL. */
...@@ -718,6 +764,7 @@ replace_immediate_uses (tree var, tree repl) ...@@ -718,6 +764,7 @@ replace_immediate_uses (tree var, tree repl)
dataflow_t df; dataflow_t df;
tree stmt; tree stmt;
stmt_ann_t ann; stmt_ann_t ann;
bool mark_new_vars;
df = get_immediate_uses (SSA_NAME_DEF_STMT (var)); df = get_immediate_uses (SSA_NAME_DEF_STMT (var));
n = num_immediate_uses (df); n = num_immediate_uses (df);
...@@ -742,12 +789,22 @@ replace_immediate_uses (tree var, tree repl) ...@@ -742,12 +789,22 @@ replace_immediate_uses (tree var, tree repl)
} }
get_stmt_operands (stmt); get_stmt_operands (stmt);
mark_new_vars = false;
if (is_gimple_reg (SSA_NAME_VAR (var))) 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); uses = USE_OPS (ann);
for (j = 0; j < (int) NUM_USES (uses); j++) for (j = 0; j < (int) NUM_USES (uses); j++)
if (USE_OP (uses, j) == var) 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 else
{ {
...@@ -762,15 +819,15 @@ replace_immediate_uses (tree var, tree repl) ...@@ -762,15 +819,15 @@ replace_immediate_uses (tree var, tree repl)
propagate_value (V_MAY_DEF_OP_PTR (v_may_defs, j), 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 /* 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 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 only had a type tag. In these cases, the virtual operands (if
any) in the statement will refer to different symbols which need any) in the statement will refer to different symbols which need
to be renamed. */ to be renamed. */
if (POINTER_TYPE_P (TREE_TYPE (repl))) if (mark_new_vars)
mark_new_vars_to_rename (stmt, vars_to_rename); 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) ...@@ -788,23 +845,6 @@ raise_value (tree phi, tree val, tree *eq_to)
if (eq_to[ver] == var) if (eq_to[ver] == var)
return; 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 (eq_to[ver])
{ {
if (operand_equal_p (eq_to[ver], val, 0)) if (operand_equal_p (eq_to[ver], val, 0))
......
...@@ -191,4 +191,29 @@ release_ssa_name (tree var) ...@@ -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" #include "gt-tree-ssanames.h"
...@@ -2537,6 +2537,7 @@ extern void phinodes_print_statistics (void); ...@@ -2537,6 +2537,7 @@ extern void phinodes_print_statistics (void);
extern void init_ssanames (void); extern void init_ssanames (void);
extern void fini_ssanames (void); extern void fini_ssanames (void);
extern tree make_ssa_name (tree, tree); extern tree make_ssa_name (tree, tree);
extern tree duplicate_ssa_name (tree, tree);
extern void release_ssa_name (tree); extern void release_ssa_name (tree);
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
extern void ssanames_print_statistics (void); extern void ssanames_print_statistics (void);
......
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