re PR ipa/65076 (16% tramp3d-v4.cpp compile time regression)
PR ipa/65076 * passes.def: Add pass_nothrow. * ipa-pure-const.c: (pass_data_nothrow): New. (pass_nothrow): New. (pass_nothrow::execute): New. (make_pass_nothrow): New. * tree-pass.h (make_pass_nothrow): Declare. From-SVN: r221719
This commit is contained in:
parent
a21065cad0
commit
38147a2a4e
|
@ -1,3 +1,13 @@
|
|||
2015-03-26 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR ipa/65076
|
||||
* passes.def: Add pass_nothrow.
|
||||
* ipa-pure-const.c: (pass_data_nothrow): New.
|
||||
(pass_nothrow): New.
|
||||
(pass_nothrow::execute): New.
|
||||
(make_pass_nothrow): New.
|
||||
* tree-pass.h (make_pass_nothrow): Declare.
|
||||
|
||||
2015-03-26 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* ipa-inline-analysis.c (redirect_to_unreachable): Be prepared for
|
||||
|
|
|
@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-scalar-evolution.h"
|
||||
#include "intl.h"
|
||||
#include "opts.h"
|
||||
#include "varasm.h"
|
||||
|
||||
/* Lattice values for const and pure functions. Everything starts out
|
||||
being const, then may drop to pure and then neither depending on
|
||||
|
@ -710,6 +711,16 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
|
|||
if (is_gimple_debug (stmt))
|
||||
return;
|
||||
|
||||
/* Do consider clobber as side effects before IPA, so we rather inline
|
||||
C++ destructors and keep clobber semantics than eliminate them.
|
||||
|
||||
TODO: We may get smarter during early optimizations on these and let
|
||||
functions containing only clobbers to be optimized more. This is a common
|
||||
case of C++ destructors. */
|
||||
|
||||
if ((ipa || cfun->after_inlining) && gimple_clobber_p (stmt))
|
||||
return;
|
||||
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, " scanning: ");
|
||||
|
@ -1870,3 +1881,96 @@ make_pass_warn_function_noreturn (gcc::context *ctxt)
|
|||
{
|
||||
return new pass_warn_function_noreturn (ctxt);
|
||||
}
|
||||
|
||||
/* Simple local pass for pure const discovery reusing the analysis from
|
||||
ipa_pure_const. This pass is effective when executed together with
|
||||
other optimization passes in early optimization pass queue. */
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_nothrow =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"nothrow", /* name */
|
||||
OPTGROUP_NONE, /* optinfo_flags */
|
||||
TV_IPA_PURE_CONST, /* tv_id */
|
||||
0, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_nothrow : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_nothrow (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_nothrow, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
opt_pass * clone () { return new pass_nothrow (m_ctxt); }
|
||||
virtual bool gate (function *) { return optimize; }
|
||||
virtual unsigned int execute (function *);
|
||||
|
||||
}; // class pass_nothrow
|
||||
|
||||
unsigned int
|
||||
pass_nothrow::execute (function *)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
basic_block this_block;
|
||||
|
||||
if (TREE_NOTHROW (current_function_decl))
|
||||
return 0;
|
||||
|
||||
node = cgraph_node::get (current_function_decl);
|
||||
|
||||
/* We run during lowering, we can not really use availability yet. */
|
||||
if (cgraph_node::get (current_function_decl)->get_availability ()
|
||||
<= AVAIL_INTERPOSABLE)
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Function is interposable;"
|
||||
" not analyzing.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
FOR_EACH_BB_FN (this_block, cfun)
|
||||
{
|
||||
for (gimple_stmt_iterator gsi = gsi_start_bb (this_block);
|
||||
!gsi_end_p (gsi);
|
||||
gsi_next (&gsi))
|
||||
if (stmt_can_throw_external (gsi_stmt (gsi)))
|
||||
{
|
||||
if (is_gimple_call (gsi_stmt (gsi)))
|
||||
{
|
||||
tree callee_t = gimple_call_fndecl (gsi_stmt (gsi));
|
||||
if (callee_t && recursive_call_p (current_function_decl,
|
||||
callee_t))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "Statement can throw: ");
|
||||
print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
node->set_nothrow_flag (true);
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Function found to be nothrow: %s\n",
|
||||
current_function_name ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
make_pass_nothrow (gcc::context *ctxt)
|
||||
{
|
||||
return new pass_nothrow (ctxt);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
NEXT_PASS (pass_build_ssa);
|
||||
NEXT_PASS (pass_ubsan);
|
||||
NEXT_PASS (pass_early_warn_uninitialized);
|
||||
NEXT_PASS (pass_nothrow);
|
||||
POP_INSERT_PASSES ()
|
||||
|
||||
NEXT_PASS (pass_chkp_instrumentation_passes);
|
||||
|
|
|
@ -436,6 +436,7 @@ extern gimple_opt_pass *make_pass_remove_cgraph_callee_edges (gcc::context
|
|||
*ctxt);
|
||||
extern gimple_opt_pass *make_pass_build_cgraph_edges (gcc::context *ctxt);
|
||||
extern gimple_opt_pass *make_pass_local_pure_const (gcc::context *ctxt);
|
||||
extern gimple_opt_pass *make_pass_nothrow (gcc::context *ctxt);
|
||||
extern gimple_opt_pass *make_pass_tracer (gcc::context *ctxt);
|
||||
extern gimple_opt_pass *make_pass_warn_unused_result (gcc::context *ctxt);
|
||||
extern gimple_opt_pass *make_pass_diagnose_tm_blocks (gcc::context *ctxt);
|
||||
|
|
Loading…
Reference in New Issue