This is the mail archive of the
mailing list for the GCC project.
Re: Register-passed arguments copied to the stack?
Hi Vladimir, and thanks for the informative reply.
> The compiler uses virtual registers for scalar variables/arguments. As I
> understand hard registers 4 and 5 are copied into virtual registers during
> rtl generation. After that the global register allocator decides not to
> assign the pseudo-registers to hard-registers. Reload follows the
> assignment and changes the pseudo-registers to the stack slots.
Is it so? If I do a dump right after RTL generation (with -dr, before
reloading) I can see that registers 4 and 5 are already copied to exactly the
same stack slots. So to me it doesn't look like it's the reloading pass that
assigned them there, otherwise in the .01.rtl dump registers 4 and 5 would
have been copied to pseudo registers, right?
Actually I've looked at the ARM port too, and it has the same behavior, even
though the first two arguments are passed through registers, they are
immediatly copied into stack slots at the beginning of the function, and
these stack slots are used later in the function instead of the registers
(which makes sense regarding the allocator, at the light of your
The keypoint is that my target is completely abstract. It has no registers and
I make a matching between the GCC representation and my own model, where
things are declared as arguments, local variables, or temporaries (no stack
or registers - yes, it's an assembly language :p). This is a fun sport, but
in these conditions I have no constraints on the "hard" registers used by GCC
and can use as much as them as I want. What I wanted to do is to have a
special class of registers that would only serve as argument registers. This
would be a very easy way to know when I'm using an argument inside a
function, and which one. So of course, the allocator's behavior who wants to
save as many registers as possible (which makes sense of most targets)
doesn't suit what I want to do: having a range of registers used exclusively
(and which are the only way) to pass/use arguments and that can't be assigned
another value. If I could make the compiler be aware of this fact, and
therefore of the fact that it is useless to save these registers, it would be
great. As far as I know, this is not possible, but I don't know very far.
That's why I'm interested in any hint that could help me doing the above (or
any claim that it is not possible).
To explain how I do things in practise:
- CUMULATIVE_ARGS is an integer initialized to the number of the first
argument register and increased by FUNCTION_ARG_ADVANCE.
- FUNCTION_ARG(CUM, ...) generates a rtx for the register number CUM.
FUNCTION_INCOMING_ARG isn't defined.
- The argument registers form a class that is outside of GENERAL_REGS.
Even for this simple function:
void argsfunc(short arg1, char arg2)
The arguments (reg 4 and 5 are arg1 and arg2 respectively) are put into the
stack by the function prologue. I guess this is the prologue since it appears
before the FUNCTION_BEG note (from the .01.rtl dump):
;; Function argsfunc
(note 2 0 3 NOTE_INSN_DELETED)
(insn 3 2 4 (set (mem/f:HI (reg/f:SI 25 virtual-stack-vars) [0 arg1+0 S2 A8])
(reg:HI 4 (null) [ arg1 ])) -1 (nil)
(insn 4 3 5 (set (mem/f:QI (plus:SI (reg/f:SI 25 virtual-stack-vars)
(const_int 2 [0x2])) [0 arg2+0 S1 A8])
(reg:QI 5 (null) [ arg2 ])) -1 (nil)
(note 5 4 6 NOTE_INSN_FUNCTION_BEG)
(note 6 5 7 NOTE_INSN_DELETED)
(note 7 6 9 NOTE_INSN_FUNCTION_END)
From the caller, everything goes fine and I have no mapping problem. From the
callee however, this makes things hard to handle. If I could keep the
arguments into these registers from beginning to end, that would be simply
> So you could try to use the new register allocator to solve the problem.
> But the new register allocator works worse for machine with small register
> file (like x86). IMHO, It is important to take CFG information into
> account for small register file. The colour based register allocator does
> not take this information into account.
I'll have a look at it. I'm sceptical about the actual results for my case
(won't make the compiler more aware of my particular register distribution),
but it'd be a good occasion to see it.