I will appreciate your help. Thanks in advance.
Let me give a concrete example of what I want to do (Please understand I
have other reasons to do this after gimplification, though the example shows
that there is a much simpler way to achieve this): in the example, I want
to add a call of instrument() after each call of foo()
-----------------------
//input source: example.c
main(){
int i=0;
foo();
i++;
bar();
}
-----------------------------
//conceptual source: with my compiler, the output should look like the
output of the following source code
main(){
int i=0;
foo();
instrument(); //i.e, adding a node of CALL_EXPR (instrument) after each
node CALL_EXPR (foo)
i++;
bar();
}
-----------------------------
What I want to do is whenever I find a CALL_EXPR node, I look up its ID to
see if it is "foo". If it is, I add another CALL_EXPR node with ID of
"instrument". I have two questions:
(1) I know "call_node = build (CALL_EXPR, tree_node)" can build a new node,
but how can I fill the field of tree_node properly? i.e., make the content
of tree_node be a call to "instrument". It seems there is no API to do so.
(2) after the node the call_node has been built, how can I added to the
proper place? It seems that tsi_link_after () can't do what I want under
this situation because it's only used for STATEMENT_LIST, not other type of
nodes, like CALL_EXPR.
Can someone give me some help or hint on above two questions?
//pass-myinstrument.c
static void
add_instruments (tree *tp)
{
tree t=*tp, op, new_call;
switch (TREE_CODE (t))
{
case CALL_EXPR:
//I want to add another CALL_EXPR node after the current CALL_EXPR
node
//*******this is my question ***********
break;
case COND_EXPR:
add_instruments ( &COND_EXPR_THEN(t));
add_instruments ( &COND_EXPR_ELSE(t));
break;
case BIND_EXPR:
add_instruments ( &BIND_EXPR_BODY(t));
break;
//and other cases not shown here
default:
fprintf(stderr, "%d\n", TREE_CODE(t));
break;
}
}
static void
code_instrumentation (void)
{
add_instruments (&DECL_SAVED_TREE (current_function_decl));
}
struct tree_opt_pass pass_beacon_instrument =
{
"my_instrumentation", /* name */
NULL, /* gate */
code_instrumentation, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_TREE_BEACON_INSERTION, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_ggc_collect, /* todo_flags_finish */
0 /* letter */
};
The place of the added pass is shown here
---------------------------------------------------------
//file name: tree-optimize.c GCC4.0.2
init_tree_optimization_passes (void)
{
struct tree_opt_pass **p;
#define NEXT_PASS(PASS) (p = next_pass_1 (p, &PASS))
p = &all_passes;
NEXT_PASS (pass_gimple);
// this is where the pass is added
NEXT_PASS (pass_beacon_instrument);
NEXT_PASS (pass_remove_useless_stmts);
//....
}
-------------------------------------------------------------------
_________________________________________________________________
FREE pop-up blocking with the new MSN Toolbar get it now!
http://toolbar.msn.click-url.com/go/onm00200415ave/direct/01/