From: Justin Seyster Date: Thu, 12 Aug 2010 22:59:51 +0000 (-0400) Subject: aop_join_on_copy() support for function entry pointcuts. X-Git-Tag: release-v1.0~73^2~3 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=c81e0645518226e994dcec6024e131fb75633e24;p=interaspect.git aop_join_on_copy() support for function entry pointcuts. Added in_edge field to join points to support this feature. --- diff --git a/src/aop-pc-entry.c b/src/aop-pc-entry.c index a3fae6a..cd1179a 100644 --- a/src/aop-pc-entry.c +++ b/src/aop-pc-entry.c @@ -34,6 +34,7 @@ #include #include "aop.h" +#include "aop-duplicate.h" #include "aop-pointcut.h" #include "aop-type.h" @@ -42,23 +43,34 @@ * \{ */ -static void -op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb, - void *callback_param) +/* Function have only one entry. Return true if that entry matches + the pointcut's filtering criteria. */ +static bool +is_function_entry_matching (struct aop_pointcut *pc) { - struct aop_joinpoint jp; - gimple_stmt_iterator gsi; - - aop_assert (pc->kind == ATP_ENTRY); - - /* Filter this pointcut by function name if necessary. */ - if(pc->pc_entry.function_name != NULL) + /* Filter by name. */ + if(pc->pc_entry.function_name == NULL) + { + /* No name filter in place. */ + return true; + } + else { const char *func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl)); - if (strcmp (func_name, pc->pc_entry.function_name) != 0) - return; - } + return (strcmp (func_name, pc->pc_entry.function_name) == 0); + } +} + +/* We represent the function's entry as a control-flow graph edge. + That edge is the only thing necessary to join on the pointcut's one + join point. */ +static void +join_on_entry_edge (struct aop_pointcut *pc, edge in_edge, join_callback cb, + void *callback_param) +{ + struct aop_joinpoint jp; + gimple_stmt_iterator gsi; /* Note that the gimple iterator gets initialized by op_prepare_entry when it is time to insert advice. (We poison it @@ -66,15 +78,48 @@ op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb, memset (&gsi, 0xfa, sizeof (gimple_stmt_iterator)); init_joinpoint (&jp, &gsi, pc, NULL); + jp.in_edge = in_edge; cb (&jp, callback_param); } +static void +op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb, + void *callback_param) +{ + edge in_edge; + + aop_assert (pc->kind == ATP_ENTRY); + + if (!is_function_entry_matching (pc)) + return; + + /* Get the function's actual entry point: the edge coming out of the + entry block. */ + in_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)); + join_on_entry_edge (pc, in_edge, cb, 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); + int last_copy; + edge in_edge; + + aop_assert (pc->kind == ATP_ENTRY); + aop_assert (is_current_func_duplicated ()); + + if (!is_function_entry_matching (pc)) + return; + + /* We wish to join on the entry to the duplicated function body. + This will be one of the edges coming out of the distributor + block. */ + last_copy = EDGE_COUNT (distributor_bb->succs) - 1; + copy = (copy <= last_copy) ? copy : last_copy; + in_edge = EDGE_SUCC (distributor_bb, copy); + + join_on_entry_edge (pc, in_edge, cb, callback_param); } /* There is no GIMPLE statement that is suitable as an anchor point @@ -93,14 +138,12 @@ op_prepare_entry (struct aop_joinpoint *jp) { gimple nop; basic_block bb; - edge in_edge; aop_assert (jp->pc->kind = ATP_ENTRY); + aop_assert (jp->in_edge != NULL); nop = gimple_build_nop (); - - in_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION(cfun)); - gsi_insert_on_edge_immediate (in_edge, nop); + gsi_insert_on_edge_immediate (jp->in_edge, nop); /* Find an iterator pointing to the nop. */ FOR_EACH_BB (bb) @@ -114,7 +157,7 @@ op_prepare_entry (struct aop_joinpoint *jp) } } - /* We failed to found the statement we just inserted! */ + /* We failed to find the statement we just inserted! */ aop_assert (0); } diff --git a/src/aop-pointcut.c b/src/aop-pointcut.c index 587b097..086feef 100644 --- a/src/aop-pointcut.c +++ b/src/aop-pointcut.c @@ -59,5 +59,6 @@ init_joinpoint (struct aop_joinpoint *jp, gimple_stmt_iterator *gsi, jp->pc = pc; jp->gsi = gsi; jp->stmt = stmt; + jp->in_edge = NULL; jp->is_prepared = false; } diff --git a/src/aop-pointcut.h b/src/aop-pointcut.h index e12966d..c86fc2d 100644 --- a/src/aop-pointcut.h +++ b/src/aop-pointcut.h @@ -101,6 +101,10 @@ struct aop_joinpoint { /* The GIMPLE statement being instrumented (where relevant). */ gimple stmt; + /* The control-flow graph edge representing function entry (used + only for the function entry pointcut). */ + edge in_edge; + /* True if prepare_for_weave() has been called for this joinpoint. */ bool is_prepared;