On Apr 19, 2006, at 1:37 PM, sean yang wrote:

Thanks a lot. Here I further have a question, which is about the GIMPLE grammar. Thanks for the help again:

I looked at walk_stmt(), which is basically how I want to walk through the function body (&DECL_SAVED_TREE(fn) ).

This seems like a bad idea if the bb's have already been created, and looks really ugly, but okay :)


---------------------------------------------------------------------- -------
//in tree-nested.c
   walk_stmts (struct walk_stmt_info *wi, tree *tp)
   {
      tree t = *tp;
      switch (TREE_CODE (t))
        {
       case COND_EXPR:
         walk_tree (&COND_EXPR_COND (t), wi->callback, wi, NULL);
         walk_stmts (wi, &COND_EXPR_THEN (t));
         walk_stmts (wi, &COND_EXPR_ELSE (t));
         break;
/*     Quetion 1, as grammar for COND_EXPR is
       if-stmt      : COND_EXPR
                            op0 -> condition
                            op1 -> compound-stmt
                            op2 -> compound-stmt
       condition    : val
                    | RELOP
                            op0 -> val
                            op1 -> val
For my purpose (only searching possible CALL_EXPR node), can I ignore &COND_EXPR_COND (t) node? i.e, only do something like
   walk_stmts (wi, &COND_EXPR_THEN (t));
   walk_stmts (wi, &COND_EXPR_ELSE (t));
In other words, can "condition" tree_node include a CALL_EXPR? It seems that the GIMPLE grammar does not allow that, i.e., there is no chance for &COND_EXPR_COND (t) to contain CALL_EXPR as its internal content.
*/

Sigh, i hadn't looked at how early those passes run.

If i was running where you should be (IE about right after referenced_vars are created), i wouldn't use anything like the above (tree-nested has to denest pretty early, so it can't do this, unfortunately).

In fact, there are only *two* places a call can occur in GIMPLE at that point: bare, or the RHS of a MODIFY_EXPR.

The following code will give you *all* the CALL_EXPR statements in a function.


block_stmt_iterator bsi;
basic_block bb;

FOR_EACH_BB (bb)
{
  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
  {
    tree stmt = bsi_stmt (bsi);
    if (TREE_CODE (stmt) == CALL_EXPR
|| (TREE_CODE (stmt) == MODIFY_EXPR && TREE_CODE (TREE_OPERAND (stmt, 1) == CALL_EXPR))
     {
/* Do your thing, make sure to use BSI_SAME flags so that iteration will move properly. */
     }
  }
}


   case BIND_EXPR:
         walk_stmts (wi, &BIND_EXPR_BODY (t));
         break;
/*     Quetion 2: as grammar for BIND_EXPR is
       block        : BIND_EXPR
                            BIND_EXPR_VARS -> chain of DECLs
                            BIND_EXPR_BLOCK -> BLOCK
                            BIND_EXPR_BODY -> compound-stmt
why is it safe for the walking procedure to skip "BIND_EXPR_BLOCK" component? I think BIND_EXPR_BLOCK part can still contain statements.
*/
..........

I don't remember whether it can or not, but if you walk the basic blocks instead of the trees directly, you don't have to care.

Reply via email to