On 04 Jun 01:15, Jeff Law wrote:
> On 06/03/14 01:10, Ilya Enkovich wrote:
> >Hi,
> >
> >This patch does not allow splitting in case bounds are returned until 
> >retutrned bounds are supported.  It also propagates instrumentation marks 
> >for generated call and function.
> >
> >Bootstrapped and tested on linux-x86_64.
> >
> >Thanks,
> >Ilya
> >--
> >gcc/
> >
> >2014-06-03  Ilya Enkovich  <ilya.enkov...@intel.com>
> >
> >     * ipa-split.c: Include tree-chkp.h.
> >     (consider_split): Do not split when return bounds.
> >     (split_function): Propagate Pointer Bounds Checker
> >     instrumentation marks.
> It's a hack.  There's no reason we can't support this.  So I'll
> approve on the condition that you do look at removing this
> limitation in the future.
> 
> jeff
> 

I did some work for function splitting and now patch cover more cases.  Now 
returned bounds are supported but it is not allowed to split producers of 
returned pointer and its bounds.  Is it OK?

Thanks,
Ilya
--
2014-08-15  Ilya Enkovich  <ilya.enkov...@intel.com>

        * ipa-split.c: Include tree-chkp.h.
        (find_retbnd): New.
        (consider_split): Do not split retbnd and retval
        producers.
        (split_function): Propagate Pointer Bounds Checker
        instrumentation marks and handle returned bounds.


diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 2af3a93..f8ecaf7 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
+#include "tree-chkp.h"
 
 /* Per basic block info.  */
 
@@ -151,6 +152,7 @@ struct split_point best_split_point;
 static bitmap forbidden_dominators;
 
 static tree find_retval (basic_block return_bb);
+static tree find_retbnd (basic_block return_bb);
 
 /* Callback for walk_stmt_load_store_addr_ops.  If T is non-SSA automatic
    variable, check it if it is present in bitmap passed via DATA.  */
@@ -387,6 +389,7 @@ consider_split (struct split_point *current, bitmap 
non_ssa_vars,
   unsigned int i;
   int incoming_freq = 0;
   tree retval;
+  tree retbnd;
   bool back_edge = false;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -588,6 +591,32 @@ consider_split (struct split_point *current, bitmap 
non_ssa_vars,
   else
     current->split_part_set_retval = true;
 
+  /* See if retbnd used by return bb is computed by header or split part.  */
+  retbnd = find_retbnd (return_bb);
+  if (retbnd)
+    {
+      bool split_part_set_retbnd
+       = (!SSA_NAME_IS_DEFAULT_DEF (retbnd)
+          && (bitmap_bit_p (current->split_bbs,
+                            gimple_bb (SSA_NAME_DEF_STMT (retbnd))->index)
+              || gimple_bb (SSA_NAME_DEF_STMT (retbnd)) == return_bb));
+
+      /* If we have both return value and bounds then keep their definitions
+        in a single function.  We use SSA names to link returned bounds and
+        value and therefore do not handle cases when result is passed by
+        reference (which should not be our case anyway since bounds are
+        returned for pointers only).  */
+      if ((DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))
+          && current->split_part_set_retval)
+         || split_part_set_retbnd != current->split_part_set_retval)
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           fprintf (dump_file,
+                    "  Refused: split point splits return value and bounds\n");
+         return;
+       }
+    }
+
   /* split_function fixes up at most one PHI non-virtual PHI node in return_bb,
      for the return value.  If there are other PHIs, give up.  */
   if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
@@ -710,6 +739,18 @@ find_retval (basic_block return_bb)
   return NULL;
 }
 
+/* Given return basic block RETURN_BB, see where return bounds are really
+   stored.  */
+static tree
+find_retbnd (basic_block return_bb)
+{
+  gimple_stmt_iterator bsi;
+  for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi); gsi_next (&bsi))
+    if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN)
+      return gimple_return_retbnd (gsi_stmt (bsi));
+  return NULL;
+}
+
 /* Callback for walk_stmt_load_store_addr_ops.  If T is non-SSA automatic
    variable, mark it as used in bitmap passed via DATA.
    Return true when access to T prevents splitting the function.  */
