diff options
Diffstat (limited to 'gcc/value-prof.c')
-rw-r--r-- | gcc/value-prof.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 0e4ec8a..1b203e8 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "tree-nested.h" #include "params.h" +#include "tree-chkp.h" /* In this file value profile based optimizations are placed. Currently the following optimizations are implemented (for more detailed descriptions @@ -1382,7 +1383,7 @@ gimple gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, int prob, gcov_type count, gcov_type all) { - gimple dcall_stmt, load_stmt, cond_stmt; + gimple dcall_stmt, load_stmt, cond_stmt, iretbnd_stmt = NULL; tree tmp0, tmp1, tmp; basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL; tree optype = build_pointer_type (void_type_node); @@ -1396,6 +1397,9 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, cond_bb = gimple_bb (icall_stmt); gsi = gsi_for_stmt (icall_stmt); + if (gimple_call_with_bounds_p (icall_stmt) && gimple_call_lhs (icall_stmt)) + iretbnd_stmt = chkp_retbnd_call_by_val (gimple_call_lhs (icall_stmt)); + tmp0 = make_temp_ssa_name (optype, NULL, "PROF"); tmp1 = make_temp_ssa_name (optype, NULL, "PROF"); tmp = unshare_expr (gimple_call_fn (icall_stmt)); @@ -1488,6 +1492,50 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, gimple_call_set_lhs (dcall_stmt, duplicate_ssa_name (result, dcall_stmt)); add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION); + + /* If indirect call has following BUILT_IN_CHKP_BNDRET + call then we need to make it's copy for the direct + call. */ + if (iretbnd_stmt) + { + if (gimple_call_lhs (iretbnd_stmt)) + { + gimple copy; + + gimple_set_vdef (iretbnd_stmt, NULL_TREE); + gimple_set_vuse (iretbnd_stmt, NULL_TREE); + update_stmt (iretbnd_stmt); + + result = gimple_call_lhs (iretbnd_stmt); + phi = create_phi_node (result, join_bb); + + copy = gimple_copy (iretbnd_stmt); + gimple_call_set_arg (copy, 0, + gimple_call_lhs (dcall_stmt)); + gimple_call_set_lhs (copy, duplicate_ssa_name (result, copy)); + gsi_insert_on_edge (e_dj, copy); + add_phi_arg (phi, gimple_call_lhs (copy), + e_dj, UNKNOWN_LOCATION); + + gimple_call_set_arg (iretbnd_stmt, 0, + gimple_call_lhs (icall_stmt)); + gimple_call_set_lhs (iretbnd_stmt, + duplicate_ssa_name (result, iretbnd_stmt)); + psi = gsi_for_stmt (iretbnd_stmt); + gsi_remove (&psi, false); + gsi_insert_on_edge (e_ij, iretbnd_stmt); + add_phi_arg (phi, gimple_call_lhs (iretbnd_stmt), + e_ij, UNKNOWN_LOCATION); + + gsi_commit_one_edge_insert (e_dj, NULL); + gsi_commit_one_edge_insert (e_ij, NULL); + } + else + { + psi = gsi_for_stmt (iretbnd_stmt); + gsi_remove (&psi, true); + } + } } /* Build an EH edge for the direct call if necessary. */ |