From: Justin Seyster Date: Wed, 27 Oct 2010 23:17:49 +0000 (-0400) Subject: Added idea of pre_stmts. X-Git-Tag: release-v1.0~8 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=d18408222e96d08a9f5081ac6f72187c4dc4dedc;p=interaspect.git Added idea of pre_stmts. The pre_stmts vector lets build_dynval construct a list of statements it wants to insert rather than directly inserting those statements on its own. --- diff --git a/src/aop-weave.c b/src/aop-weave.c index 2b94156..711e753 100644 --- a/src/aop-weave.c +++ b/src/aop-weave.c @@ -157,7 +157,7 @@ build_string_ptr (const char *string) variable with a cast. Insert the assignment before the join point and return the temporary value. */ static tree -insert_cast (tree val, tree cast_type, struct aop_joinpoint *jp) +insert_cast (tree val, tree cast_type, VEC(gimple, heap) *pre_stmts) { tree tmp; tree cast; @@ -167,7 +167,7 @@ insert_cast (tree val, tree cast_type, struct aop_joinpoint *jp) cast = build1 (CONVERT_EXPR, cast_type, val); cast_assign = gimple_build_assign (tmp, cast); - jp->pc->insert_before (jp, cast_assign); + VEC_safe_push (gimple, heap, pre_stmts, cast_assign); return tmp; } @@ -175,7 +175,7 @@ insert_cast (tree val, tree cast_type, struct aop_joinpoint *jp) /* Whenver InterAspect matches an "all signed" or "all unsigned" value, it needs to cast it up to a long long before passing it. */ static tree -cast_to_all_integer (tree val, struct aop_joinpoint *jp) +cast_to_all_integer (tree val, VEC(gimple, heap) *pre_stmts) { tree gcc_type; HOST_WIDE_INT size; @@ -191,7 +191,7 @@ cast_to_all_integer (tree val, struct aop_joinpoint *jp) tree cast_type = TYPE_UNSIGNED (gcc_type) ? long_long_unsigned_type_node : long_long_integer_type_node; - return insert_cast (val, cast_type, jp); + return insert_cast (val, cast_type, pre_stmts); } else { @@ -202,7 +202,7 @@ cast_to_all_integer (tree val, struct aop_joinpoint *jp) /* Similar to cast_to_all_integer, above. */ static tree -cast_to_all_fp (tree val, struct aop_joinpoint *jp) +cast_to_all_fp (tree val, VEC(gimple, heap) *pre_stmts) { tree gcc_type; HOST_WIDE_INT size; @@ -215,7 +215,7 @@ cast_to_all_fp (tree val, struct aop_joinpoint *jp) if (size != 8) { - return insert_cast (val, double_type_node, jp); + return insert_cast (val, double_type_node, pre_stmts); } else { @@ -224,17 +224,20 @@ cast_to_all_fp (tree val, struct aop_joinpoint *jp) } } +/* Building a dynval creates a tree node but may also generate GIMPLE + statements that are necessary setup for the tree node. Those + statements are output to the pre_stmts list. */ static tree -build_dynval (struct aop_dynval *dv) +build_dynval (struct aop_dynval *dv, VEC(gimple, heap) *pre_stmts) { tree val; val = dv->get_dynval (dv); if (is_all_integer_type (dv->type)) - val = cast_to_all_integer (val, dv->jp); + val = cast_to_all_integer (val, pre_stmts); else if (is_all_fp_type (dv->type)) - val = cast_to_all_fp (val, dv->jp); + val = cast_to_all_fp (val, pre_stmts); return val; } @@ -244,10 +247,12 @@ build_dynval (struct aop_dynval *dv) iterates through those arguments and creates GIMPLE tree nodes for each of them. - The new nodes get stored in arglist. */ + The new nodes get stored in arglist. GIMPLE statements that must + be inserted before the call are put in the pre_stmts list. */ static gimple build_gcc_call (const char *func_name, tree return_type, - enum aop_insert_location location, va_list argp) + enum aop_insert_location location, VEC(gimple, heap) *pre_stmts, + va_list argp) { enum aop_argkind kind; VEC(tree, heap) *arg_list; @@ -307,7 +312,7 @@ build_gcc_call (const char *func_name, tree return_type, if (location == AOP_INSERT_BEFORE) verify_legal_in_before_advice (dv); - new_arg = build_dynval (dv); + new_arg = build_dynval (dv, pre_stmts); VEC_safe_push (tree, heap, arg_list, new_arg); break; default: @@ -393,6 +398,7 @@ aop_insert_advice (struct aop_joinpoint *jp, const char *func_name, va_list argp; gimple func_call; struct aop_pointcut *pc; + VEC(gimple, heap) *pre_stmts; pc = jp->pc; @@ -403,19 +409,59 @@ aop_insert_advice (struct aop_joinpoint *jp, const char *func_name, jp->is_prepared = true; } + pre_stmts = VEC_alloc (gimple, heap, 2); + va_start (argp, location); - func_call = build_gcc_call (func_name, void_type_node, location, argp); + func_call = build_gcc_call (func_name, void_type_node, location, pre_stmts, + argp); va_end (argp); va_start (argp, location); insert_prototype (false /* void return type */, func_name, gimple_call_num_args (func_call), argp); va_end (argp); - + if(location == AOP_INSERT_BEFORE) - pc->insert_before(jp, func_call); + { + int i; + gimple stmt; + + for (i = 0; VEC_iterate (gimple, pre_stmts, i, stmt); i++) + pc->insert_before (jp, stmt); + pc->insert_before (jp, func_call); + } else if(location == AOP_INSERT_AFTER) - pc->insert_after(jp, func_call); + { + /* insert_after() adds statements backwards, so we have to work + in reverse. */ + pc->insert_after (jp, func_call); + while (!VEC_empty (gimple, pre_stmts)) + { + gimple stmt; + stmt = VEC_pop (gimple, pre_stmts); + aop_assert (stmt != NULL); + + pc->insert_after (jp, stmt); + } + } + + VEC_free(gimple, heap, pre_stmts); +} + +/* Take a list of statements and insert them at the current function's + main entry point. */ +static void +insert_stmts_at_entry (VEC(gimple, heap) *stmt_list) +{ + int i; + edge in_edge; + gimple stmt; + + /* Get the edge for the main entry point. */ + in_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)); + + for (i = 0; VEC_iterate (gimple, stmt_list, i, stmt); i++) + gsi_insert_on_edge_immediate (in_edge, stmt); } /** @@ -451,6 +497,7 @@ aop_duplicate (struct aop_joinpoint *jp, const char *func_name, ...) va_list argp; gimple func_call; struct aop_pointcut *pc; + VEC(gimple, heap) *pre_stmts; pc = jp->pc; @@ -463,9 +510,11 @@ aop_duplicate (struct aop_joinpoint *jp, const char *func_name, ...) else if (is_current_func_duplicated()) fatal_error ("(InterAspect) Cannot duplicate a function more than once."); + pre_stmts = VEC_alloc (gimple, heap, 2); + va_start (argp, func_name); func_call = build_gcc_call (func_name, integer_type_node, AOP_INSERT_BEFORE, - argp); + pre_stmts, argp); va_end (argp); va_start (argp, func_name); @@ -473,4 +522,10 @@ aop_duplicate (struct aop_joinpoint *jp, const char *func_name, ...) gimple_call_num_args (func_call), argp); duplicate_function_body ("ia_body_index", func_call); + + /* Insert all of the pre_stmts at the function entry so they will be + before func_call. */ + insert_stmts_at_entry (pre_stmts); + + VEC_free(gimple, heap, pre_stmts); }