mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 01:50:33 +08:00
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
This commit is contained in:
parent
a2f0e34d9e
commit
571325db59
@ -1,3 +1,19 @@
|
||||
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>
|
||||
|
||||
* stor-layout.c (update_alignment_for_field): Use
|
||||
|
@ -1,3 +1,7 @@
|
||||
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>
|
||||
|
||||
* gfortran.fortran-torture/compile/noncontinuation_1.f90: New
|
||||
|
17
gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c
Normal file
17
gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* { 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
|
||||
#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. */
|
||||
|
||||
static tree
|
||||
@ -51,7 +40,7 @@ gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
|
||||
if (is_gimple_val (exp))
|
||||
return exp;
|
||||
|
||||
t = make_temp (type);
|
||||
t = make_rename_temp (type, NULL);
|
||||
new_stmt = build (MODIFY_EXPR, type, t, exp);
|
||||
|
||||
orig_stmt = bsi_stmt (*bsi);
|
||||
@ -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);
|
||||
bsi_insert_before (bsi, cond, BSI_SAME_STMT);
|
||||
|
||||
min = make_temp (inner_type);
|
||||
max = make_temp (inner_type);
|
||||
min = make_rename_temp (inner_type, NULL);
|
||||
max = make_rename_temp (inner_type, NULL);
|
||||
l3 = create_artificial_label ();
|
||||
|
||||
/* Split the original block, and create the TRUE and FALSE blocks. */
|
||||
|
@ -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
|
||||
|
@ -510,6 +510,7 @@ extern tree get_virtual_var (tree);
|
||||
extern void add_referenced_tmp_var (tree var);
|
||||
extern void mark_new_vars_to_rename (tree, bitmap);
|
||||
extern void redirect_immediate_uses (tree, tree);
|
||||
extern tree make_rename_temp (tree, const char *);
|
||||
|
||||
/* Flags used when computing reaching definitions and reached uses. */
|
||||
#define TDFA_USE_OPS 1 << 0
|
||||
|
@ -112,17 +112,6 @@ sra_elt_eq (const void *x, const void *y)
|
||||
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.
|
||||
This becomes necessary when we modify all of a non-scalar. */
|
||||
|
||||
@ -194,7 +183,7 @@ lookup_scalar (struct sra_elt *key, tree type)
|
||||
res = xmalloc (sizeof (*res));
|
||||
*slot = res;
|
||||
*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))
|
||||
{
|
||||
@ -691,7 +680,7 @@ create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode)
|
||||
tree stmt, tmp;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Mark all the variables in VDEF operands for renaming, because
|
||||
|
@ -72,6 +72,7 @@ extern void change_partition_var (var_map, tree, int);
|
||||
extern void compact_var_map (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 tree make_ssa_temp (tree);
|
||||
|
||||
static inline int num_var_partitions (var_map);
|
||||
static inline tree var_to_partition_to_var (var_map, tree);
|
||||
|
@ -37,9 +37,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
static void tree_ssa_phiopt (void);
|
||||
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
|
||||
an assignment from a conditional expression. ie if we have something
|
||||
like:
|
||||
@ -108,11 +107,13 @@ static bool
|
||||
conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
|
||||
{
|
||||
tree result;
|
||||
tree old_result = NULL;
|
||||
basic_block other_block = NULL;
|
||||
basic_block cond_block = NULL;
|
||||
tree last0, last1, new, cond;
|
||||
block_stmt_iterator bsi;
|
||||
edge true_edge, false_edge;
|
||||
tree new_var = NULL;
|
||||
|
||||
/* The PHI arguments have the constants 0 and 1, then convert
|
||||
it to the conditional. */
|
||||
@ -172,14 +173,20 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
|
||||
return false;
|
||||
|
||||
/* 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
|
||||
as it would likely create non-gimple code when the condition
|
||||
was converted to the result's type. */
|
||||
match the type of the result, then we have to create a new
|
||||
variable to optimize this case as it would likely create
|
||||
non-gimple code when the condition was converted to the
|
||||
result's type. */
|
||||
|
||||
cond = COND_EXPR_COND (last_stmt (cond_block));
|
||||
result = PHI_RESULT (phi);
|
||||
if (TREE_CODE (cond) != SSA_NAME
|
||||
&& !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
|
||||
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)
|
||||
/* 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. */
|
||||
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.
|
||||
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)
|
||||
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
|
||||
will directly reach BB and thus be associated with an argument. */
|
||||
|
||||
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, 1) == true_edge && integer_onep (arg1))
|
||||
@ -218,11 +245,25 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
|
||||
}
|
||||
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)
|
||||
&& !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
|
||||
&& !is_gimple_val (TREE_OPERAND (cond, 0)))
|
||||
@ -232,9 +273,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
|
||||
PHI_RESULT (phi), cond);
|
||||
}
|
||||
|
||||
/* Insert our new statement at the head of our block. */
|
||||
bsi = bsi_start (bb);
|
||||
bsi_insert_after (&bsi, new, BSI_SAME_STMT);
|
||||
bsi_insert_after (&bsi, new, BSI_NEW_STMT);
|
||||
|
||||
/* Register our new statement as the defining statement for
|
||||
the result. */
|
||||
@ -300,7 +339,8 @@ struct tree_opt_pass pass_phiopt =
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
|
||||
| TODO_verify_ssa
|
||||
| TODO_verify_ssa | TODO_rename_vars
|
||||
| TODO_verify_flow
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user