This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH 0/2] Require that constraints are used to reference global regs
Hi,
On Mon, 23 Apr 2018, Alexander Monakov wrote:
> I don't see how a user reading the documentation could infer that asms
> and global reg vars interact like you say.
That was always my interpretation of this clause (old docu, the current
bullet list seems to have removed some clarity) and memories of old code
in the compiler:
------------------
Defining a global register variable in a certain register reserves that
register entirely for this use, at least within the current compilation.
The register will not be allocated for any other purpose in the
functions in the current compilation.
------------------
It never occured to me that this wouldn't include implicit dependencies
from asms to each occurrence of the global reg var, though in re-reading I
now see how it could be interpreted as such (i.e. that there are no such
implicit dependencies). In my mind accesses to global reg vars are
volatile, though I also see that my mind might have made that up years ago
as well. Probably the sub-phrase "Stores into this register are never
deleted even if they would appear to be dead," caused this (indicating
volatile-like), even though it continues to say "but references may be
deleted or moved or simplified." (indicating non-volatile-like).
> (indications to the contrary can be found on the other hand, e.g.
> "It also does not know about side effects of the assembler code, such as
> modifications to memory or registers. Unlike some compilers, GCC assumes that no
> changes to general purpose registers occur. " in Basic Asm section)
>
> What am I missing?
Maybe nothing, your reading of the docu seems valid. If that really
reflects the intent is of course another question.
> > Sure, so the other scanners need fixing as well. An alternative is to
> > massage the asms while constructing them (e.g. gimplification time) to
> > read and write all global reg var registers. Then all scanners will
> > automatically work.
>
> Yes, but that is problematic since on some backends global_regs is
> non-empty (e.g. rs6000, tile*) so it would tie all asms (it's also a
> problem with the current DF behavior).
[side remark:
I think these are misuses and should rather set fixed_regs (I see
other back-ends also set some global_regs members): there should be a
reg-set which precisely captures the user-declared global register
variables, and nothing more, which then would avoid the problem (and tie
only asms when global reg vars are in scope, but would do so with all of
them indeed). But even if we decide that these are mistakes it's probably
non-trivial to fix without regressions (short of inventing something
dubious like still another reg-set used for globalize_reg() that wouldn't
be exported and hence not available to backends).]
> > IMHO we can't define our bugs away in this way, after saying for
> > decades how something is supposed to work. Especially not rushing it
> > in a couple days before release.
>
> I honestly don't see where GCC was indicating how it's supposed to work.
Given all the above I don't see it either anymore. I do remember several
threads of discussions with various people over the years that always
assumed that asms can validly implicitly refer to registers of global reg
vars and expect everything to work, and I do remember code in GCC that
tried to make sure to not mess that up. Looking for some minutes I find
e.g. old regcprop (at the time still regrename.c:copy_value):
/* Do not propagate copies to fixed or global registers, patterns
can be relying to see particular fixed register or users can
expect the chosen global register in asm. */
if (fixed_regs[dr] || global_regs[dr])
return;
(Note the last part of the comment "users can expect the chosen global
register in asm"). Also, a snippet from flow.c:mark_used_regs():
/* Traditional and volatile asm instructions must be considered to use
and clobber all hard registers, all pseudo-registers and all of
memory. So must TRAP_IF and UNSPEC_VOLATILE operations.
(it then goes on to say that making all these explicit creates other
problems and so doesn't in fact do as the comment says. Those compilers
deal with that by not inferring much from volatile asms or propagating
things over them.)
So, there definitely once was code (or comments) trying to make sure at
least volatile asms had access to global reg vars even without explicitely
mentioning them. It might already have been incomplete at that time, or
it only might have become inconsistent and incomplete since then
(certainly we became more aggressive with any implicit things about
extended asms), and most probably the changes that did occur in that area
weren't all intentional. Hence I can't even begin to guess if a full
change to only explicit dependencies would break existing code or not;
global reg vars are not used very often, so there's a chance we might
break all 10 users in the world, or none :)
Sooo, hmm, I don't know ;-) We could try doing a roll backwards and
demand explicit dependencies from asms with unknown effects on the few
unknown users, though the timing really makes me nervous. But my gut
feeling says to remain (or become again) very conservative with global reg
vars (and document that for real then!).
Ciao,
Michael.