@@ -1095,8 +1136,9 @@ split_function (struct split_point *split_point)
   gimple call;
   edge e;
   edge_iterator ei;
-  tree retval = NULL, real_retval = NULL;
+  tree retval = NULL, real_retval = NULL, retbnd = NULL;
   bool split_part_return_p = false;
+  bool with_bounds = chkp_function_instrumented_p (current_function_decl);
   gimple last_stmt = NULL;
   unsigned int i;
   tree arg, ddef;
@@ -1245,6 +1287,12 @@ split_function (struct split_point *split_point)
       DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN;
       DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0;
     }
+
+  /* If the original function is instrumented then it's
+     part is also instrumented.  */
+  if (with_bounds)
+    chkp_function_mark_instrumented (node->decl);
+
   /* If the original function is declared inline, there is no point in issuing
      a warning for the non-inlinable part.  */
   DECL_NO_INLINE_WARNING_P (node->decl) = 1;
@@ -1279,6 +1327,7 @@ split_function (struct split_point *split_point)
        args_to_pass[i] = arg;
       }
   call = gimple_build_call_vec (node->decl, args_to_pass);
+  gimple_call_set_with_bounds (call, with_bounds);
   gimple_set_block (call, DECL_INITIAL (current_function_decl));
   args_to_pass.release ();
 
@@ -1385,6 +1434,7 @@ split_function (struct split_point *split_point)
       if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
        {
          real_retval = retval = find_retval (return_bb);
+         retbnd = find_retbnd (return_bb);
 
          if (real_retval && split_point->split_part_set_retval)
            {
@@ -1429,6 +1479,21 @@ split_function (struct split_point *split_point)
                          }
                      update_stmt (gsi_stmt (bsi));
                    }
+
+                 /* Replace retbnd with new one.  */
+                 if (retbnd)
+                   {
+                     gimple_stmt_iterator bsi;
+                     for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi);
+                          gsi_next (&bsi))
+                       if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN)
+                         {
+                           retbnd = copy_ssa_name (retbnd, call);
+                           gimple_return_set_retbnd (gsi_stmt (bsi), retbnd);
+                           update_stmt (gsi_stmt (bsi));
+                           break;
+                         }
+                   }
                }
              if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
                {
@@ -1450,6 +1515,15 @@ split_function (struct split_point *split_point)
                      gsi_insert_after (&gsi, cpy, GSI_NEW_STMT);
                      retval = tem;
                    }
+                 /* Build bndret call to obtain returned bounds.  */
+                 if (retbnd)
+                   {
+                     tree fndecl
+                       = targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDRET);
+                     gimple bndret = gimple_build_call (fndecl, 1, retval);
+                     gimple_call_set_lhs (bndret, retbnd);
+                     gsi_insert_after (&gsi, bndret, GSI_NEW_STMT);
+                   }
                  gimple_call_set_lhs (call, retval);
                  update_stmt (call);
                }
@@ -1468,6 +1542,10 @@ split_function (struct split_point *split_point)
            {
              retval = DECL_RESULT (current_function_decl);
 
+             if (chkp_function_instrumented_p (current_function_decl)
+                 && BOUNDED_P (retval))
+               retbnd = create_tmp_reg (pointer_bounds_type_node, NULL);
+
              /* We use temporary register to hold value when aggregate_value_p
                 is false.  Similarly for DECL_BY_REFERENCE we must avoid extra
                 copy.  */
@@ -1491,6 +1569,15 @@ split_function (struct split_point *split_point)
                gimple_call_set_lhs (call, retval);
            }
           gsi_insert_after (&gsi, call, GSI_NEW_STMT);
+         /* Build bndret call to obtain returned bounds.  */
+         if (retbnd)
+           {
+             tree fndecl
+               = targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDRET);
+             gimple bndret = gimple_build_call (fndecl, 1, retval);
+             gimple_call_set_lhs (bndret, retbnd);
+             gsi_insert_after (&gsi, bndret, GSI_NEW_STMT);
+           }
          ret = gimple_build_return (retval);
          gsi_insert_after (&gsi, ret, GSI_NEW_STMT);
        }

Reply via email to