static const char *aop_plugin_name;
+/* This code regimplifies the current function. Regimplification
+ fixes broken GIMPLE invariants. */
+static void
+regimplify ()
+{
+ basic_block bb;
+ FOR_EACH_BB(bb)
+ {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb (bb) ; !gsi_end_p (gsi) ; gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ gimple_regimplify_operands(stmt, &gsi);
+ }
+ }
+}
+
void
aop_join_on (struct aop_pointcut *pc, join_callback callback,
void *callback_param)
aop_assert (pc != NULL && pc->join_on != NULL);
pc->join_on (pc, 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
dv->jp = jp;
dv->get_dynval = op_get_lhs_addr;
+ jp->pc->need_regimplification = true;
+
return dv;
}
pc->kind = ATP_ASSIGN;
pc->join_on = op_join_on_assign;
pc->insert_before = op_default_insert_before;
+ pc->insert_after = op_default_insert_after;
pc->prepare_for_weave = op_prepare_assign;
pc->pc_assign.type = type;
pc->pc_assign.include_temp_vars = false;
+ pc->need_regimplification = false;
return pc;
}
struct aop_pointcut *pc;
pc = ggc_alloc (sizeof (struct aop_pointcut));
pc->kind = ATP_ENTRY;
+ pc->need_regimplification = false;
+
pc->join_on = op_join_on_function_entry;
pc->insert_before = op_default_insert_before;
pc->prepare_for_weave = op_default_prepare_for_weave;
struct aop_pointcut *pc;
pc = ggc_alloc (sizeof (struct aop_pointcut));
pc->kind = ATP_EXIT;
+ pc->need_regimplification = false;
+
pc->join_on = op_join_on_function_exit;
pc->insert_before = op_default_insert_before;
pc->prepare_for_weave = op_default_prepare_for_weave;
+
return pc;
}
pc = ggc_alloc (sizeof (struct aop_pointcut));
pc->kind = ATP_CALL;
+ pc->need_regimplification = false;
+
pc->join_on = op_join_on_function_call;
pc->insert_after = op_default_insert_after;
pc->insert_before = op_default_insert_before;
/* Initialize the list to NULL */
pc->pc_call.param_list_head = NULL;
+
return pc;
}
struct aop_pc_entry pc_entry;
struct aop_pc_fun_call pc_call;
};
+
+ /* True if the pointcut needs regimplification after join_on */
+ bool need_regimplification;
};
/* An AOP joinpoint represents a specific location in the code where