aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-prof.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/value-prof.c')
-rw-r--r--gcc/value-prof.c50
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. */