Hi, This patch adds instrumented code support for strlen optimization.
Bootstrapped and tested on linux-x86_64. Does it look OK? Thanks, Ilya -- gcc/ 2014-06-09 Ilya Enkovich <ilya.enkov...@intel.com> * tree-ssa-strlen.c: include tree-chkp.h. (get_string_length): Handle calls with bounds. (adjust_last_stmt): Likewise. (handle_builtin_strchr): Likewise. (handle_builtin_strcpy): Likewise. (handle_builtin_memcpy): Likewise. (handle_builtin_strcat): Likewise. diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index f55b7ee..959b376 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "params.h" #include "expr.h" +#include "tree-chkp.h" /* A vector indexed by SSA_NAME_VERSION. 0 means unknown, positive value is an index into strinfo vector, negative value stands for @@ -426,6 +427,7 @@ get_string_length (strinfo si) if (si->stmt) { gimple stmt = si->stmt, lenstmt; + bool with_bounds = gimple_call_with_bounds_p (stmt); tree callee, lhs, fn, tem; location_t loc; gimple_stmt_iterator gsi; @@ -449,7 +451,14 @@ get_string_length (strinfo si) fn = builtin_decl_implicit (BUILT_IN_STRLEN); gcc_assert (lhs == NULL_TREE); tem = unshare_expr (gimple_call_arg (stmt, 0)); - lenstmt = gimple_build_call (fn, 1, tem); + if (with_bounds) + { + lenstmt = gimple_build_call (chkp_maybe_create_clone (fn)->decl, + 2, tem, gimple_call_arg (stmt, 1)); + gimple_call_set_with_bounds (lenstmt, true); + } + else + lenstmt = gimple_build_call (fn, 1, tem); lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), lenstmt); gimple_call_set_lhs (lenstmt, lhs); gimple_set_vuse (lenstmt, gimple_vuse (stmt)); @@ -472,10 +481,12 @@ get_string_length (strinfo si) /* FALLTHRU */ case BUILT_IN_STRCPY: case BUILT_IN_STRCPY_CHK: - if (gimple_call_num_args (stmt) == 2) + if (gimple_call_num_args (stmt) == (with_bounds ? 4 : 2)) fn = builtin_decl_implicit (BUILT_IN_STPCPY); else fn = builtin_decl_explicit (BUILT_IN_STPCPY_CHK); + if (with_bounds) + fn = chkp_maybe_create_clone (fn)->decl; gcc_assert (lhs == NULL_TREE); if (dump_file && (dump_flags & TDF_DETAILS) != 0) { @@ -780,6 +791,7 @@ adjust_last_stmt (strinfo si, gimple stmt, bool is_strcat) tree vuse, callee, len; struct laststmt_struct last = laststmt; strinfo lastsi, firstsi; + unsigned len_arg_no = 2; laststmt.stmt = NULL; laststmt.len = NULL_TREE; @@ -855,7 +867,9 @@ adjust_last_stmt (strinfo si, gimple stmt, bool is_strcat) return; } - len = gimple_call_arg (last.stmt, 2); + if (gimple_call_with_bounds_p (last.stmt)) + len_arg_no = 4; + len = gimple_call_arg (last.stmt, len_arg_no); if (tree_fits_uhwi_p (len)) { if (!tree_fits_uhwi_p (last.len) @@ -879,7 +893,7 @@ adjust_last_stmt (strinfo si, gimple stmt, bool is_strcat) else return; - gimple_call_set_arg (last.stmt, 2, last.len); + gimple_call_set_arg (last.stmt, len_arg_no, last.len); update_stmt (last.stmt); } @@ -970,11 +984,12 @@ handle_builtin_strchr (gimple_stmt_iterator *gsi) tree src; gimple stmt = gsi_stmt (*gsi); tree lhs = gimple_call_lhs (stmt); + bool with_bounds = gimple_call_with_bounds_p (stmt); if (lhs == NULL_TREE) return; - if (!integer_zerop (gimple_call_arg (stmt, 1))) + if (!integer_zerop (gimple_call_arg (stmt, with_bounds ? 2 : 1))) return; src = gimple_call_arg (stmt, 0); @@ -1081,8 +1096,9 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi) gimple stmt = gsi_stmt (*gsi); strinfo si, dsi, olddsi, zsi; location_t loc; + bool with_bounds = gimple_call_with_bounds_p (stmt); - src = gimple_call_arg (stmt, 1); + src = gimple_call_arg (stmt, with_bounds ? 2 : 1); dst = gimple_call_arg (stmt, 0); lhs = gimple_call_lhs (stmt); idx = get_stridx (src); @@ -1268,14 +1284,33 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi) fprintf (dump_file, "Optimizing: "); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); } - if (gimple_call_num_args (stmt) == 2) - success = update_gimple_call (gsi, fn, 3, dst, src, len); + if (with_bounds) + { + fn = chkp_maybe_create_clone (fn)->decl; + if (gimple_call_num_args (stmt) == 4) + success = update_gimple_call (gsi, fn, 5, dst, + gimple_call_arg (stmt, 1), + src, + gimple_call_arg (stmt, 3), + len); + else + success = update_gimple_call (gsi, fn, 6, dst, + gimple_call_arg (stmt, 1), + src, + gimple_call_arg (stmt, 3), + len, + gimple_call_arg (stmt, 4)); + } else - success = update_gimple_call (gsi, fn, 4, dst, src, len, - gimple_call_arg (stmt, 2)); + if (gimple_call_num_args (stmt) == 2) + success = update_gimple_call (gsi, fn, 3, dst, src, len); + else + success = update_gimple_call (gsi, fn, 4, dst, src, len, + gimple_call_arg (stmt, 2)); if (success) { stmt = gsi_stmt (*gsi); + gimple_call_set_with_bounds (stmt, with_bounds); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS) != 0) { @@ -1303,9 +1338,10 @@ handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi) tree src, dst, len, lhs, oldlen, newlen; gimple stmt = gsi_stmt (*gsi); strinfo si, dsi, olddsi; + bool with_bounds = gimple_call_with_bounds_p (stmt); - len = gimple_call_arg (stmt, 2); - src = gimple_call_arg (stmt, 1); + len = gimple_call_arg (stmt, with_bounds ? 4 : 2); + src = gimple_call_arg (stmt, with_bounds ? 2 : 1); dst = gimple_call_arg (stmt, 0); idx = get_stridx (src); if (idx == 0) @@ -1442,8 +1478,9 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi) gimple stmt = gsi_stmt (*gsi); strinfo si, dsi; location_t loc; + bool with_bounds = gimple_call_with_bounds_p (stmt); - src = gimple_call_arg (stmt, 1); + src = gimple_call_arg (stmt, with_bounds ? 2 : 1); dst = gimple_call_arg (stmt, 0); lhs = gimple_call_lhs (stmt); @@ -1549,7 +1586,7 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi) fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK); else fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK); - objsz = gimple_call_arg (stmt, 2); + objsz = gimple_call_arg (stmt, with_bounds ? 4 : 2); break; default: gcc_unreachable (); @@ -1584,15 +1621,35 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi) fprintf (dump_file, "Optimizing: "); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); } - if (srclen != NULL_TREE) - success = update_gimple_call (gsi, fn, 3 + (objsz != NULL_TREE), - dst, src, len, objsz); + if (with_bounds) + { + fn = chkp_maybe_create_clone (fn)->decl; + if (srclen != NULL_TREE) + success = update_gimple_call (gsi, fn, 5 + (objsz != NULL_TREE), + dst, + gimple_call_arg (stmt, 1), + src, + gimple_call_arg (stmt, 3), + len, objsz); + else + success = update_gimple_call (gsi, fn, 4 + (objsz != NULL_TREE), + dst, + gimple_call_arg (stmt, 1), + src, + gimple_call_arg (stmt, 3), + objsz); + } else - success = update_gimple_call (gsi, fn, 2 + (objsz != NULL_TREE), - dst, src, objsz); + if (srclen != NULL_TREE) + success = update_gimple_call (gsi, fn, 3 + (objsz != NULL_TREE), + dst, src, len, objsz); + else + success = update_gimple_call (gsi, fn, 2 + (objsz != NULL_TREE), + dst, src, objsz); if (success) { stmt = gsi_stmt (*gsi); + gimple_call_set_with_bounds (stmt, with_bounds); update_stmt (stmt); if (dump_file && (dump_flags & TDF_DETAILS) != 0) {