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

Reply via email to