getting non-global variable names from RTL
Mihai Burcea
burceam@eecg.toronto.edu
Tue Feb 24 20:58:00 GMT 2004
Hi,
And thanks a lot for the help.
You're probably right, I should have given an example.
Here is what the source code for the function whose arguments I want to
identify looks like:
-----------code starts
void quake__ompc_func_10 (__ompc_args)
void **__ompc_args;
{
auto int **_pp_temp1;
auto int **_pp_temp2;
auto double **_pp_bigdist1;
auto double **_pp_bigdist2;
(_pp_temp1) = (((int **) (*__ompc_args)));
(_pp_temp2) = (((int **) (*((__ompc_args) + (1)))));
(_pp_bigdist1) = (((double **) (*((__ompc_args) + (2)))));
(_pp_bigdist2) = (((double **) (*((__ompc_args) + (3)))));
.... irrelevant stuff.
-----code ends
What my pass is trying to do is identify the variables that are being sent
to the function, and replace them with constants (it's some sort of
primitive constant propagation).
However, in my particular case, in the caller of the function, all the
arguments that are being sent to the function are always encapsulated in
a void *: _ompc_args, as you can see above.
And the first thing that the happens in the function is of course
extracting those arguments from the stack.
Although following Mr. Zlomek's suggestion I managed to use some of his
(and others') code, I got what I should have expected: the function's only
argument is of course, ompc_args. Which doesn't help me really, because
what I need is to know those variables, _pp_temp1, _pp_temp2,
_pp_bigdist1, _pp_bigdist2. I need the names of all those variables (or
some way to get to their names).
What I've been trying to do lately is try to identify some pattern in the
generated RTL code that relates to extracting these variables from the
stack, and get their names from there.
For instance, the RTL code looked like this:
(insn 16 6 17 (nil) (set (reg/f:SI 58)
(mem/f:SI (reg/f:SI 53 virtual-incoming-args) [0 __ompc_args+0 S4
A32]))
-1 (nil)
(nil))
(insn 17 16 18 (nil) (set (reg:SI 59)
(mem:SI (reg/f:SI 58) [0 S4 A32])) -1 (nil)
(nil))
(insn 18 17 20 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -68 [0xffffffbc])) [0 _pp_temp1+0 S4 A32])
(reg:SI 59)) -1 (nil)
(nil))
(insn 20 18 21 (nil) (parallel [
(set (reg/f:SI 60)
(plus:SI (mem/f:SI (reg/f:SI 53 virtual-incoming-args) [0 __ompc_args+0 S4 A32]
(const_int 4 [0x4])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 21 20 22 (nil) (set (reg:SI 61)
(mem:SI (reg/f:SI 60) [0 S4 A32])) -1 (nil)
(nil))
(insn 22 21 24 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -72 [0xffffffb8])) [0 _pp_temp2+0 S4 A32])
(reg:SI 61)) -1 (nil)
(nil))
-------------
and similarly for the other 2 variables.
Like I said, right now I'm trying to identify a pattern in the sequence of
insns, so that I can always find and identify the variables based on that
pattern (e.g., I first look for the first occurrence of a set (mem (reg
54))) (because I know reg 54 will always be VIRTUAL_STACK_VARS_REGNUM),
and I check the name of the variable, and that's the first one.
Same way for the other ones.
But this seems very unsafe to me, because I am always looking for insn of
a specific format; if that format ever changes in the slightest bit, I'd
have to rewrite the whole code.
Moreover, another problem is that my pass is after .01.sibling (If need
be I can move it right after .00.rtl), and I don't seem to have the
variable name info in there. The code from the .01.sibling file looks like
this:
--------------------code starts
note 133 2 3 0 [bb 0] NOTE_INSN_BASIC_BLOCK)
(insn 3 133 4 0 (nil) (set (reg/v/f:SI 58)
(mem/f:SI (reg/f:SI 53 virtual-incoming-args) [9 __ompc_args+0 S4
A32])) -1 (nil)
(expr_list:REG_EQUIV (mem/f:SI (reg/f:SI 53 virtual-incoming-args) [9
__ompc_args+0 S4 A32])
(nil)))
(note 4 3 6 0 NOTE_INSN_FUNCTION_BEG)
(note 6 4 17 0 0x4001839c NOTE_INSN_BLOCK_BEG)
(insn 17 6 19 0 (nil) (set (reg/v/f:SI 62)
(mem:SI (reg/v/f:SI 58) [11 S4 A32])) -1 (nil)
(nil))
(insn 19 17 21 0 (nil) (set (reg/v/f:SI 63)
(mem:SI (plus:SI (reg/v/f:SI 58)
(const_int 4 [0x4])) [11 S4 A32])) -1 (nil)
(nil))
(insn 21 19 23 0 (nil) (set (reg/v/f:SI 64)
(mem:SI (plus:SI (reg/v/f:SI 58)
(const_int 8 [0x8])) [11 S4 A32])) -1 (nil)
(nil))
(insn 23 21 32 0 (nil) (set (reg/v/f:SI 65)
(mem:SI (plus:SI (reg/v/f:SI 58)
(const_int 12 [0xc])) [11 S4 A32])) -1 (nil)
(nil))
------------------------code ends
As you can see, it's a totally different strategy of extracting the 4
variables from the stack this time.
So I'm really confused and not sure how to approach this in a somewhat
flexible way...
It would be great if you could suggest what kind of things I can look out
for that will be somewhat constant (as opposed to the significant
difference in the RTL code between .00.rtl and .01.sibling as shown
above).
Of course if you think that my entire approach is wrong, I'd be happy to
take other ideas into consideration.
I hope I've managed to better explain what I'm trying to do this time ;)
Thanks again for all the help.
mihai
On Tue, 24 Feb 2004, Jim Wilson wrote:
> Mihai Burcea wrote:
> > I am writing a small optimization pass for gcc-3.3.1, and I would need to
> > be able to identify the arguments that were passed to the current
> > function on the stack with their counterparts from the source code
>
> It sounds like you want some inter-procedural analysis (IPA) info. This
> is something that gcc does very poorly to not at all.
>
> I suspect the only place that gcc had this info is during function inlining.
>
> There might be some stuff on the tree-ssa branch that would be useful to
> you. It does have some IPA. I don't know how you would get the
> information though, as I don't work on the tree-ssa branch.
>
> It would help if you clarified what you want. Examples are always good.
> --
> Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com
>
>
More information about the Gcc
mailing list