On Mon, Jan 17, 2022 at 1:55 PM Richard Biener
<richard.guent...@gmail.com> wrote:
>
> On Mon, Jan 17, 2022 at 12:54 AM David Malcolm via Gcc <gcc@gcc.gnu.org> 
> wrote:
> >
> > On Sun, 2022-01-16 at 18:52 +0530, Shubham Narlawar via Gcc wrote:
> > > Hello,
> >
> > Hi; various notes inline below...
> >
> > >
> > > My aim is to iterate over gimple call stmt parameters and check
> > > whether it is constant or constant expression and mark/store them for
> > > some gimple transformation.
> > >
> > > I have an intrinsic function call of the following -
> > >
> > > __builtin_xyz(void*, 7, addr + 10);
> > >
> > > I want to find its parameters which are either constant or constant
> > > expression i.e. 7 and addr + 10 from above case.
> >
> > Gimple "flattens" all tree-like operations into a sequence of simple
> > operations, so I would expect the gimple for this to look something
> > like this:
> >
> >    _tmp = addr + 10;
> >    __builtin_xyx (7, _tmp);
> >
> > Your email doesn't specify *when* your code runs.
> >
> > The IR for a function goes through several stages:
> >
> > - an initial gimple IR without a CFG
> > - gimple with a CFG, but not in SSA
> > - gimple-SSA with a CFG
> >   (most of the gimple optimization passes operate in this form of the
> > IR)
> > - gimple with a CFG, but no longer in CFG form, immediately before
> > conversion to RTL-with-CFG form
> > - RTL-with-CFG
> > - RTL-without a CFG
> > - assembler
> >
> > Are you doing it as part of a plugin, or modifying an existing pass?
> > In either case, it's a good idea to dump the gimple and see what the
> > code has been turned into.  You'll probably find the following options
> > useful:
> >   -fdump-tree-all -fdump-gimple-all
> >
> > or alternatively just turn it on for the pass that you're working on.
> >
> > >
> > > [1] I tried below macro but there is very less usage in the entire
> > > source code -
> > >
> > > tree fn_ptr = gimple_call_fn (dyn_cast<gcall *> (stmt));        //stmt
> >
> > gimple_call_fn returns the function that will be called, a pointer.
> > This is very general, for handling things like jumps through function
> > pointers, but here you have the common case of a callsite that calls a
> > specific function, so "fn_ptr" here is:
> >    &__builtin_xyx
> > i.e. an ADDR_EXPR where operand 0 is the FUNCTION_DECL for the builtin.
> >
> > > = gimple_call
> > > function_args_iterator iter;
> > > tree argtype;
> > >
> > > if (TREE_CODE (fn_ptr) == ADDR_EXPR)
> > > {
> > >   FOREACH_FUNCTION_ARGS (fn_ptr, argtype, iter)
> >
> > Looking in tree.h, FOREACH_FUNCTION_ARGS takes a FUNCTION_TYPE as its
> > first argument, but the code above is passing it the ADDR_EXPR wrapping
> > the FUNCTION_DECL.
> >
> > Unfortunately, because these things are all of type "tree", this kind
> > of type mismatch doesn't get caught - unless you build gcc from source
> > (with --enable-checking=debug) in which case all these accesses are
> > checked at the compiler's run time (which is probably a good thing to
> > do if you're hoping to work on gcc for GSoC).
> >
> > You can get the FUNCTION_TYPE of a FUNCTION_DECL via TREE_TYPE
> > (fndecl), or alternatively, gimple_call_fntype (call) will get the type
> > of the function expected at the call stmt (useful if there was a type
> > mismatch).
> >
> > That said, FOREACH_FUNCTION_ARGS iterates through the types of the
> > params of the FUNCTION_TYPE, but it sounds like you want to be
> > iterating through the arguments at this particular *callsite*.
> >
> > For that you can use
> >   gimple_call_num_args (call);
> > and
> >   gimple_call_arg (call, idx);
> >
> > >     {
> > >         if (TREE_CONSTANT (argtype))
> > >            // Found a constant expression parameter
> > >     }
> > > }
> > >
> > > The problem is I am getting only one parameter tree but there are 2
> > > constants in the above function call. Even if "addr + 10" is treated
> > > differently, I want to mark it for the transformation.
> >
> > I think you're seeing the function pointer being called, ather than the
> > params.
>
> I think you are iterating over the functions formal argument types
> rather than a specific call parameters.  To look at the actual
> parameters use sth like
>
>   for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
>     {
>        tree arg = gimple_call_arg (stmt, i);
>        if (CONSTANT_CLASS_P (arg))
>          ...
>     }
>
> and replace CONSTANT_CLASS_P with is_gimple_ip_invariant ()
> if you also want to handle symbolic constants like &global_var
> as constant.

Understood. I was iterating on formal parameters. But the above solves
the problem. CONSTANT_CLASS_P() and is_gimple_ip_invariant() are
helpful on integer constant.

In below gimple dump w.r.t code snippet shared by you from above -

def_stmt    _14 = (unsigned int) _13;
__builtin_xyz(instrn_buffer.3_11, 12, _14);

Here, all actual parameters are represented by tree whose classes are -

instrn_buffer.3_11 - tcc_exceptional
12 - tcc_constant
_14 - tcc_exceptional

The 1st and 3rd parameters are denoted by tcc_exceptional which fits
no category of tree, but I want to collect such 3rd parameter i.e. to
identify it whether it is variable or expression. Is it possible to do
it?

I want to mark _14 for gimple transformation if -
a. it is a variable like above _14 representing a constant.
b. it is a expression _14 + 7 i.e. again at gimple level, it is case (a)
c. it is a phi node which represents constant when there is a case of
ternary operator usage.

How to identify such an actual parameter of gimple call?

The aim of the above scenario is to identify such
variables/expressions and then apply constant folding and propagation.
If constant folding and propagation are not happening on actual
parameters of intrinsic call, then I need to write some plugin to do
it. My plugin is placed just after "pass_build_cgraph_edges" i.e.
Callgraph Construction.

Thanks for the helpful suggestions.

Regards,
Shubham


>
> Richard.
>
> > >
> > > a. Is the above correct method to iterate over function call
> > > parameters?
> >
> > As noted above, it depends on whether you want to iterate over the
> > types of the parameters in the function's decl, or over the expressions
> > of the arguments at the callsite.  I believe the above explains how to
> > do each of these.
> >
> > > b. Is there a different way to achieve the above goal?
> >
> > If you're looking to get familiar with GCC's insides, I recommend
> > stepping through it in the debugger, rather than relying on injecting
> > print statements and recompiling, since the former makes it much easier
> > to spot mistakes like the one above (which we all make).
> >
> > I've written a guide to debugging GCC here:
> >
> > https://dmalcolm.fedorapeople.org/gcc/newbies-guide/debugging.html
> >
> >
> > Hope this is helpful
> > Dave
> >

Reply via email to