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)
        {

Reply via email to