* Re: 2.2.0 and egcs 1.1 was Re: Sorry, wrong gcc-version
[not found] <Pine.LNX.3.96.981025144701.3859K-100000@penguin.transmeta.com>
@ 1998-10-26 3:07 ` David S. Miller
1998-10-26 10:58 ` Bernd Schmidt
1 sibling, 0 replies; 2+ messages in thread
From: David S. Miller @ 1998-10-26 3:07 UTC (permalink / raw)
To: torvalds; +Cc: ak, khim, linux-kernel, crux
Date: Sun, 25 Oct 1998 14:55:09 -0800 (PST)
From: Linus Torvalds <torvalds@transmeta.com>
For example, everybody in the egcs camp just decided that clobbers
and inputs must not overlap. Nobody told me why, and why they can't
just be automatically converted to early-clobbers inside gcc.
You're telling the compiler two different things which conflict.
The gcc documentation indicates how the design of the asm construct
was really geared for single assembler instructions, and the
constraint/clobber specification works in a much more sensible way if
you only use it in this manner. Of course, we all have used it in a
much more broad sense to use multiple assembler instructions and a lot
of people screw up the "input operand only" case.
The reload pass of the compiler groups operands for a single piece of
RTL (the internal representation of "instructions" in gcc) into
several groups when it sees register pressure and must create relods.
These are:
1) Input reloads
Such operands must have the specified value on input to the
instruction. They will still have this specified value upon
completion of the instructions execution.
2) Output reloads
Such operands will be killed by this instruction and set is to some
value which will be set upon completion of the instruction.
3) Address reloads
These deal with address formation for memory operands found in the
RTL for a particular instruction and sometimes require secondary
reloads to be created (to deal with cases such as when the address
must be in a single register because the usage does not allow an
offsettable [reg + offset] type addressing mode, ie. the 'o'
constraint)
When the compiler scans an instruction for an instruction it says:
1) What must be in registers upon entry to this instruction.
These are the input reloads, once assigned a register life analysis
marks these registers as containin the specified value upon input
and also upon exit from the instruction.
2) Which registers get killed as the "last thing" this instruction
does. That is, with a simple example:
add DEST, SRC
DEST would be an output reload, and so far gcc can legitimately
load the SRC value into DEST and just use DEST twice in the
instruction unless...
3) Which input and output reloads conflict.
When you say that an input and output don't need to be in the same
register value, it will use the same register for input and output
reloads as it sees profitable. Unless you specify early clobber
with '&' in the constraints the compiler can legitimately use the
same register for arbitrary input and output reloads.
4) Which registers die in some unspecified way during this
instruction. This is an explicit clobber.
So in the case being mentioned you are telling the compiler that a
particular (in fact a specific) register is an "input only" operand
and it dies in some unspecified way during this instruction. So I
just scanned the gcc documentation and I see:
Some instructions clobber specific hard registers. To describe
this, write a third colon after the input operands, followed by the
names of the clobbered hard registers (given as strings).
If I'm not trying to be pedantic about all this, I would interpret
this to mean "if you cannot describe what happens to a hard register
using constraints, then use clobbers".
It seems to imply that "constraint mentioned" registers and clobbers
are mutually exclusive.
So in my view either such input constraints are spurious and
inaccurate, or one is using clobbers to describe what output
constraints are there for.
Later,
David S. Miller
davem@dm.cobaltmicro.com
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: 2.2.0 and egcs 1.1 was Re: Sorry, wrong gcc-version
[not found] <Pine.LNX.3.96.981025144701.3859K-100000@penguin.transmeta.com>
1998-10-26 3:07 ` 2.2.0 and egcs 1.1 was Re: Sorry, wrong gcc-version David S. Miller
@ 1998-10-26 10:58 ` Bernd Schmidt
1 sibling, 0 replies; 2+ messages in thread
From: Bernd Schmidt @ 1998-10-26 10:58 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andi Kleen, Khimenko Victor, linux-kernel
> > Actually this is not entirely correct. Even 2.1.x kernels still have lots
> > of incorrect inline assembler constraints which can cause the compiler
> > to misoptimize the kernel.
First, I should note that there are two issues here: we have bugs related to
inline assembly in both the kernel, and in the compiler. The compiler bugs
are present in every version of gcc, not just gcc-2.8 or egcs.
1. Explicitly clobbering a register is supposed to make it unavailable for
both inputs and outputs of the same statement. This rule has been there
for a long time; it's documented at least since gcc-2.6.0 (I have no earlier
docs available at the moment; I suspect it's been there forever). This is
from gcc.info, version 2.6.0:
The input operands are guaranteed not to use any of the clobbered
registers, and neither will the output operands' addresses, so you can
read and write the clobbered registers as many times as you like.
[Obviously, the clobbered regs aren't used for output operands either.]
Thus, using a construct like
__asm__ (" " : : "a" (somevalue) : "eax")
is incorrect. This sort of thing occurs in the kernel, and it's a bug.
It should be written as
__asm__ (" " : "=&a" (dummy) : "0" (somevalue));
2. Clobbers are dangerous on the i386. The compiler can't guarantee that
even for a correctly-written asm, the clobbered register will not be used
for another operand. Thus, it is highly advisable not to use clobbers
at all, and to use earlyclobbers as described above. This is a compiler
bug, and it's very closely related to the one that lets you use "a" as
a constraint in the example above.
All of this only affects the i386 and other machines for which gcc has to
define the macro SMALL_REGISTER_CLASSES in the machine description. Without
this macro, which normally isn't defined, gcc doesn't use registers which
are explicitly mentioned anywhere in the internal representation at all for
other purposes (like register allocation or for spill registers). That makes
the code correct, but it would also make the compiler fail to work at all for
a machine where registers can be used explicitly (like eax as the function
return value) and be necessary for certain instructions (like some
multiplications that also require eax).
Thus, on most machines supported by gcc the incorrect asm statement above
would cause a spill failure error, if it could be written for other machines
(most other machine descriptions don't have single-register register classes).
> I don't agree.
>
> The assembler used to be correct, and the gcc people unilaterally decided
> to change the rules. As such, I don't think the asm is any more
> "incorrect" than the new gcc versions are incorrect.
The assembler never was correct. It happens to work most of the time, because
even when SMALL_REGISTER_CLASSES is defined, the compiler puts the explicitly
mentioned registers at the end of the list that it chooses its reload regs
from. Only when it can't find any other register will it use any of the
explicitly mentioned ones.
> The changes I have seen break older compilers.
In what ways?
> So Andi, don't go saying that the kernel has problems, when it is equally
> true to say that gcc has problems.
Right. Both have problems. I'm currently working with the egcs people to
fix the ones in gcc (make the compiler generate errors for the illegal asms,
and avoid the whole SMALL_REGISTER_CLASSES nonsense). However, once the
compiler is fixed, the current kernels will fail to compile.
> > In short, if you want to play safe stay with 2.7.2.3 for kernel compilation.
>
> That, I think, everybody can agree on.
Except that 2.7.2 is buggy as hell. It has the same problems as egcs when
it comes to asm statements, it just happens you may not have seen them yet.
Fact is, any change in the kernel could cause the 2.7.2 to fall over just
as well.
> For example, everybody in the egcs camp just decided that clobbers and
> inputs must not overlap. Nobody told me why,
Because it's documented that way. Because on sane machines, it has always
worked that way.
You seem to suggest that the meaning of clobbered registers should be
redefined so that they work the way you expect them to work. Technically,
that's feasible. However, for the kernel inline assembly, you'd be left with
the oh-so-stable gcc-2.7.2 which still doesn't work properly. Worse,
redefining the meaning of clobbers will suddenly make hundreds of correctly
written asm statements for other machines as well as for the i386 generate
incorrect code silently. Are you seriously proposing this is a good idea?
> and why they can't just be
> automatically converted to early-clobbers inside gcc.
Clobbers in an asm statement can use a register number. The operands need
a register class. There may not be a register class for a register you want
to clobber (consider clobbering ebp which has no corresponding register class).
Bernd
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~1998-10-26 4:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <Pine.LNX.3.96.981025144701.3859K-100000@penguin.transmeta.com>
1998-10-26 3:07 ` 2.2.0 and egcs 1.1 was Re: Sorry, wrong gcc-version David S. Miller
1998-10-26 10:58 ` Bernd Schmidt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.