GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* Currently, the only mini-pass in this file tries to CSE reciprocal
operations. These are common in sequences such as this one:
{
return TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
&& TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == RDIV_EXPR
- && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 1) == def;
+ && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 1) == def
+ /* Do not recognize x / x as valid division, as we are getting
+ confused later by replacing all immediate uses x in such
+ a stmt. */
+ && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0) != def;
}
/* Walk the subset of the dominator tree rooted at OCC, setting the
static bool
gate_cse_reciprocals (void)
{
- return optimize && !optimize_size && flag_unsafe_math_optimizations;
+ return optimize && !optimize_size && flag_reciprocal_math;
}
/* Go through all the floating-point SSA_NAMEs, and call
&& TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == RDIV_EXPR)
{
tree arg1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 1);
- tree stmt1 = SSA_NAME_DEF_STMT (arg1);
+ tree stmt1;
+
+ if (TREE_CODE (arg1) != SSA_NAME)
+ continue;
+
+ stmt1 = SSA_NAME_DEF_STMT (arg1);
if (TREE_CODE (stmt1) == GIMPLE_MODIFY_STMT
&& TREE_CODE (GIMPLE_STMT_OPERAND (stmt1, 1)) == CALL_EXPR
|| DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
{
enum built_in_function code;
+ bool md_code;
tree arg10;
tree tmp;
code = DECL_FUNCTION_CODE (fndecl);
- fndecl = targetm.builtin_reciprocal (code, false);
+ md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
+
+ fndecl = targetm.builtin_reciprocal (code, md_code, false);
if (!fndecl)
continue;
return 0;
}
-struct tree_opt_pass pass_cse_reciprocals =
+struct gimple_opt_pass pass_cse_reciprocals =
{
+ {
+ GIMPLE_PASS,
"recip", /* name */
gate_cse_reciprocals, /* gate */
execute_cse_reciprocals, /* execute */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
- | TODO_verify_stmts, /* todo_flags_finish */
- 0 /* letter */
+ | TODO_verify_stmts /* todo_flags_finish */
+ }
};
/* Records an occurrence at statement USE_STMT in the vector of trees
call = build_call_expr (fndecl, 1, name);
stmt = build_gimple_modify_stmt (res, call);
def_stmt = SSA_NAME_DEF_STMT (name);
- if (bb_for_stmt (def_stmt) == top_bb
- && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT)
+ if (!SSA_NAME_IS_DEFAULT_DEF (name)
+ && TREE_CODE (def_stmt) != PHI_NODE
+ && bb_for_stmt (def_stmt) == top_bb)
{
bsi = bsi_for_stmt (def_stmt);
bsi_insert_after (&bsi, stmt, BSI_SAME_STMT);
&& optimize;
}
-struct tree_opt_pass pass_cse_sincos =
+struct gimple_opt_pass pass_cse_sincos =
{
+ {
+ GIMPLE_PASS,
"sincos", /* name */
gate_cse_sincos, /* gate */
execute_cse_sincos, /* execute */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
- | TODO_verify_stmts, /* todo_flags_finish */
- 0 /* letter */
+ | TODO_verify_stmts /* todo_flags_finish */
+ }
};
/* Find all expressions in the form of sqrt(a/b) and
|| DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
{
enum built_in_function code;
+ bool md_code;
tree arg1;
tree stmt1;
code = DECL_FUNCTION_CODE (fndecl);
- fndecl = targetm.builtin_reciprocal (code, true);
+ md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
+
+ fndecl = targetm.builtin_reciprocal (code, md_code, true);
if (!fndecl)
continue;
arg1 = CALL_EXPR_ARG (GIMPLE_STMT_OPERAND (stmt, 1), 0);
+
+ if (TREE_CODE (arg1) != SSA_NAME)
+ continue;
+
stmt1 = SSA_NAME_DEF_STMT (arg1);
if (TREE_CODE (stmt1) == GIMPLE_MODIFY_STMT
return flag_unsafe_math_optimizations && optimize;
}
-struct tree_opt_pass pass_convert_to_rsqrt =
+struct gimple_opt_pass pass_convert_to_rsqrt =
{
+ {
+ GIMPLE_PASS,
"rsqrt", /* name */
gate_convert_to_rsqrt, /* gate */
execute_convert_to_rsqrt, /* execute */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
- | TODO_verify_stmts, /* todo_flags_finish */
- 0 /* letter */
+ | TODO_verify_stmts /* todo_flags_finish */
+ }
};