summaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-10 18:07:31 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-10 18:07:31 +0000
commitfe34354e72b674130ffcf5a67e2d0b3b7307383e (patch)
treeca6f19ee04949a3bcd2ab0374a056dcb46fc2056 /gcc/tree-inline.c
parent8b3716ff7532ddf9cb6f3ae6beac038506b70941 (diff)
parentbf62ed7307453c4f8d35c952fba2c2a5d990b1a4 (diff)
downloadgcc-fe34354e72b674130ffcf5a67e2d0b3b7307383e.tar.gz
Merge in trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@207666 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 44ae34c4c47..3fd56f124e5 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1743,7 +1743,6 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
if (is_gimple_call (stmt))
{
struct cgraph_edge *edge;
- int flags;
switch (id->transform_call_graph_edges)
{
@@ -1866,11 +1865,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
}
}
- flags = gimple_call_flags (stmt);
- if (flags & ECF_MAY_BE_ALLOCA)
- cfun->calls_alloca = true;
- if (flags & ECF_RETURNS_TWICE)
- cfun->calls_setjmp = true;
+ notice_special_calls (stmt);
}
maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt,
@@ -1965,7 +1960,7 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
static bool
copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb,
- bool can_make_abnormal_goto)
+ basic_block abnormal_goto_dest)
{
basic_block new_bb = (basic_block) bb->aux;
edge_iterator ei;
@@ -2019,7 +2014,9 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb,
into a COMPONENT_REF which doesn't. If the copy
can throw, the original could also throw. */
can_throw = stmt_can_throw_internal (copy_stmt);
- nonlocal_goto = stmt_can_make_abnormal_goto (copy_stmt);
+ nonlocal_goto
+ = (stmt_can_make_abnormal_goto (copy_stmt)
+ && !computed_goto_p (copy_stmt));
if (can_throw || nonlocal_goto)
{
@@ -2050,9 +2047,26 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb,
/* If the call we inline cannot make abnormal goto do not add
additional abnormal edges but only retain those already present
in the original function body. */
- nonlocal_goto &= can_make_abnormal_goto;
+ if (abnormal_goto_dest == NULL)
+ nonlocal_goto = false;
if (nonlocal_goto)
- make_abnormal_goto_edges (gimple_bb (copy_stmt), true);
+ {
+ basic_block copy_stmt_bb = gimple_bb (copy_stmt);
+
+ if (get_abnormal_succ_dispatcher (copy_stmt_bb))
+ nonlocal_goto = false;
+ /* ABNORMAL_DISPATCHER (1) is for longjmp/setjmp or nonlocal gotos
+ in OpenMP regions which aren't allowed to be left abnormally.
+ So, no need to add abnormal edge in that case. */
+ else if (is_gimple_call (copy_stmt)
+ && gimple_call_internal_p (copy_stmt)
+ && (gimple_call_internal_fn (copy_stmt)
+ == IFN_ABNORMAL_DISPATCHER)
+ && gimple_call_arg (copy_stmt, 0) == boolean_true_node)
+ nonlocal_goto = false;
+ else
+ make_edge (copy_stmt_bb, abnormal_goto_dest, EDGE_ABNORMAL);
+ }
if ((can_throw || nonlocal_goto)
&& gimple_in_ssa_p (cfun))
@@ -2491,13 +2505,22 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
last = last_basic_block_for_fn (cfun);
/* Now that we've duplicated the blocks, duplicate their edges. */
- bool can_make_abormal_goto
- = id->gimple_call && stmt_can_make_abnormal_goto (id->gimple_call);
+ basic_block abnormal_goto_dest = NULL;
+ if (id->gimple_call
+ && stmt_can_make_abnormal_goto (id->gimple_call))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (id->gimple_call);
+
+ bb = gimple_bb (id->gimple_call);
+ gsi_next (&gsi);
+ if (gsi_end_p (gsi))
+ abnormal_goto_dest = get_abnormal_succ_dispatcher (bb);
+ }
FOR_ALL_BB_FN (bb, cfun_to_copy)
if (!id->blocks_to_copy
|| (bb->index > 0 && bitmap_bit_p (id->blocks_to_copy, bb->index)))
need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map,
- can_make_abormal_goto);
+ abnormal_goto_dest);
if (new_entry)
{
@@ -4114,7 +4137,8 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
/* During early inline pass, report only when optimization is
not turned on. */
&& (cgraph_global_info_ready
- || !optimize)
+ || !optimize
+ || cgraph_inline_failed_type (reason) == CIF_FINAL_ERROR)
/* PR 20090218-1_0.c. Body can be provided by another module. */
&& (reason != CIF_BODY_NOT_AVAILABLE || !flag_generate_lto))
{