On Wed, May 6, 2020 at 12:26 PM Erick Ochoa <erick.oc...@theobroma-systems.com> wrote: > > Hi, > > I am trying to find out how to use the alias and/or points-to analysis > in GCC. Ideally, I would like to find a function that given an > allocation site, the return value is a set of pointers which may point > to memory allocated from that allocation site. > > For example: > > int > main(int argc, char** argv) > { > int a; > int *b = argc > 2 ? &a : NULL; > int *c = b; > } > > Here, querying the allocation site corresponding to the declaration of > local variable "a", should return { "b", "c" }.
So that's a "reverse query" to that you are asking for below ... > I've found the following documentation on Alias-Analysis [0] and two > source files[1][2] which seem to implement some (distinct?) alias analysis. > > I am trying to keep the discussion a bit high level, otherwise I would > have a lot of questions, but given this C example, **how would someone > be able to use any of the alias analyses in GCC to determine that "b" > and "c" may-alias "a"?** ... here? Otherwise for a pointer "b" you can query whether it may-alias "a" by using ptr_deref_may_alias_decl_p (b, a) or of 'a' is not a decl but a general reference there is ptr_deref_may_alias_ref_p_1 (not exported - there wasn't any need sofar). > I compiled my example and placed an pass to experiment with alias > analysis at link time. (I include the patch at the end). This is the > gimple produced by the example above. > > main (int argc, char * * argv) > { > int * c; > int * b; > int a; > int D.4170; > int * iftmp.0; > int * iftmp.0_1; > int * iftmp.0_3; > int * iftmp.0_4; > int _9; > > <bb 2> : > if (argc_2(D) > 2) > goto <bb 3>; [INV] > else > goto <bb 4>; [INV] > > <bb 3> : > iftmp.0_4 = &a; > goto <bb 5>; [INV] > > <bb 4> : > iftmp.0_3 = 0B; > > <bb 5> : > # iftmp.0_1 = PHI <iftmp.0_4(3), iftmp.0_3(4)> > b_5 = iftmp.0_1; > c_6 = b_5; > a ={v} {CLOBBER}; > _9 = 0; > > <bb 6> : > <L3>: > return _9; > > } > > I include this example because looking at the Alias Analysis [0] > section, it mentions memory SSA form. But I do not see any #.MEM_n > assignments. You need to dump with the -vops modifier (to get virtual operands dumped). And you can use the -alias modifier to dump points-to results. > Furthermore, I made an equivalent code to the example of Memory SSA form > and I still don't see any Memory SSA forms: > > ```c > int i; > int foo() > { > i = 1; > return i; > } > ``` > > ```gimple > foo () > { > int D.4164; > int _3; > > <bb 2> : > i = 1; > _3 = i; > > <bb 3> : > <L0>: > return _3; > > } > ``` > > So, I am not sure how the gimple shown on the Alias-analysis page is > produced. **Does anyone know why the gimple produced is not showing the > virtual SSA names?** > > Afterwards, instead of looking at the virtual SSA names, I then focused > on finding out whether SSA_NAME_PTR_INFO but I found that it was not > set. **Do I need I need to run something to make sure that > SSA_NAME_PTR_INFO is set?** Maybe the example I chose for compilation > did not trigger the path for setting SSA_NAME_PTR_INFO. What would be an > example of some code that does set SSA_NAME_PTR_INFO? SSA_NAME_PTR_INFO is computed by points-to analysis, for a simple IPA pass run at LTRANS time that will not be computed yet (it is not streamed into the IL because it's not in a convenient form and it can be and is re-computed early enough - just not for you ;)). Without LTO the info should be still there from the early optimization pipeline computation. Hope this helps, Richard. > Here is the patch, and in order to compile an example and dump the log: > > /path/to/gcc -fdump-ipa-hello-world -fipa-hello-world a.c > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index 543b477ff18..bc1af09cbf8 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -1399,6 +1399,7 @@ OBJS = \ > incpath.o \ > init-regs.o \ > internal-fn.o \ > + ipa-hello-world.o \ > ipa-cp.o \ > ipa-sra.o \ > ipa-devirt.o \ > diff --git a/gcc/common.opt b/gcc/common.opt > index d33383b523c..09cabeb114d 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -3408,4 +3408,8 @@ fipa-ra > Common Report Var(flag_ipa_ra) Optimization > Use caller save register across calls if possible. > > +fipa-hello-world > +Common Report Var(flag_ipa_hello_world) Optimization > +TBD > + > ; This comment is to ensure we retain the blank line above. > diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c > new file mode 100644 > index 00000000000..00e276a4bd7 > --- /dev/null > +++ b/gcc/ipa-hello-world.c > @@ -0,0 +1,126 @@ > +#include "config.h" > +#include "system.h" > +#include "coretypes.h" > +#include "backend.h" > +#include "tree.h" > +#include "gimple-expr.h" > +#include "predict.h" > +#include "alloc-pool.h" > +#include "tree-pass.h" > +#include "cgraph.h" > +#include "diagnostic.h" > +#include "fold-const.h" > +#include "gimple-fold.h" > +#include "symbol-summary.h" > +#include "tree-vrp.h" > +#include "ipa-prop.h" > +#include "tree-pretty-print.h" > +#include "tree-inline.h" > +#include "ipa-fnsummary.h" > +#include "ipa-utils.h" > +#include "tree-ssa-ccp.h" > +#include "stringpool.h" > +#include "attribs.h" > +#include "tree-ssa-alias.h" > +#include "tree-ssanames.h" > +#include "gimple.h" > +#include "cfg.h" > +#include "gimple-iterator.h" > +#include "gimple-ssa.h" > + > +void inline > +log(const char* const fmt, ...) > +{ > + if (!dump_file) return; > + > + va_list args; > + va_start(args, fmt); > + vfprintf(dump_file, fmt, args); > + va_end(args); > +} > + > +static void > +alias_experiment_gimple_body(const cgraph_node *cnode) > +{ > + gcc_assert(cnode); > + > + function *func = DECL_STRUCT_FUNCTION(cnode->decl); > + > + // We are looking first into SSA becaues of > + // this documentation... > + // Points-to and escape analysis. > + // Points-to analysis builds a set of constraints from the GIMPLE SSA IL > + // representing all pointer operations and facts we do or do not know > + // about pointers. Solving this set of constraints yields a > conservatively > + // correct solution for each pointer variable in the program (though > we are > + // only interested in SSA name pointers) as to what it may possibly > point to. > + // https://gcc.gnu.org/onlinedocs/gccint/Alias-analysis.html > + > + size_t j = 0; > + tree var_decl = NULL; > + FOR_EACH_LOCAL_DECL(func, j, var_decl) > + { > + const_tree identifier_node = DECL_NAME(var_decl); > + if (!identifier_node) continue; > + const char* const identifier_pointer = > IDENTIFIER_POINTER(identifier_node); > + log("var_decl = %s\n", identifier_pointer); > + if (POINTER_TYPE_P(TREE_TYPE(var_decl))) break; > + } > + > + size_t i = 0; > + tree ssa_name = NULL; > + push_cfun(func); > + FOR_EACH_SSA_NAME(i, ssa_name, cfun) > + { > + struct ptr_info_def *pi = SSA_NAME_PTR_INFO(ssa_name); > + if (!pi) continue; > + log("i have a pi"); > + pt_solution_includes(&pi->pt, var_decl); > + } > + pop_cfun(); > + > + > +} > + > +static unsigned int > +iphw_execute() > +{ > + cgraph_node *node = NULL; > + FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) > + { > + alias_experiment_gimple_body (node); > + } > + return 0; > +} > + > +namespace { > +const pass_data pass_data_ipa_hello_world = > +{ > + SIMPLE_IPA_PASS, > + "hello-world", > + OPTGROUP_NONE, > + TV_NONE, > + (PROP_cfg | PROP_ssa), > + 0, > + 0, > + TODO_rebuild_alias, > + 0, > +}; > + > +class pass_ipa_hello_world : public simple_ipa_opt_pass > +{ > +public: > + pass_ipa_hello_world (gcc::context *ctx) > + : simple_ipa_opt_pass(pass_data_ipa_hello_world, ctx) > + {} > + > + virtual bool gate(function*) { return flag_ipa_hello_world; } > + virtual unsigned execute (function*) { return iphw_execute(); } > +}; > +} // anon namespace > + > +simple_ipa_opt_pass* > +make_pass_ipa_hello_world (gcc::context *ctx) > +{ > + return new pass_ipa_hello_world (ctx); > +} > diff --git a/gcc/passes.def b/gcc/passes.def > index 2bf2cb78fc5..66f333f81dc 100644 > --- a/gcc/passes.def > +++ b/gcc/passes.def > @@ -149,6 +149,7 @@ along with GCC; see the file COPYING3. If not see > NEXT_PASS (pass_ipa_profile); > NEXT_PASS (pass_ipa_icf); > NEXT_PASS (pass_ipa_devirt); > + NEXT_PASS (pass_ipa_hello_world); > NEXT_PASS (pass_ipa_cp); > NEXT_PASS (pass_ipa_sra); > NEXT_PASS (pass_ipa_cdtor_merge); > diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h > index a1207a20a3c..377dda689cc 100644 > --- a/gcc/tree-pass.h > +++ b/gcc/tree-pass.h > @@ -501,6 +501,7 @@ extern ipa_opt_pass_d *make_pass_ipa_fn_summary > (gcc::context *ctxt); > extern ipa_opt_pass_d *make_pass_ipa_inline (gcc::context *ctxt); > extern simple_ipa_opt_pass *make_pass_ipa_free_lang_data (gcc::context > *ctxt); > extern simple_ipa_opt_pass *make_pass_ipa_free_fn_summary > (gcc::context *ctxt); > +extern simple_ipa_opt_pass *make_pass_ipa_hello_world (gcc::context *ctxt); > extern ipa_opt_pass_d *make_pass_ipa_cp (gcc::context *ctxt); > extern ipa_opt_pass_d *make_pass_ipa_sra (gcc::context *ctxt); > extern ipa_opt_pass_d *make_pass_ipa_icf (gcc::context *ctxt); > > > > [0] https://gcc.gnu.org/onlinedocs/gccint/Alias-analysis.html > [1] tree-ssa-alias.c > [2] tree-ssa-structalias.c