else
{
/* insert: tmpvar = distributor_fn(...) */
- /* TODO: No need to copy. */
- gimple distributor_fn = gimple_copy(call);
- aop_assert (gimple_code (distributor_fn) == GIMPLE_CALL);
+ aop_assert (gimple_code (call) == GIMPLE_CALL);
/* TODO: Do we need this? */
if (gimple_in_ssa_p (cfun))
{
- tmpvar = make_ssa_name (tmpvar, distributor_fn);
+ tmpvar = make_ssa_name (tmpvar, call);
}
- gimple_call_set_lhs (distributor_fn, tmpvar);
- gsi_insert_before (&gsi, distributor_fn, GSI_SAME_STMT);
+ gimple_call_set_lhs (call, tmpvar);
+ gsi_insert_before (&gsi, call, GSI_SAME_STMT);
}
/* insert: if (tmpvar) goto <new_label> else goto <old_label> */
#include "aop-dynval.h"
#include "aop-pointcut.h"
#include "aop-type.h"
+#include "aop-weave.h"
/**
* \defgroup assign_pc Assignment Pointcut Functions
tree lhs = gimple_get_lhs(stmt);
tree type = TREE_TYPE (gimple_get_lhs (stmt));
+ /* We never want to match a call that is actually one we
+ inserted! */
+ if (is_stmt_advice (stmt))
+ return false;
+
/* Temp variables with matching type only match the pointcut if
include_temp_vars is true. */
return does_type_match (type, pc->pc_assign.type)
--- /dev/null
+#include <aop.h>
+#include <stdio.h>
+#include <string.h>
+
+AOP_I_AM_GPL_COMPATIBLE();
+
+int duplicated = 0;
+
+static void plugin_join_on_entry(struct aop_joinpoint *jp, void *data)
+{
+ const char *name;
+
+ name = aop_capture_function_name(jp);
+ if (name != NULL && strcmp(name, "foo") == 0) {
+ aop_duplicate(jp, "_distrib", AOP_TERM_ARG);
+ duplicated = 1;
+ }
+ else {
+ duplicated = 0;
+ }
+}
+
+static void plugin_join_on_assign(struct aop_joinpoint *jp, void *data)
+{
+ aop_insert_advice(jp, "_assign_advice", AOP_INSERT_BEFORE, AOP_TERM_ARG);
+}
+
+static unsigned int plugin_reinst_dup()
+{
+ struct aop_pointcut *pc;
+
+ pc = aop_match_function_entry();
+ aop_join_on(pc, plugin_join_on_entry, NULL);
+
+ if (duplicated) {
+ /* Duplication creates an assignment that we might accidentally
+ match during a join. (This test is primarily to make sure that
+ doesn't happen! */
+ pc = aop_match_assignment_by_type(aop_t_all_signed());
+ aop_filter_include_temps (pc);
+ aop_join_on(pc, plugin_join_on_assign, NULL);
+ }
+
+ return 0;
+}
+
+AOP_MAIN_PROTO aop_main()
+{
+ aop_register_pass("reinst-dup", plugin_reinst_dup);
+}
--- /dev/null
+#include <stdio.h>
+
+void _distrib()
+{
+ printf("In distributor.\n");
+}
+
+void _assign_advice()
+{
+ printf("In assign advice.\n");
+}
--- /dev/null
+#include <stdio.h>
+
+void foo(const char *str, int n)
+{
+ printf("%d: %s\n", n, str);
+}
+
+int run_test()
+{
+ foo("A Space Odyssey", 2001);
+
+ return 0;
+}
<testcase name="Instrumenting Advice">
<plugin id="plugin-reinst1" source="plugin-reinst1.c" />
<plugin id="plugin-reinst2" source="plugin-reinst2.c" />
+ <plugin id="plugin-reinst-dup" source="plugin-reinst-dup.c" />
<run name="Attempt to instrument advice" target="reinst-target.c" hooks="reinst-hooks.c">
<using plugin="plugin-reinst1" />
<output>
THX 1138
</output>
</run>
+ <run name="Attempt to instrument distributor assignment" target="reinst-dup-target.c" hooks="reinst-dup-hooks.c">
+ <using plugin="plugin-reinst-dup" />
+ <output>
+ In distributor.
+ 2001: A Space Odyssey
+ </output>
+ </run>
</testcase>