Commit 571325db by Andrew Pinski Committed by Andrew Pinski

re PR tree-optimization/14466 (missed PHI optimization (different types))

2004-05-14  Andrew Pinski  <pinskia@physics.uc.edu>

 	        PR optimization/14466
        * tree-complex.c (make_temp): Remove.
        (gimplify_val): Replace make_temp with make_rename_temp
        and add NULL as the second argument.
        (expand_complex_div_wide): Likewise.
        * tree-dfa.c (make_rename_temp): New function.
        * tree-flow.h (make_rename_temp): Declare.
        * tree-sra.c (make_temp): Remove.
        (lookup_scalar): Replace make_temp with make_rename_temp.
        (create_scalar_copies): Likewise.
        * tree-ssa-phiopt.c (conditional_replacement): When we
        get non gimple create a temporary variable to hold the
        casted expression.

2004-05-14  Andrew Pinski  <pinskia@physics.uc.edu>

	        PR optimization/14466
        * gcc.dg/tree-ssa/20040514-1.c: New test.

From-SVN: r81847
parent a2f0e34d
2004-05-14 Andrew Pinski <pinskia@physics.uc.edu>
PR optimization/14466
* tree-complex.c (make_temp): Remove.
(gimplify_val): Replace make_temp with make_rename_temp
and add NULL as the second argument.
(expand_complex_div_wide): Likewise.
* tree-dfa.c (make_rename_temp): New function.
* tree-flow.h (make_rename_temp): Declare.
* tree-sra.c (make_temp): Remove.
(lookup_scalar): Replace make_temp with make_rename_temp.
(create_scalar_copies): Likewise.
* tree-ssa-phiopt.c (conditional_replacement): When we
get non gimple create a temporary variable to hold the
casted expression.
2004-05-14 Paul Brook <paul@codesourcery.com> 2004-05-14 Paul Brook <paul@codesourcery.com>
* stor-layout.c (update_alignment_for_field): Use * stor-layout.c (update_alignment_for_field): Use
......
2004-05-14 Andrew Pinski <pinskia@physics.uc.edu>
* gcc.dg/tree-ssa/20040514-1.c: New test.
2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de> 2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
* gfortran.fortran-torture/compile/noncontinuation_1.f90: New * gfortran.fortran-torture/compile/noncontinuation_1.f90: New
......
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-phiopt1-details" } */
int t( int i)
{
int j;
if(i ==0)
{
j = 1;
goto end;
}
j = 0;
end:
return j;
/* Should have no ifs left after straightening. */
/* { dg-final { scan-tree-dump-times "if " 0 "phiopt1"} } */
...@@ -30,17 +30,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -30,17 +30,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "flags.h" #include "flags.h"
/* Build a temporary. Make sure and register it to be renamed. */
static tree
make_temp (tree type)
{
tree t = create_tmp_var (type, NULL);
add_referenced_tmp_var (t);
bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
return t;
}
/* Force EXP to be a gimple_val. */ /* Force EXP to be a gimple_val. */
static tree static tree
...@@ -51,7 +40,7 @@ gimplify_val (block_stmt_iterator *bsi, tree type, tree exp) ...@@ -51,7 +40,7 @@ gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
if (is_gimple_val (exp)) if (is_gimple_val (exp))
return exp; return exp;
t = make_temp (type); t = make_rename_temp (type, NULL);
new_stmt = build (MODIFY_EXPR, type, t, exp); new_stmt = build (MODIFY_EXPR, type, t, exp);
orig_stmt = bsi_stmt (*bsi); orig_stmt = bsi_stmt (*bsi);
...@@ -251,8 +240,8 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type, ...@@ -251,8 +240,8 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
cond = build (COND_EXPR, void_type_node, cond, t1, t2); cond = build (COND_EXPR, void_type_node, cond, t1, t2);
bsi_insert_before (bsi, cond, BSI_SAME_STMT); bsi_insert_before (bsi, cond, BSI_SAME_STMT);
min = make_temp (inner_type); min = make_rename_temp (inner_type, NULL);
max = make_temp (inner_type); max = make_rename_temp (inner_type, NULL);
l3 = create_artificial_label (); l3 = create_artificial_label ();
/* Split the original block, and create the TRUE and FALSE blocks. */ /* Split the original block, and create the TRUE and FALSE blocks. */
......
...@@ -486,6 +486,18 @@ create_ssa_name_ann (tree t) ...@@ -486,6 +486,18 @@ create_ssa_name_ann (tree t)
} }
/* Build a temporary. Make sure and register it to be renamed. */
tree
make_rename_temp (tree type, const char *prefix)
{
tree t = create_tmp_var (type, prefix);
add_referenced_tmp_var (t);
bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
return t;
}
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Debugging functions Debugging functions
......
...@@ -510,6 +510,7 @@ extern tree get_virtual_var (tree); ...@@ -510,6 +510,7 @@ extern tree get_virtual_var (tree);
extern void add_referenced_tmp_var (tree var); extern void add_referenced_tmp_var (tree var);
extern void mark_new_vars_to_rename (tree, bitmap); extern void mark_new_vars_to_rename (tree, bitmap);
extern void redirect_immediate_uses (tree, tree); extern void redirect_immediate_uses (tree, tree);
extern tree make_rename_temp (tree, const char *);
/* Flags used when computing reaching definitions and reached uses. */ /* Flags used when computing reaching definitions and reached uses. */
#define TDFA_USE_OPS 1 << 0 #define TDFA_USE_OPS 1 << 0
......
...@@ -112,17 +112,6 @@ sra_elt_eq (const void *x, const void *y) ...@@ -112,17 +112,6 @@ sra_elt_eq (const void *x, const void *y)
return true; return true;
} }
/* Build a temporary. Make sure and register it to be renamed. */
static tree
make_temp (tree type, const char *prefix)
{
tree t = create_tmp_var (type, prefix);
add_referenced_tmp_var (t);
bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
return t;
}
/* Mark all the variables in VDEF operands for STMT for renaming. /* Mark all the variables in VDEF operands for STMT for renaming.
This becomes necessary when we modify all of a non-scalar. */ This becomes necessary when we modify all of a non-scalar. */
...@@ -194,7 +183,7 @@ lookup_scalar (struct sra_elt *key, tree type) ...@@ -194,7 +183,7 @@ lookup_scalar (struct sra_elt *key, tree type)
res = xmalloc (sizeof (*res)); res = xmalloc (sizeof (*res));
*slot = res; *slot = res;
*res = *key; *res = *key;
res->replace = make_temp (type, "SR"); res->replace = make_rename_temp (type, "SR");
if (DECL_NAME (key->base) && !DECL_IGNORED_P (key->base)) if (DECL_NAME (key->base) && !DECL_IGNORED_P (key->base))
{ {
...@@ -691,7 +680,7 @@ create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode) ...@@ -691,7 +680,7 @@ create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode)
tree stmt, tmp; tree stmt, tmp;
/* Add TMP = VA_ARG_EXPR <> */ /* Add TMP = VA_ARG_EXPR <> */
tmp = make_temp (TREE_TYPE (rhs), NULL); tmp = make_rename_temp (TREE_TYPE (rhs), NULL);
stmt = csc_assign (&tsi, tmp, rhs); stmt = csc_assign (&tsi, tmp, rhs);
/* Mark all the variables in VDEF operands for renaming, because /* Mark all the variables in VDEF operands for renaming, because
......
...@@ -72,6 +72,7 @@ extern void change_partition_var (var_map, tree, int); ...@@ -72,6 +72,7 @@ extern void change_partition_var (var_map, tree, int);
extern void compact_var_map (var_map, int); extern void compact_var_map (var_map, int);
extern void remove_ssa_form (FILE *, var_map, int); extern void remove_ssa_form (FILE *, var_map, int);
extern void register_ssa_partitions_for_vars (bitmap vars, var_map map); extern void register_ssa_partitions_for_vars (bitmap vars, var_map map);
extern tree make_ssa_temp (tree);
static inline int num_var_partitions (var_map); static inline int num_var_partitions (var_map);
static inline tree var_to_partition_to_var (var_map, tree); static inline tree var_to_partition_to_var (var_map, tree);
......
...@@ -37,9 +37,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -37,9 +37,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static void tree_ssa_phiopt (void); static void tree_ssa_phiopt (void);
static bool conditional_replacement (basic_block bb, tree phi, tree arg0, static bool conditional_replacement (basic_block bb, tree phi, tree arg0,
tree arg1); tree arg1);
/* This pass eliminates PHI nodes which can be trivially implemented as /* This pass eliminates PHI nodes which can be trivially implemented as
an assignment from a conditional expression. ie if we have something an assignment from a conditional expression. ie if we have something
like: like:
...@@ -108,11 +107,13 @@ static bool ...@@ -108,11 +107,13 @@ static bool
conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
{ {
tree result; tree result;
tree old_result = NULL;
basic_block other_block = NULL; basic_block other_block = NULL;
basic_block cond_block = NULL; basic_block cond_block = NULL;
tree last0, last1, new, cond; tree last0, last1, new, cond;
block_stmt_iterator bsi; block_stmt_iterator bsi;
edge true_edge, false_edge; edge true_edge, false_edge;
tree new_var = NULL;
/* The PHI arguments have the constants 0 and 1, then convert /* The PHI arguments have the constants 0 and 1, then convert
it to the conditional. */ it to the conditional. */
...@@ -172,14 +173,20 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) ...@@ -172,14 +173,20 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
return false; return false;
/* If the condition is not a naked SSA_NAME and its type does not /* If the condition is not a naked SSA_NAME and its type does not
match the type of the result, then we can not optimize this case match the type of the result, then we have to create a new
as it would likely create non-gimple code when the condition variable to optimize this case as it would likely create
was converted to the result's type. */ non-gimple code when the condition was converted to the
result's type. */
cond = COND_EXPR_COND (last_stmt (cond_block)); cond = COND_EXPR_COND (last_stmt (cond_block));
result = PHI_RESULT (phi); result = PHI_RESULT (phi);
if (TREE_CODE (cond) != SSA_NAME if (TREE_CODE (cond) != SSA_NAME
&& !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result))) && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
return false; {
new_var = make_rename_temp (TREE_TYPE (cond), NULL);
old_result = cond;
cond = new_var;
}
/* If the condition was a naked SSA_NAME and the type is not the /* If the condition was a naked SSA_NAME and the type is not the
same as the type of the result, then convert the type of the same as the type of the result, then convert the type of the
...@@ -190,6 +197,25 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) ...@@ -190,6 +197,25 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
/* We need to know which is the true edge and which is the false /* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */ edge so that we know when to invert the condition below. */
extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge); extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
/* Insert our new statement at the head of our block. */
bsi = bsi_start (bb);
if (old_result)
{
tree new1;
if (TREE_CODE_CLASS (TREE_CODE (old_result)) != '<')
return false;
new1 = build (TREE_CODE (old_result), TREE_TYPE (result),
TREE_OPERAND (old_result, 0),
TREE_OPERAND (old_result, 1));
new1 = build (MODIFY_EXPR, TREE_TYPE (result),
new_var, new1);
bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
}
/* At this point we know we have a COND_EXPR with two successors. /* At this point we know we have a COND_EXPR with two successors.
One successor is BB, the other successor is an empty block which One successor is BB, the other successor is an empty block which
...@@ -208,6 +234,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) ...@@ -208,6 +234,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
false edge as the value zero. Note that those conditions are not false edge as the value zero. Note that those conditions are not
the same since only one of the outgoing edges from the COND_EXPR the same since only one of the outgoing edges from the COND_EXPR
will directly reach BB and thus be associated with an argument. */ will directly reach BB and thus be associated with an argument. */
if ((PHI_ARG_EDGE (phi, 0) == true_edge && integer_onep (arg0)) if ((PHI_ARG_EDGE (phi, 0) == true_edge && integer_onep (arg0))
|| (PHI_ARG_EDGE (phi, 0) == false_edge && integer_zerop (arg0)) || (PHI_ARG_EDGE (phi, 0) == false_edge && integer_zerop (arg0))
|| (PHI_ARG_EDGE (phi, 1) == true_edge && integer_onep (arg1)) || (PHI_ARG_EDGE (phi, 1) == true_edge && integer_onep (arg1))
...@@ -218,11 +245,25 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) ...@@ -218,11 +245,25 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
} }
else else
{ {
cond = invert_truthvalue (cond); tree cond1 = invert_truthvalue (cond);
cond = cond1;
/* If what we get back is a conditional expression, there is no
way that is can be gimple. */
if (TREE_CODE (cond) == COND_EXPR)
return false;
/* If what we get back is not gimple try to create it as gimple by
using a temporary variable. */
if (is_gimple_cast (cond) if (is_gimple_cast (cond)
&& !is_gimple_val (TREE_OPERAND (cond, 0))) && !is_gimple_val (TREE_OPERAND (cond, 0)))
return false; {
tree temp = TREE_OPERAND (cond, 0);
tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
bsi_insert_after (&bsi, new, BSI_NEW_STMT);
cond = fold_convert (TREE_TYPE (result), new_var_1);
}
if (TREE_CODE (cond) == TRUTH_NOT_EXPR if (TREE_CODE (cond) == TRUTH_NOT_EXPR
&& !is_gimple_val (TREE_OPERAND (cond, 0))) && !is_gimple_val (TREE_OPERAND (cond, 0)))
...@@ -232,9 +273,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) ...@@ -232,9 +273,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
PHI_RESULT (phi), cond); PHI_RESULT (phi), cond);
} }
/* Insert our new statement at the head of our block. */ bsi_insert_after (&bsi, new, BSI_NEW_STMT);
bsi = bsi_start (bb);
bsi_insert_after (&bsi, new, BSI_SAME_STMT);
/* Register our new statement as the defining statement for /* Register our new statement as the defining statement for
the result. */ the result. */
...@@ -300,7 +339,8 @@ struct tree_opt_pass pass_phiopt = ...@@ -300,7 +339,8 @@ struct tree_opt_pass pass_phiopt =
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
| TODO_verify_ssa | TODO_verify_ssa | TODO_rename_vars
| TODO_verify_flow
}; };
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