mirror of git://gcc.gnu.org/git/gcc.git
re PR tree-optimization/52976 (Revision 186384 breaks the polyhedron tests aermod.f90 and doduc.f90 at -O3 -ffast-math)
gcc: 2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com> PR tree-optimization/52976 * tree-ssa-reassoc.c (add_to_ops_vec_max_rank): Delete. (possibly_move_powi): New function. (rewrite_expr_tree): Call possibly_move_powi. (rewrite_expr_tree_parallel): Likewise. (attempt_builtin_powi): Change call of add_to_ops_vec_max_rank to call add_to_ops_vec instead. gcc/testsuite: 2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com> PR tree-optimization/52976 gfortran.dg/reassoc_11.f: New test. From-SVN: r186568
This commit is contained in:
parent
c2723bdeb0
commit
b59eee4039
|
@ -1,3 +1,13 @@
|
||||||
|
2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
PR tree-optimization/52976
|
||||||
|
* tree-ssa-reassoc.c (add_to_ops_vec_max_rank): Delete.
|
||||||
|
(possibly_move_powi): New function.
|
||||||
|
(rewrite_expr_tree): Call possibly_move_powi.
|
||||||
|
(rewrite_expr_tree_parallel): Likewise.
|
||||||
|
(attempt_builtin_powi): Change call of add_to_ops_vec_max_rank to
|
||||||
|
call add_to_ops_vec instead.
|
||||||
|
|
||||||
2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
||||||
|
|
||||||
PR tree-optimization/52976
|
PR tree-optimization/52976
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
PR tree-optimization/52976
|
||||||
|
gfortran.dg/reassoc_11.f: New test.
|
||||||
|
|
||||||
2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
2012-04-18 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
||||||
|
|
||||||
PR tree-optimization/52976
|
PR tree-optimization/52976
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-O3 -ffast-math" }
|
||||||
|
|
||||||
|
! This tests only for compile-time failure, which formerly occurred
|
||||||
|
! when a __builtin_powi was introduced by reassociation in a bad place.
|
||||||
|
|
||||||
|
SUBROUTINE GRDURBAN(URBWSTR, ZIURB, GRIDHT)
|
||||||
|
|
||||||
|
IMPLICIT NONE
|
||||||
|
INTEGER :: I
|
||||||
|
REAL :: SW2, URBWSTR, ZIURB, GRIDHT(87)
|
||||||
|
|
||||||
|
SAVE
|
||||||
|
|
||||||
|
SW2 = 1.6*(GRIDHT(I)/ZIURB)**0.667*URBWSTR**2
|
||||||
|
|
||||||
|
END
|
|
@ -544,28 +544,6 @@ add_repeat_to_ops_vec (VEC(operand_entry_t, heap) **ops, tree op,
|
||||||
reassociate_stats.pows_encountered++;
|
reassociate_stats.pows_encountered++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add an operand entry to *OPS for the tree operand OP, giving the
|
|
||||||
new entry a larger rank than any other operand already in *OPS. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_to_ops_vec_max_rank (VEC(operand_entry_t, heap) **ops, tree op)
|
|
||||||
{
|
|
||||||
operand_entry_t oe = (operand_entry_t) pool_alloc (operand_entry_pool);
|
|
||||||
operand_entry_t oe1;
|
|
||||||
unsigned i;
|
|
||||||
unsigned max_rank = 0;
|
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (operand_entry_t, *ops, i, oe1)
|
|
||||||
if (oe1->rank > max_rank)
|
|
||||||
max_rank = oe1->rank;
|
|
||||||
|
|
||||||
oe->op = op;
|
|
||||||
oe->rank = max_rank + 1;
|
|
||||||
oe->id = next_operand_entry_id++;
|
|
||||||
oe->count = 1;
|
|
||||||
VEC_safe_push (operand_entry_t, heap, *ops, oe);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true if STMT is reassociable operation containing a binary
|
/* Return true if STMT is reassociable operation containing a binary
|
||||||
operation with tree code CODE, and is inside LOOP. */
|
operation with tree code CODE, and is inside LOOP. */
|
||||||
|
|
||||||
|
@ -2264,6 +2242,47 @@ remove_visited_stmt_chain (tree var)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If OP is an SSA name, find its definition and determine whether it
|
||||||
|
is a call to __builtin_powi. If so, move the definition prior to
|
||||||
|
STMT. Only do this during early reassociation. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
possibly_move_powi (gimple stmt, tree op)
|
||||||
|
{
|
||||||
|
gimple stmt2;
|
||||||
|
tree fndecl;
|
||||||
|
gimple_stmt_iterator gsi1, gsi2;
|
||||||
|
|
||||||
|
if (!first_pass_instance
|
||||||
|
|| !flag_unsafe_math_optimizations
|
||||||
|
|| TREE_CODE (op) != SSA_NAME)
|
||||||
|
return;
|
||||||
|
|
||||||
|
stmt2 = SSA_NAME_DEF_STMT (op);
|
||||||
|
|
||||||
|
if (!is_gimple_call (stmt2)
|
||||||
|
|| !has_single_use (gimple_call_lhs (stmt2)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
fndecl = gimple_call_fndecl (stmt2);
|
||||||
|
|
||||||
|
if (!fndecl
|
||||||
|
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (DECL_FUNCTION_CODE (fndecl))
|
||||||
|
{
|
||||||
|
CASE_FLT_FN (BUILT_IN_POWI):
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsi1 = gsi_for_stmt (stmt);
|
||||||
|
gsi2 = gsi_for_stmt (stmt2);
|
||||||
|
gsi_move_before (&gsi2, &gsi1);
|
||||||
|
}
|
||||||
|
|
||||||
/* This function checks three consequtive operands in
|
/* This function checks three consequtive operands in
|
||||||
passed operands vector OPS starting from OPINDEX and
|
passed operands vector OPS starting from OPINDEX and
|
||||||
swaps two operands if it is profitable for binary operation
|
swaps two operands if it is profitable for binary operation
|
||||||
|
@ -2369,6 +2388,8 @@ rewrite_expr_tree (gimple stmt, unsigned int opindex,
|
||||||
print_gimple_stmt (dump_file, stmt, 0, 0);
|
print_gimple_stmt (dump_file, stmt, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
possibly_move_powi (stmt, oe1->op);
|
||||||
|
possibly_move_powi (stmt, oe2->op);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2414,6 +2435,8 @@ rewrite_expr_tree (gimple stmt, unsigned int opindex,
|
||||||
fprintf (dump_file, " into ");
|
fprintf (dump_file, " into ");
|
||||||
print_gimple_stmt (dump_file, stmt, 0, 0);
|
print_gimple_stmt (dump_file, stmt, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
possibly_move_powi (stmt, oe->op);
|
||||||
}
|
}
|
||||||
/* Recurse on the LHS of the binary operator, which is guaranteed to
|
/* Recurse on the LHS of the binary operator, which is guaranteed to
|
||||||
be the non-leaf side. */
|
be the non-leaf side. */
|
||||||
|
@ -2587,6 +2610,9 @@ rewrite_expr_tree_parallel (gimple stmt, int width,
|
||||||
fprintf (dump_file, " into ");
|
fprintf (dump_file, " into ");
|
||||||
print_gimple_stmt (dump_file, stmts[i], 0, 0);
|
print_gimple_stmt (dump_file, stmts[i], 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
possibly_move_powi (stmts[i], op1);
|
||||||
|
possibly_move_powi (stmts[i], op2);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_visited_stmt_chain (last_rhs1);
|
remove_visited_stmt_chain (last_rhs1);
|
||||||
|
@ -3298,6 +3324,8 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops,
|
||||||
power));
|
power));
|
||||||
gimple_call_set_lhs (pow_stmt, iter_result);
|
gimple_call_set_lhs (pow_stmt, iter_result);
|
||||||
gimple_set_location (pow_stmt, gimple_location (stmt));
|
gimple_set_location (pow_stmt, gimple_location (stmt));
|
||||||
|
/* Temporarily place the call; we will move it to the
|
||||||
|
correct place during rewrite_expr. */
|
||||||
gsi_insert_before (&gsi, pow_stmt, GSI_SAME_STMT);
|
gsi_insert_before (&gsi, pow_stmt, GSI_SAME_STMT);
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
@ -3402,10 +3430,8 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops,
|
||||||
gsi_insert_before (&gsi, pow_stmt, GSI_SAME_STMT);
|
gsi_insert_before (&gsi, pow_stmt, GSI_SAME_STMT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append the result of this iteration to the ops vector.
|
/* Append the result of this iteration to the ops vector. */
|
||||||
Give it a rank higher than all other ranks in the ops vector
|
add_to_ops_vec (ops, iter_result);
|
||||||
so that all uses of it will be forced to come after it. */
|
|
||||||
add_to_ops_vec_max_rank (ops, iter_result);
|
|
||||||
|
|
||||||
/* Decrement the occurrence count of each element in the product
|
/* Decrement the occurrence count of each element in the product
|
||||||
by the count found above, and remove this many copies of each
|
by the count found above, and remove this many copies of each
|
||||||
|
|
Loading…
Reference in New Issue