public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Questions about LTO, clones and ipa_ref
@ 2019-11-27 19:32 erick.ochoa
  2019-11-27 19:38 ` erick.ochoa
  0 siblings, 1 reply; 3+ messages in thread
From: erick.ochoa @ 2019-11-27 19:32 UTC (permalink / raw)
  To: gcc-help; +Cc: Christoph Müllner


Hello,

I am working on an interprocedural analysis (ipa) and transformation for 
GCC.
The optimizations is called ipa-initcall-cp because it copies and 
propagates
values assign to constants (with static lifetime) as in the case of 
calling
an initialization function.

I am new to gcc compiler development, but I already have a working
implementation for ipa-initcall-cp and can be found here [0]. 
ipa-initcall-cp
is currently implemented as a SIMPLE_IPA_PASS and is able to compile 
code for
some benchmarks. The current limitation is that when compiling with
ipa-initcall-cp, one needs to specify the flag `-flto-partition=none`. I 
would
like to ask a few questions as a sanity check:

The GCC internal documentation says the following [0]

   To facilitate [...] communication [between the different LTO stages], 
the GCC
   callgraph infrastructure implements virtual clones [...]

   A virtual clone in the callgraph is a function that has no associated 
body,
   just a description of how to create its body based on a different 
function.

   The description of function modifications includes adjustments to the
   function's signature [...], substitutions to perform on the function 
body

Looking at the code, I was able to find several examples of clones 
(virtual and
other types). The examples that I have been able to find, modify a
function's body but it is all done through the parameters:
* vec<ipa_replace_map *, gc> *tree_map
* ipa_param_adjustments *param_adjustments
(These are found in several functions defined on gcc/cgraphclones.c)

Looking at the definition for ipa_replace_map
(defined on gcc/cgraph.h:713)
```
struct GTY(()) ipa_replace_map
{
   /* The new (replacing) tree. */
   tree new_tree;
   /* Parameter number to replace, when old_tree is NULL. */
   int parm_num;
}
```
suggests that the only replacements possible are those that replace a 
parameter
with a tree. Furthermore, the comments suggest that previously the 
capability
to replace any arbitrary old_tree with new_tree was possible.

Question #1: Is there a way to replace arbitrary old_trees for 
new_trees?
Question #2: If there is a way, what is the way to do so?

This is necessary for ipa-initcall-cp because functions might access 
global
variables with static life-time and therefore have no impact on the
method's parameters.



So far, instead of using ipa_replace map and parameter adjustments, what
ipa-initcall-cp does is it modifies the original function, and at the 
end of
ipa-initcall-cp it creates a clone (with the modified function) and 
removes
the original function. I would like to keep around the original 
function, as
it seems that it might be necessary for linking without 
-flto-partition=none.
It might also be a source of linking errors in some other programs.

As a result, another alternative I have explored is to create a clone 
and only
modify the clone.

Question #3: How does creating a clone affect an IPA_REF?

More concretely: If I have the following code

```
static void
propagate_constant_to_read(tree write_val, struct ipa_ref* ref) {

   gcc_assert(ref->use == IPA_REF_LOAD);
   symtab_node *f_node = ref->referring;
   cgraph_node *f_cnode = dyn_cast<cgraph_node *> (f_node);
   f_cnode->get_untransformed_body();

   cgraph_node *clone = f_cnode->create_clone(/* ... */);

   gimple *read_stmt = ref->stmt;
   gcc_assert(gimple_code(read_stmt) == GIMPLE_ASSIGN);
   gcc_assert(gimple_num_ops(read_stmt) == 2);
   tree old_lhs = gimple_op(read_stmt, 0);

   push_cfun(clone);
   gimple *use_stmt;
   imm_use_iterator use_iter;
   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, old_lhs)
      {
      // replace old use with write...
      }
   pop_cfun();

}
```

Can I still use ipa_ref/read_stmt but now in the context of the clone?
Will I be iterating over the uses in clone or the uses in f_cnode?

Question #4: Is there a way to map the ipa_ref in one function to the 
ipa_ref
in its clones?

Thanks! Any help will be greatly appreciated!

[0] https://gcc.gnu.org/onlinedocs/gccint/IPA.html#IPA

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Questions about LTO, clones and ipa_ref
  2019-11-27 19:32 Questions about LTO, clones and ipa_ref erick.ochoa
@ 2019-11-27 19:38 ` erick.ochoa
  2019-11-27 19:49   ` erick.ochoa
  0 siblings, 1 reply; 3+ messages in thread
From: erick.ochoa @ 2019-11-27 19:38 UTC (permalink / raw)
  To: gcc-help

Sorry, I forgot to mention where the code can be found:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92538

On 2019-11-27 14:32, erick.ochoa@theobroma-systems.com wrote:
> Hello,
> 
> I am working on an interprocedural analysis (ipa) and transformation 
> for GCC.
> The optimizations is called ipa-initcall-cp because it copies and 
> propagates
> values assign to constants (with static lifetime) as in the case of 
> calling
> an initialization function.
> 
> I am new to gcc compiler development, but I already have a working
> implementation for ipa-initcall-cp and can be found here [0]. 
> ipa-initcall-cp
> is currently implemented as a SIMPLE_IPA_PASS and is able to compile 
> code for
> some benchmarks. The current limitation is that when compiling with
> ipa-initcall-cp, one needs to specify the flag `-flto-partition=none`. 
> I would
> like to ask a few questions as a sanity check:
> 
> The GCC internal documentation says the following [0]
> 
>   To facilitate [...] communication [between the different LTO stages], 
> the GCC
>   callgraph infrastructure implements virtual clones [...]
> 
>   A virtual clone in the callgraph is a function that has no associated 
> body,
>   just a description of how to create its body based on a different 
> function.
> 
>   The description of function modifications includes adjustments to the
>   function's signature [...], substitutions to perform on the function 
> body
> 
> Looking at the code, I was able to find several examples of clones 
> (virtual and
> other types). The examples that I have been able to find, modify a
> function's body but it is all done through the parameters:
> * vec<ipa_replace_map *, gc> *tree_map
> * ipa_param_adjustments *param_adjustments
> (These are found in several functions defined on gcc/cgraphclones.c)
> 
> Looking at the definition for ipa_replace_map
> (defined on gcc/cgraph.h:713)
> ```
> struct GTY(()) ipa_replace_map
> {
>   /* The new (replacing) tree. */
>   tree new_tree;
>   /* Parameter number to replace, when old_tree is NULL. */
>   int parm_num;
> }
> ```
> suggests that the only replacements possible are those that replace a 
> parameter
> with a tree. Furthermore, the comments suggest that previously the 
> capability
> to replace any arbitrary old_tree with new_tree was possible.
> 
> Question #1: Is there a way to replace arbitrary old_trees for 
> new_trees?
> Question #2: If there is a way, what is the way to do so?
> 
> This is necessary for ipa-initcall-cp because functions might access 
> global
> variables with static life-time and therefore have no impact on the
> method's parameters.
> 
> 
> 
> So far, instead of using ipa_replace map and parameter adjustments, 
> what
> ipa-initcall-cp does is it modifies the original function, and at the 
> end of
> ipa-initcall-cp it creates a clone (with the modified function) and 
> removes
> the original function. I would like to keep around the original 
> function, as
> it seems that it might be necessary for linking without 
> -flto-partition=none.
> It might also be a source of linking errors in some other programs.
> 
> As a result, another alternative I have explored is to create a clone 
> and only
> modify the clone.
> 
> Question #3: How does creating a clone affect an IPA_REF?
> 
> More concretely: If I have the following code
> 
> ```
> static void
> propagate_constant_to_read(tree write_val, struct ipa_ref* ref) {
> 
>   gcc_assert(ref->use == IPA_REF_LOAD);
>   symtab_node *f_node = ref->referring;
>   cgraph_node *f_cnode = dyn_cast<cgraph_node *> (f_node);
>   f_cnode->get_untransformed_body();
> 
>   cgraph_node *clone = f_cnode->create_clone(/* ... */);
> 
>   gimple *read_stmt = ref->stmt;
>   gcc_assert(gimple_code(read_stmt) == GIMPLE_ASSIGN);
>   gcc_assert(gimple_num_ops(read_stmt) == 2);
>   tree old_lhs = gimple_op(read_stmt, 0);
> 
>   push_cfun(clone);
>   gimple *use_stmt;
>   imm_use_iterator use_iter;
>   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, old_lhs)
>      {
>      // replace old use with write...
>      }
>   pop_cfun();
> 
> }
> ```
> 
> Can I still use ipa_ref/read_stmt but now in the context of the clone?
> Will I be iterating over the uses in clone or the uses in f_cnode?
> 
> Question #4: Is there a way to map the ipa_ref in one function to the 
> ipa_ref
> in its clones?
> 
> Thanks! Any help will be greatly appreciated!
> 
> [0] https://gcc.gnu.org/onlinedocs/gccint/IPA.html#IPA

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Questions about LTO, clones and ipa_ref
  2019-11-27 19:38 ` erick.ochoa
