public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Martin Sebor <msebor@gmail.com>
To: Shubham Narlawar <gsocshubham@gmail.com>,
	Richard Biener <richard.guenther@gmail.com>
Cc: GCC Development <gcc@gcc.gnu.org>
Subject: Re: Accessing const parameter of GIMPLE_CALL
Date: Mon, 17 Jan 2022 13:49:50 -0700	[thread overview]
Message-ID: <d2e2bebe-8cc1-b6a2-c68a-716f73d6bfca@gmail.com> (raw)
In-Reply-To: <CAN=hqDAjkV97JMdf46ChG91c_Ay9FoVbGKSLW=D1dqG8CVpNqQ@mail.gmail.com>

On 1/17/22 12:18, Shubham Narlawar via Gcc wrote:
> On Mon, Jan 17, 2022 at 1:55 PM Richard Biener
> <richard.guenther@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.

I use the following code.  It runs after pass_build_ssa, so a bit
later than pass_build_cgraph_edges:

       /* Use the range query to determine constant values in the absence
	 of constant proppagation (such as at -O0).  */
       value_range rng;
       if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt)
	  || !rng.constant_p ()
	  || !rng.singleton_p (&ord))
	return false;

       wide_int lob = rng.lower_bound ();
       if (!wi::fits_uhwi_p (lob))
	return false;

       val = lob.to_shwi ();

Martin

> 
> 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	other threads:[~2022-01-17 20:49 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-16 13:22 Shubham Narlawar
2022-01-16 23:53 ` David Malcolm
2022-01-17  8:25   ` Richard Biener
2022-01-17 19:18     ` Shubham Narlawar
2022-01-17 20:49       ` Martin Sebor [this message]
2022-01-18 18:45         ` Shubham Narlawar
2022-01-18  8:50       ` Richard Biener
2022-01-18 18:50         ` Shubham Narlawar
2022-01-17 19:18   ` Shubham Narlawar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d2e2bebe-8cc1-b6a2-c68a-716f73d6bfca@gmail.com \
    --to=msebor@gmail.com \
    --cc=gcc@gcc.gnu.org \
    --cc=gsocshubham@gmail.com \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).