Discussion:
Problem with SSA form usign cgraph_nodes and push_cfun
Massimo Nazaria
2010-04-29 17:28:47 UTC
Permalink
Hi everybody!
I am working on a gcc-pass which processes every statement using this code:

for (node = cgraph_nodes; node; node = node->next)
{
if (node->analyzed && cgraph_is_master_clone (node))
{
push_cfun (DECL_STRUCT_FUNCTION (node->decl));

FOR_EACH_BB (bb)
{
// Here I would like to use SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));


With the code above I can't use SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)) (I get 'segmentation fault'). I think the reason is that the statements are not in SSA-form.

Insead, if I use

FOR_EACH_BB (bb) { ... }

without using "for (node = graph_nodes; ...", I have the statements in SSA-form and SSA_NAME_DEF_STMT is OK.

Unfortunately, with this solution, I can not process every function at once...

How can I do to use SSA_NAME_DEF_STMT while processing every function?

Thank you!

Max
Richard Guenther
2010-04-30 08:41:57 UTC
Permalink
Post by Massimo Nazaria
Hi everybody!
 for (node = cgraph_nodes; node; node = node->next)
   {
     if (node->analyzed && cgraph_is_master_clone (node))
       {
         push_cfun (DECL_STRUCT_FUNCTION (node->decl));
         FOR_EACH_BB (bb)
           {
           // Here I would like to use SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
With the code above I can't use SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)) (I get 'segmentation fault'). I think the reason is that the statements are not in SSA-form.
Insead, if I use
 FOR_EACH_BB (bb) { ... }
without using "for (node = graph_nodes; ...", I have the statements in SSA-form and SSA_NAME_DEF_STMT is OK.
Unfortunately, with this solution, I can not process every function at once...
How can I do to use SSA_NAME_DEF_STMT while processing every function?
You have to schedule your IPA pass at a point where the whole
program is in SSA form, which is during the regular IPA passes
at earlierst.

Richard.
Post by Massimo Nazaria
Thank you!
Max
Massimo Nazaria
2010-04-30 11:42:07 UTC
Permalink
Post by Richard Guenther
You have to schedule your IPA pass at a point where the
whole
program is in SSA form, which is during the regular IPA
passes
at earlierst.
Richard.
It does not work :(
I put my pass after all the ipa-passes and right before the optimization-passes.

My problem occurs when I try to process every function at once using "for(node=cgraph_nodes;node;node=node->next) ..."

Other ideas?

Thank you!
Richard Guenther
2010-04-30 12:10:19 UTC
Permalink
Post by Massimo Nazaria
Post by Richard Guenther
You have to schedule your IPA pass at a point where the
whole
program is in SSA form, which is during the regular IPA
passes
at earlierst.
Richard.
It does not work :(
I put my pass after all the ipa-passes and right before the optimization-passes.
My problem occurs when I try to process every function at once using "for(node=cgraph_nodes;node;node=node->next) ..."
It definitely works that way.

Richard.
Post by Massimo Nazaria
Other ideas?
Thank you!
Steven Bosscher
2010-04-30 12:11:54 UTC
Permalink
Post by Massimo Nazaria
Post by Richard Guenther
You have to schedule your IPA pass at a point where the
whole
program is in SSA form, which is during the regular IPA
passes
at earlierst.
Richard.
It does not work :(
I put my pass after all the ipa-passes and right before the optimization-passes.
My problem occurs when I try to process every function at once using "for(node=cgraph_nodes;node;node=node->next) ..."
Other ideas?
You'll have to post your work so people can see. Now the best the
experts here can do is guess what you're holding behind your back :-)

Ciao!
Steven
Massimo Nazaria
2010-04-30 13:35:01 UTC
Permalink
Post by Steven Bosscher
You'll have to post your work so people can see. Now the
best the
experts here can do is guess what you're holding behind
your back :-)
Ciao!
Steven
I completely agree with you. This is my pass:

static unsigned int
execute_mypass (void)
{
basic_block bb;
gimple stmt, def_stmt;
gimple_stmt_iterator gsi;
struct cgraph_node *node;
unsigned int rhs_code_class;

if (flag_mypass)
{
for (node = cgraph_nodes; node; node = node->next)
{
if (node->analyzed && cgraph_is_master_clone (node))
{
push_cfun (DECL_STRUCT_FUNCTION (node->decl));

FOR_EACH_BB (bb)
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
stmt = gsi_stmt (gsi);

if (gimple_code (stmt) == GIMPLE_ASSIGN)
{
/* Check if the assignment is acctually
a function call. For example:
D.1 = func (args...);
a.9 = D.1
a = a.9
The last one is seen as a GIMPLE_ASSIGN stmt
but I want to check if it refers to a function call */

rhs_code_class = get_gimple_rhs_class (gimple_assign_rhs_code (stmt));
if ((rhs_code_class == GIMPLE_UNARY_RHS) || (rhs_code_class == GIMPLE_SINGLE_RHS))
{
if (is_temporary_var (gimple_assign_rhs1 (stmt))) // e.g.: a.1, D.1234...
{
def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));

fprintf (dump_file, "gimple_code: %d\n", gimple_code (def_stmt)); // Here I get segmentation fault...
}
}
}
}
}
pop_cfun ();
}
}
}

return 0;
}

The problem is that "SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt))" does not return a gimple stmt. I think that's because, when I make a dump of the stmts with the code above, this one has not the SSA-form. But if only use the FOR_EACH (bb), without "for (node = cgraph_nodes; ...", the SS-form is OK and SSA_NAME_DEF_STMT works well.

How can I do?

Thank you!
Steven Bosscher
2010-04-30 13:42:57 UTC
Permalink
Post by Steven Bosscher
You'll have to post your work so people can see. Now the
best the
experts here can do is guess what you're holding behind
your back :-)
Ciao!
Steven
The place where you insert the patch is as important as the
implementation of your patch. What do your changes to passes.c look
like?

Ciao!
Steven
Massimo Nazaria
2010-04-30 13:48:13 UTC
Permalink
Post by Steven Bosscher
The place where you insert the patch is as important as
the
implementation of your patch. What do your changes to
passes.c look
like?
Here is the "passes.c":

NEXT_PASS (pass_early_warn_uninitialized);
NEXT_PASS (pass_all_early_optimizations);

NEXT_PASS (pass_mypass); // My pass...

{
struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
NEXT_PASS (pass_rebuild_cgraph_edges);
Diego Novillo
2010-04-30 14:00:04 UTC
Permalink
Post by Massimo Nazaria
fprintf (dump_file, "gimple_code: %d\n", gimple_code (def_stmt)); // Here I get segmentation fault...
For default SSA names, the defining statement will be NULL. A default
SSA name will be created when a symbol is never written before its first
read (e.g., function parameters are typical).


Diego.

PS: It's usually better to post the output of 'svn diff' so we can see
*all* your changes and possibly apply them into our own local trees for
testing.
Michael Matz
2010-04-30 14:48:41 UTC
Permalink
Hi,
Post by Diego Novillo
Post by Massimo Nazaria
fprintf (dump_file, "gimple_code: %d\n", gimple_code (def_stmt)); // Here I get segmentation fault...
For default SSA names, the defining statement will be NULL.
Nope, it will be non-NULL but gimple_nop_p().


Ciao,
Michael.
Diego Novillo
2010-04-30 14:55:45 UTC
Permalink
Post by Michael Matz
Post by Diego Novillo
For default SSA names, the defining statement will be NULL.
Nope, it will be non-NULL but gimple_nop_p().
Bah! yes, of course. Sorry about that.


Diego.
Richard Guenther
2010-04-30 14:13:28 UTC
Permalink
Post by Massimo Nazaria
Post by Steven Bosscher
You'll have to post your work so people can see. Now the
best the
experts here can do is guess what you're holding behind
your back :-)
Ciao!
Steven
static unsigned int
execute_mypass (void)
{
 basic_block bb;
 gimple stmt, def_stmt;
 gimple_stmt_iterator gsi;
 struct cgraph_node *node;
 unsigned int rhs_code_class;
 if (flag_mypass)
   {
     for (node = cgraph_nodes; node; node = node->next)
       {
         if (node->analyzed && cgraph_is_master_clone (node))
               {
                 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
             FOR_EACH_BB (bb)
               {
                 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
                   {
                     stmt = gsi_stmt (gsi);
                     if (gimple_code (stmt) == GIMPLE_ASSIGN)
                       {
                       /* Check if the assignment is acctually
                            D.1 = func (args...);
                            a.9 = D.1
                            a = a.9
                         The last one is seen as a GIMPLE_ASSIGN stmt
                         but I want to check if it refers to a function call */
                         rhs_code_class = get_gimple_rhs_class (gimple_assign_rhs_code (stmt));
                         if ((rhs_code_class == GIMPLE_UNARY_RHS) || (rhs_code_class == GIMPLE_SINGLE_RHS))
                           {
                             if (is_temporary_var (gimple_assign_rhs1 (stmt))) // e.g.: a.1, D.1234...
This check is critical - if it is not verifying that
TREE_CODE (gimple_Assign_rhs1 (Stmt)) == SSA_NAME then
it's wrong.
Post by Massimo Nazaria
                               {
                                 def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
                                 fprintf (dump_file, "gimple_code: %d\n", gimple_code (def_stmt)); // Here I get segmentation fault...
                               }
                           }
                       }
                   }
               }
             pop_cfun ();
           }
       }
   }
 return 0;
}
The problem is that "SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt))" does not return a gimple stmt. I think that's because, when I make a dump of the stmts with the code above, this one has not the SSA-form. But if only use the FOR_EACH (bb), without "for (node = cgraph_nodes; ...", the SS-form is OK and SSA_NAME_DEF_STMT works well.
How can I do?
Thank you!
Massimo Nazaria
2010-04-30 18:53:48 UTC
Permalink
Thank you everyone!!!
I found out a solution...

I had to add a line to my pass (the 2nd if):
for (node = cgraph_nodes; node; node = node->next) {
if (node->analyzed && cgraph_is_master_clone (node)) {
if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))) return 0; // I added this line

In my case, the remaining code of the pass is executed only when the pass-manager is working on the last function of the input program. Now I can process every function at once, and the statements are in SSA-form.

Thank you again!

Max

Loading...