@ 2019-11-27 19:49   ` erick.ochoa
  0 siblings, 0 replies; 3+ messages in thread
From: erick.ochoa @ 2019-11-27 19:49 UTC (permalink / raw)
  To: gcc-help

Sending the same content but with fixed formatting:

Hello,

I am working on an interprocedural analysis (ipa) and transformation for 
GCC.
The optimizations is called ipa-initcall-cp because it copies and 
propagates
values assign to constants (with static lifetime) as in the case of 
calling
an initialization function.

I am new to gcc compiler development, but I already have a working
implementation for ipa-initcall-cp and can be found here [0]. 
ipa-initcall-cp
is currently implemented as a SIMPLE_IPA_PASS and is able to compile 
code for
some benchmarks. The current limitation is that when compiling with
ipa-initcall-cp, one needs to specify the flag `-flto-partition=none`. I 
would
like to ask a few questions as a sanity check:

The GCC internal documentation says the following

   To facilitate [...] communication [between the different LTO stages], 
the GCC
   callgraph infrastructure implements virtual clones [...]

   A virtual clone in the callgraph is a function that has no associated 
body,
   just a description of how to create its body based on a different 
function.

   The description of function modifications includes adjustments to the
   function's signature [...], substitutions to perform on the function 
body

Looking at the code, I was able to find several examples of clones 
(virtual and
other types). The examples that I have been able to find on how to 
modify a
function's body is all done through the parameters:
* vec<ipa_replace_map *, gc> *tree_map
* ipa_param_adjustments *param_adjustments
(These are found in several functions defined on gcc/cgraphclones.c)

Looking at the definition for ipa_replace_map
(defined on gcc/cgraph.h:713)
```
struct GTY(()) ipa_replace_map
{
   /* The new (replacing) tree. */
   tree new_tree;
   /* Parameter number to replace, when old_tree is NULL. */
   int parm_num;
}
```
suggests that the only replacements possible are those that replace a 
parameter
with a tree. Furthermore, the comments suggest that previously the 
capability
to replace any arbitrary old_tree with new_tree was possible.

Question #1: Is there a way to replace arbitrary old_trees for 
new_trees?
Question #2: If there is a way, what is the way to do so?

This is necessary for ipa-initcall-cp because functions might access 
global
variables with static durations and therefore have no impact on the 
method's
parameters.

So far, instead of using ipa_replace map and parameter adjustments, what
ipa-initcall-cp does is it modifies the original function, and at the 
end of
ipa-initcall-cp it creates a clone (with the modified function) and 
removes
the original function. I would like to keep around the original 
function, as
it seems that it might be necessary for linking without 
-flto-partition=none.
It might also be a source of linking errors in some other programs.

As a result, another alternative I have explored is to create a clone 
and only
modify the clone.

Question #3: How does creating a clone affect an IPA_REF?

More concretely: If I have the following code

```
static void
propagate_constant_to_read(tree write_val, struct ipa_ref* ref) {

   gcc_assert(ref->use == IPA_REF_LOAD);
   symtab_node *f_node = ref->referring;
   cgraph_node *f_cnode = dyn_cast<cgraph_node *> (f_node);
   f_cnode->get_untransformed_body();

   cgraph_node *clone = f_cnode->create_clone(/* ... */);

   gimple *read_stmt = ref->stmt;
   gcc_assert(gimple_code(read_stmt) == GIMPLE_ASSIGN);
   gcc_assert(gimple_num_ops(read_stmt) == 2);
   tree old_lhs = gimple_op(read_stmt, 0);

   push_cfun(clone);
   gimple *use_stmt;
   imm_use_iterator use_iter;
   FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, old_lhs)
      {
      // replace old use with write...
      }
   pop_cfun();

}
```

Can I still use ipa_ref/read_stmt but now in the context of the clone?
Will I be iterating over the uses in clone or the uses in f_cnode?

Question #4: Is there a way to map the ipa_ref in one function to the 
ipa_ref
in its clones?

Thanks! Any help will be greatly appreciated!


[0] https://gcc.gnu.org/onlinedocs/gccint/IPA.html#IPA
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92538

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-11-27 19:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-27 19:32 Questions about LTO, clones and ipa_ref erick.ochoa
2019-11-27 19:38 ` erick.ochoa
2019-11-27 19:49   ` erick.ochoa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).