#include <c-common.h>
#include "aop.h"
+#include "aop-duplicate.h"
#include "aop-pointcut.h"
//#define PAUSE_ON_START
}
}
+void
+aop_join_on_copy (struct aop_pointcut *pc, int copy, join_callback callback,
+ void *callback_param)
+{
+ aop_assert (pc != NULL && pc->join_on != NULL);
+
+ if (!is_current_func_duplicated ())
+ fatal_error ("(InterAspect) Attempt to use aop_join_on_copy() to join on a"
+ " function that was not duplicated.");
+
+ pc->join_on_copy (pc, copy, callback, callback_param);
+
+ /* Call regimplification only if the pointcut needs it */
+ if (pc->need_regimplification) {
+ regimplify();
+ pc->need_regimplification = false;
+ }
+}
+
/* Store a list of all struct opt_pass objects we create so that we
can free them at cleanup time. */
typedef struct opt_pass *aop_pass;
}
}
+static void
+op_join_on_copy_assign (struct aop_pointcut *pc, int copy, join_callback cb,
+ void *callback_param)
+{
+ /* Not yet supported. */
+ aop_assert(0);
+}
+
/**
* Include compiler-created temporary variables in an assignment
* pointcut.
pc = create_pointcut (ATP_ASSIGN);
pc->join_on = op_join_on_assign;
+ pc->join_on_copy = op_join_on_copy_assign;
pc->prepare_for_weave = op_prepare_assign;
pc->pc_assign.type = type;
cb (&jp, callback_param);
}
+static void
+op_join_on_copy_function_entry (struct aop_pointcut *pc, int copy,
+ join_callback cb, void *callback_param)
+{
+ /* Not yet supported. */
+ aop_assert(0);
+}
+
/* There is no GIMPLE statement that is suitable as an anchor point
for inserting advice at the beginning of a function.
pc = create_pointcut (ATP_ENTRY);
pc->join_on = op_join_on_function_entry;
+ pc->join_on_copy = op_join_on_copy_function_entry;
pc->prepare_for_weave = op_prepare_entry;
pc->pc_entry.function_name = NULL;
}
}
+static void
+op_join_on_copy_function_exit (struct aop_pointcut *pc, int copy,
+ join_callback cb, void *callback_param)
+{
+ /* Not yet supported. */
+ aop_assert(0);
+}
+
/* Prepare for an insert at a function entry join point.
Attempting to insert an advice call _after_ a return statement
pc = create_pointcut (ATP_EXIT);
pc->join_on = op_join_on_function_exit;
+ pc->join_on_copy = op_join_on_copy_function_exit;
pc->prepare_for_weave = op_prepare_exit;
return pc;
#include <string.h>
#include "aop.h"
+#include "aop-duplicate.h"
+#include "aop-dynval.h"
#include "aop-pointcut.h"
#include "aop-type.h"
-#include "aop-dynval.h"
/**
* \defgroup call_pc Function Call Pointcut Functions
}
static void
-op_join_on_function_call (struct aop_pointcut *pc, join_callback cb,
- void *callback_param)
+join_on_bb_function_call (basic_block bb, struct aop_pointcut *pc,
+ join_callback cb, void *callback_param)
{
- basic_block my_basic_block;
gimple_stmt_iterator gsi;
- aop_assert (pc->kind == ATP_CALL);
-
- FOR_EACH_BB(my_basic_block)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- for (gsi = gsi_start_bb (my_basic_block) ; !gsi_end_p (gsi) ;
- gsi_next (&gsi))
+ gimple stmt = gsi_stmt (gsi);
+
+ /* At this stage, there should be no GIMPLE statements with
+ sub-statements. */
+ gcc_assert(!gimple_has_substatements (stmt));
+
+ if (gimple_code (stmt) == GIMPLE_CALL)
{
- gimple stmt = gsi_stmt (gsi);
-
- /* At this stage, there should be no GIMPLE statements with
- sub-statements. */
- gcc_assert(!gimple_has_substatements (stmt));
-
- if (gimple_code (stmt) == GIMPLE_CALL)
- {
- if (call_matches (pc, stmt))
- {
- struct aop_joinpoint jp;
- init_joinpoint (&jp, &gsi, pc, stmt);
- cb (&jp, callback_param);
- }
+ if (call_matches (pc, stmt))
+ {
+ struct aop_joinpoint jp;
+ init_joinpoint (&jp, &gsi, pc, stmt);
+ cb (&jp, callback_param);
}
}
}
}
+static void
+op_join_on_function_call (struct aop_pointcut *pc, join_callback cb,
+ void *callback_param)
+{
+ basic_block bb;
+
+ aop_assert (pc->kind == ATP_CALL);
+
+ FOR_EACH_BB(bb)
+ {
+ join_on_bb_function_call (bb, pc, cb, callback_param);
+ }
+}
+
+static void
+op_join_on_copy_function_call (struct aop_pointcut *pc, int copy,
+ join_callback cb, void *callback_param)
+{
+ unsigned int pair_index;
+ bb_pair *pair;
+
+ aop_assert (is_current_func_duplicated ());
+ aop_assert (pc->kind == ATP_CALL);
+
+ FOR_EACH_BB_PAIR (bb_pairs, pair_index, pair)
+ {
+ basic_block bb = (copy == 0) ? pair->old : pair->new;
+
+ join_on_bb_function_call (bb, pc, cb, callback_param);
+ }
+}
+
/**
* Return a pointcut that matches all function calls. Use filter
* functions on the resulting pointcut to produce a pointcut that
pc = create_pointcut (ATP_CALL);
pc->join_on = op_join_on_function_call;
+ pc->join_on_copy = op_join_on_copy_function_call;
pc->pc_call.function_name = NULL;
pc->pc_call.return_type = NULL;
enum aop_pckind kind;
void (*join_on) (struct aop_pointcut *, join_callback, void *);
+ void (*join_on_copy) (struct aop_pointcut *, int copy, join_callback, void *);
insert_callback insert_before;
insert_callback insert_after;
-
/* prepare_for_weave() gets called once for each joinpoint before
any advice gets inserted at that joinpoint. */
void (*prepare_for_weave) (struct aop_joinpoint *);
extern void aop_register_pass (const char *pass_name, pass_callback callback);
extern void aop_join_on (struct aop_pointcut *pc, join_callback callback,
void *callback_param);
+extern void aop_join_on_copy (struct aop_pointcut *pc, int copy,
+ join_callback callback, void *callback_param);
extern void aop_main ();
extern void aop_abort (const char *filename, int lineno, const char *function)