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.