Added in_param filtering to all pointcuts.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 23 Sep 2010 22:28:26 +0000 (18:28 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 23 Sep 2010 22:28:26 +0000 (18:28 -0400)
src/aop-main.c
src/aop-pc-entry.c
src/aop-pointcut.c
src/aop.h
test/plugin-inparam.c

index 89210f8fc8f4e7712839b4fc5f149fb7079337b9..c69fb0c46b59b20b673cb6987cfa2e6184e652d1 100644 (file)
@@ -109,6 +109,11 @@ aop_join_on (struct aop_pointcut *pc, join_callback callback,
 {
   aop_assert (pc != NULL && pc->join_on != NULL);
 
+  /* Filtering on in_params is universal across a function.  Either
+     every join point in the function match or none do.*/
+  if (!check_in_params (pc))
+    return;
+
   pc->join_on (pc, callback, callback_param);
 
   /* Call regimplification only if the pointcut needs it */
@@ -148,6 +153,11 @@ aop_join_on_copy (struct aop_pointcut *pc, int copy, join_callback callback,
     fatal_error ("(InterAspect) Attempt to use aop_join_on_copy() to join on a"
                 " function that was not duplicated.");
 
+  /* Filtering on in_params is universal across a function.  Either
+     every join point in the function match or none do.*/
+  if (!check_in_params (pc))
+    return;
+
   pc->join_on_copy (pc, copy, callback, callback_param);
 
   /* Call regimplification only if the pointcut needs it */
index 49157fc43717c885d4aed26b76fcb55d05e88033..2fa9bad3398cc1f67d6c6ae1e129de3c4b3cb1ed 100644 (file)
@@ -87,7 +87,6 @@ is_function_entry_matching (struct aop_pointcut *pc)
        IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
       return (strcmp (func_name, pc->pc_entry.function_name) == 0);
     }
-  return check_in_params (pc);
 }
 
 /* We represent the function's entry as a control-flow graph edge.
@@ -212,54 +211,6 @@ void aop_filter_entry_by_name(struct aop_pointcut *pc_function_entry,
   pc_function_entry->pc_entry.function_name = advice_function_entry;
 }
 
-/**
- * Filter a function entry pointcut to only include function entries
- * with a parameter that matches a specified type.  This filter removes join
- * points when parameter n does not match type or when there is no
- * parameter n.
- *
- * Filters on the same parameter do not stack on top of each other.
- * If multiple parameter filters with the same n are applied a
- * pointcut, only the last one will have any effect.
- *
- * Note that you must filter a parameter by its type in order to
- * capture it with aop_capture_in_param().
- * \param pc The function call pointcut to filter.  Function entry
- * pointcuts are created with aop_match_function_entry().
- * \param n The index of the parameter to filter on.  Parameters are
- * indexed from zero.
- * \param The parameter type to filter by.
- */
-void
-aop_filter_entry_by_in_param (struct aop_pointcut *pc, int n,
-                            const struct aop_type *type)
-{
-  struct aop_param_desc *param = NULL;
-  struct aop_param_desc *iter;
-  /* Is there already a filter for this parameter? */
-  for (iter = pc->in_param_list_head ; iter != NULL ; iter = iter->next)
-    {
-      if (iter->param_index == n)
-       {
-         param = iter;
-         break;
-       }
-    }
-
-  /* No? Then create one and add it to the list. */
-  if (param == NULL)
-    {
-      param = ggc_alloc (sizeof (struct aop_param_desc));
-
-      param->next = pc->in_param_list_head;
-      pc->in_param_list_head = param;
-    }
-
-  param->param_index = n;
-  param->type = type;
-}
-
 /* Close Doxygen defgroup block. */
 /**
  * \}
index ea4cfbcb546b61dbff98d8a2184d3f9f3d90b521..c4f23e144ec7316134dd7e1efdef631fbac1e34a 100644 (file)
@@ -67,7 +67,6 @@ init_joinpoint (struct aop_joinpoint *jp, gimple_stmt_iterator *gsi,
   jp->file = file;
   jp->in_edge = NULL;
   jp->is_prepared = false;
-  
 }
 
 int
@@ -82,6 +81,32 @@ aop_capture_file_name (struct aop_joinpoint *jp)
   return jp->file;
 }
 
+/* Sometimes we want to capture a parameter some place that is not at
+   the beginning of the function.  The parameter may change during the
+   function, so we save its value at function start to preserve it
+   until we need it.
+
+   Returns the temporary variable holding the preserved parameter
+   value.  */
+static tree
+save_param(tree param)
+{
+  edge in_edge;
+  tree tmp_val;
+  gimple new_assign;
+
+  aop_assert (TREE_CODE (param) == PARM_DECL);
+
+  tmp_val = create_tmp_var (TREE_TYPE (param), "ia_preserved_param");
+  new_assign = gimple_build_assign (tmp_val, stabilize_reference (param));
+
+  /* Insert the assignment at the very beginning of the function. */
+  in_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun));
+  gsi_insert_on_edge_immediate (in_edge, new_assign);
+
+  return tmp_val;
+}
+
 static tree
 op_get_in_param (struct aop_dynval *dv)
 {
@@ -92,7 +117,6 @@ op_get_in_param (struct aop_dynval *dv)
   int index = 0;
 
   aop_assert (dv->kind == ADV_FUN_PARAM);
-  aop_assert (jp->pc->kind == ATP_ENTRY);
 
   stmt = jp->stmt;
   
@@ -101,8 +125,7 @@ op_get_in_param (struct aop_dynval *dv)
     {
       if (index == dv->dynval_in_param.param_index)
        {
-         param = param_iter;
-         param = stabilize_reference (param);
+         param = save_param (param_iter);
          break;
        }
       index++;       
@@ -132,9 +155,6 @@ aop_capture_in_param (struct aop_joinpoint *jp, int n)
   struct aop_param_desc *param;
 
   pc = jp->pc;
-  if (pc->kind != ATP_ENTRY)
-    fatal_error ("(InterAspect) Attempt to capture parameter from an"
-                " unsupported join point.");
 
   /* Search for an aop_param_desc for this parameter, so that we know
      its type. */
@@ -197,3 +217,52 @@ check_in_params (struct aop_pointcut *pc)
 
   return true;
 }
+
+/**
+ * Filter a function entry pointcut to only include function entries
+ * with a parameter that matches a specified type.  This filter removes join
+ * points when parameter n does not match type or when there is no
+ * parameter n.
+ *
+ * Filters on the same parameter do not stack on top of each other.
+ * If multiple parameter filters with the same n are applied a
+ * pointcut, only the last one will have any effect.
+ *
+ * Note that you must filter a parameter by its type in order to
+ * capture it with aop_capture_in_param().
+ * \param pc The function call pointcut to filter.  Function entry
+ * pointcuts are created with aop_match_function_entry().
+ * \param n The index of the parameter to filter on.  Parameters are
+ * indexed from zero.
+ * \param The parameter type to filter by.
+ */
+void
+aop_filter_by_in_param (struct aop_pointcut *pc, int n,
+                       const struct aop_type *type)
+{
+  struct aop_param_desc *param = NULL;
+  struct aop_param_desc *iter;
+  /* Is there already a filter for this parameter? */
+  for (iter = pc->in_param_list_head ; iter != NULL ; iter = iter->next)
+    {
+      if (iter->param_index == n)
+       {
+         param = iter;
+         break;
+       }
+    }
+
+  /* No? Then create one and add it to the list. */
+  if (param == NULL)
+    {
+      param = ggc_alloc (sizeof (struct aop_param_desc));
+
+      param->next = pc->in_param_list_head;
+      pc->in_param_list_head = param;
+    }
+
+  param->param_index = n;
+  param->type = type;
+}
+
index 2e5393dbb084ec70943f2b99a76b071f496033e1..b59b76b6f07a51d29d29c84d57deca4283900dae 100644 (file)
--- a/src/aop.h
+++ b/src/aop.h
@@ -254,8 +254,8 @@ enum aop_argkind {
 extern const char *aop_capture_function_name (struct aop_joinpoint *jp);
 
 extern struct aop_pointcut *aop_match_function_entry ();
-extern void aop_filter_entry_by_in_param (struct aop_pointcut *pc, int n,
-                                        const struct aop_type *type);
+extern void aop_filter_by_in_param (struct aop_pointcut *pc, int n,
+                                   const struct aop_type *type);
 extern struct aop_dynval *aop_capture_in_param (struct aop_joinpoint *jp,
                                             int param_index);
 
index bb083819222d14199cc194cd2059fe864b57faa5..0d83cf50b9a7102fe007cc7be106827aa829c180 100644 (file)
@@ -21,8 +21,8 @@ static unsigned int plugin_int()
 
   pc = aop_match_function_entry();
   aop_filter_entry_by_name(pc, "foo");
-  aop_filter_entry_by_in_param(pc, 0, aop_t_all_signed());
-  aop_filter_entry_by_in_param(pc, 1, aop_t_all_fp());
+  aop_filter_by_in_param(pc, 0, aop_t_all_signed());
+  aop_filter_by_in_param(pc, 1, aop_t_all_fp());
   aop_join_on(pc, plugin_join_on_call, "_advice_foo");
 
   return 0;