X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-tailcall.c;h=0458c8aec60e652938db88fa2bd64b4af17fddbf;hb=9ec0fbe12f5d88044672d79ff164eff1d2ec3f94;hp=fa63637fb6dba1b622b0892e70f1714f3236fd95;hpb=46a0e9e809c04b40dd67d472c3b3f9484757684e;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index fa63637fb6d..0458c8aec60 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -5,7 +5,7 @@ This file is part of GCC. 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) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -14,9 +14,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 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 +. */ #include "config.h" #include "system.h" @@ -35,6 +34,7 @@ Boston, MA 02110-1301, USA. */ #include "tree-pass.h" #include "flags.h" #include "langhooks.h" +#include "dbgcnt.h" /* The file implements the tail recursion elimination. It is also used to analyze the tail calls in general, passing the results to the rtl level @@ -135,7 +135,7 @@ suitable_for_tail_opt_p (void) referenced_var_iterator rvi; tree var; - if (current_function_stdarg) + if (cfun->stdarg) return false; /* No local variable nor structure field should be call-clobbered. We @@ -164,7 +164,7 @@ suitable_for_tail_call_opt_p (void) /* alloca (until we have stack slot life analysis) inhibits sibling call optimizations, but not tail recursion. */ - if (current_function_calls_alloca) + if (cfun->calls_alloca) return false; /* If we are using sjlj exceptions, we may need to add a call to @@ -176,7 +176,7 @@ suitable_for_tail_call_opt_p (void) /* Any function that calls setjmp might have longjmp called from any called function. ??? We really should represent this properly in the CFG so that this needn't be special cased. */ - if (current_function_calls_setjmp) + if (cfun->calls_setjmp) return false; /* ??? It is OK if the argument of a function is taken in some cases, @@ -297,7 +297,7 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m, /* Accumulator optimizations will reverse the order of operations. We can only do that for floating-point types if we're assuming that addition and multiplication are associative. */ - if (!flag_unsafe_math_optimizations) + if (!flag_associative_math) if (FLOAT_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))) return false; @@ -346,7 +346,7 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m, *ass_var = dest; return true; - /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR). */ + /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR, POINTER_PLUS_EXPR). */ default: return false; @@ -414,7 +414,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret) /* If the statement has virtual or volatile operands, fail. */ ann = stmt_ann (stmt); if (!ZERO_SSA_OPERANDS (stmt, (SSA_OP_VUSE | SSA_OP_VIRTUAL_DEFS)) - || ann->has_volatile_ops) + || ann->has_volatile_ops + || (!gimple_aliases_computed_p (cfun) && ann->references_memory)) return; } @@ -447,8 +448,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret) equivalent types. The latter requirement could be relaxed if we emitted a suitable type conversion statement. */ if (!is_gimple_reg_type (TREE_TYPE (param)) - || !lang_hooks.types_compatible_p (TREE_TYPE (param), - TREE_TYPE (arg))) + || !useless_type_conversion_p (TREE_TYPE (param), + TREE_TYPE (arg))) break; /* The parameter should be a real operand, so that phi node @@ -1007,7 +1008,7 @@ execute_tail_recursion (void) static bool gate_tail_calls (void) { - return flag_optimize_sibling_calls != 0; + return flag_optimize_sibling_calls != 0 && dbg_cnt (tail_call); } static unsigned int @@ -1016,8 +1017,10 @@ execute_tail_calls (void) return tree_optimize_tail_calls_1 (true); } -struct tree_opt_pass pass_tail_recursion = +struct gimple_opt_pass pass_tail_recursion = { + { + GIMPLE_PASS, "tailr", /* name */ gate_tail_calls, /* gate */ execute_tail_recursion, /* execute */ @@ -1029,12 +1032,14 @@ struct tree_opt_pass pass_tail_recursion = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */ - 0 /* letter */ + TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + } }; -struct tree_opt_pass pass_tail_calls = +struct gimple_opt_pass pass_tail_calls = { + { + GIMPLE_PASS, "tailc", /* name */ gate_tail_calls, /* gate */ execute_tail_calls, /* execute */ @@ -1046,6 +1051,6 @@ struct tree_opt_pass pass_tail_calls = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */ - 0 /* letter */ + TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + } };