This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 
explanations).

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)
    (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)
    (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 
great.

>   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.

Alex.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]