Accessing const parameter of GIMPLE_CALL

Richard Biener richard.guenther@gmail.com
Mon Jan 17 08:25:38 GMT 2022


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.

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
>


More information about the Gcc mailing list