aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-05-25 22:34:36 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-05-25 22:34:36 +0000
commit8f4f502fa905d9c6392fab52e91ee91951f92677 (patch)
tree68704a635c87543f5b0b6647ea71731266f962b4 /gcc/tree-inline.c
parentc962b78d00daa18f54b12440a8de1a8d552ab531 (diff)
downloadgcc-8f4f502fa905d9c6392fab52e91ee91951f92677.zip
gcc-8f4f502fa905d9c6392fab52e91ee91951f92677.tar.gz
gcc-8f4f502fa905d9c6392fab52e91ee91951f92677.tar.bz2
function.h (struct function): Add can_throw_non_call_exceptions bit.
* function.h (struct function): Add can_throw_non_call_exceptions bit. * lto-streamer-in.c (input_function): Stream it in. * lto-streamer-out.c (output_function): Stream it out. * function.c (allocate_struct_function): Set it. (expand_function_end): Substitute cfun->can_throw_non_call_exceptions for flag_non_call_exceptions. * cfgbuild.c (control_flow_insn_p): Likewise. (make_edges): Likewise. * cfgexpand.c (expand_stack_alignment): Likewise. * combine.c (distribute_notes): Likewise. * cse.c (cse_extended_basic_block): Likewise. * except.c (insn_could_throw_p): Likewise. * gcse.c (simple_mem): Likewise. * ipa-pure-const.c (check_call): Likewise. (check_stmt ): Likewise. * lower-subreg.c (lower-subreg.c): Likewise. * optabs.c (emit_libcall_block): Likewise. (prepare_cmp_insn): Likewise. * postreload-gcse.c (eliminate_partially_redundant_loads): Likewise. * postreload.c (rest_of_handle_postreload): Likewise. * reload1.c (reload_as_needed): Likewise. (emit_input_reload_insns): Likewise. (emit_output_reload_insns): Likewise. (fixup_abnormal_edges): Likewise. * sel-sched-ir.c (init_global_and_expr_for_insn): Likewise. * store-motion.c (find_moveable_store): Likewise. * tree-eh.c (stmt_could_throw_p): Likewise. (tree_could_throw_p): Likewise. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise. * config/arm/arm.c (arm_expand_prologue): Likewise. (thumb1_expand_prologue): Likewise. * config/rx/rx.md (cbranchsf4): Likewise. (cmpsf): Likewise. * config/s390/s390.c (s390_emit_prologue): Likewise. * tree-inline.c (initialize_cfun): Copy can_throw_non_call_exceptions. (inline_forbidden_into_p): New predicate. (expand_call_inline): Use it to forbid inlining. (tree_can_inline_p): Likewise. From-SVN: r159847
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 342b5a5..697c6bc 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2028,6 +2028,8 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
cfun->stdarg = src_cfun->stdarg;
cfun->dont_save_pending_sizes_p = src_cfun->dont_save_pending_sizes_p;
cfun->after_inlining = src_cfun->after_inlining;
+ cfun->can_throw_non_call_exceptions
+ = src_cfun->can_throw_non_call_exceptions;
cfun->returns_struct = src_cfun->returns_struct;
cfun->returns_pcc_struct = src_cfun->returns_pcc_struct;
cfun->after_tree_profile = src_cfun->after_tree_profile;
@@ -2960,6 +2962,29 @@ inline_forbidden_p (tree fndecl)
return forbidden_p;
}
+/* Return true if CALLEE cannot be inlined into CALLER. */
+
+static bool
+inline_forbidden_into_p (tree caller, tree callee)
+{
+ /* Don't inline if the functions have different EH personalities. */
+ if (DECL_FUNCTION_PERSONALITY (caller)
+ && DECL_FUNCTION_PERSONALITY (callee)
+ && (DECL_FUNCTION_PERSONALITY (caller)
+ != DECL_FUNCTION_PERSONALITY (callee)))
+ return true;
+
+ /* Don't inline if the callee can throw non-call exceptions but the
+ caller cannot. */
+ if (DECL_STRUCT_FUNCTION (callee)
+ && DECL_STRUCT_FUNCTION (callee)->can_throw_non_call_exceptions
+ && !(DECL_STRUCT_FUNCTION (caller)
+ && DECL_STRUCT_FUNCTION (caller)->can_throw_non_call_exceptions))
+ return true;
+
+ return false;
+}
+
/* Returns nonzero if FN is a function that does not have any
fundamental inline blocking properties. */
@@ -3622,15 +3647,11 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
cg_edge = cgraph_edge (id->dst_node, stmt);
- /* Don't inline functions with different EH personalities. */
- if (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
- && DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)
- && (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
- != DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)))
+ /* First check that inlining isn't simply forbidden in this case. */
+ if (inline_forbidden_into_p (cg_edge->caller->decl, cg_edge->callee->decl))
goto egress;
- /* Don't try to inline functions that are not well-suited to
- inlining. */
+ /* Don't try to inline functions that are not well-suited to inlining. */
if (!cgraph_inline_p (cg_edge, &reason))
{
/* If this call was originally indirect, we do not want to emit any
@@ -5180,12 +5201,8 @@ tree_can_inline_p (struct cgraph_edge *e)
caller = e->caller->decl;
callee = e->callee->decl;
- /* We cannot inline a function that uses a different EH personality
- than the caller. */
- if (DECL_FUNCTION_PERSONALITY (caller)
- && DECL_FUNCTION_PERSONALITY (callee)
- && (DECL_FUNCTION_PERSONALITY (caller)
- != DECL_FUNCTION_PERSONALITY (callee)))
+ /* First check that inlining isn't simply forbidden in this case. */
+ if (inline_forbidden_into_p (caller, callee))
{
e->inline_failed = CIF_UNSPECIFIED;
gimple_call_set_cannot_inline (e->call_stmt, true);