This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC] Suggested replacement for specs and switch handling
- To: Neil Booth <neil at daikokuya dot demon dot co dot uk>
- Subject: Re: [RFC] Suggested replacement for specs and switch handling
- From: "Zack Weinberg" <zackw at Stanford dot EDU>
- Date: Wed, 27 Jun 2001 00:34:51 -0700
- Cc: gcc at gcc dot gnu dot org
On Sun, Jun 24, 2001 at 09:33:45PM +0100, Neil Booth wrote:
>
> > First, I agree with Joseph that the option table should be broken up
> > by front end. It does no great harm to have an option mentioned in
> > multiple tables - you have to sort it anyway, so you can weed out the
> > duplicates then. It will be more initial work but it will definitely
> > be easier to maintain.
>
> OK, sigh. I was hoping to get something in and refine it later. It
> is more work to work on large bodies of code that are out of CVS; and
> it also means only one person can work on it.
I'm being cautious. Whatever we do involves changing every target and
every front end. That means we have to get it right the first time
(and I've perpetrated a couple of bogus patches that touched tons of
targets...)
A branch may be a good idea here. That insulates the project from the
constant churn on the mainline, allows us to change targets
incrementally, and doesn't have any of the problems with bouncing
around huge patches. I remember some of the joys of _that_ from last
year...
> > The flag letters are also going to cause confusion. I'd like to
> > suggest something a bit more verbose and less cryptic. If the time to
> > parse this file is significant, we have bigger problems.
>
> Again, I just wanted to get something working. Things that are
> complex to parse just increase complexity. I wanted to refine stuff
> later. Indeed, lisp-ish like syntax might be good; after all we use
> it everywhere else.
I guess I'm coming at this from a different angle. What you have is
great as proof of concept, but before it starts hitting the tree I
want something solidly designed with all the mechanisms laid out.
That isn't to say it has to be implemented all at once. Things like
dropping front ends in at system integration time, which I saw someone
request, should not be made impossible by this work - but neither
should they hold up the project; after all, we can't do that *now*.
> > > -D pt a +D
> > > -Wstrict-prototypes COX nB Wstrict_prototypes
> > > -falign-jumps= T j falign_jumps_eq
> > > -std=c99 pCO n std=STD_C99
> > > --shared D nAV -shared
> >
> > cpp,tcpp -D% accumulate D
> > cpp,tcpp "-D %" rewrite -D%
> > c,c++,objc -Wstrict-prototypes boolean Wstrict_prototypes
> > backend -falign-jumps=% - falign_jumps_eq
> > cpp,c,objc -std=c99 - std=STD_C99
> > driver --shared abbrev shared
>
> It's nicer, but makes gen-switches a lot more complex (at present it's
> just a quick hack 8-)).
If we can agree on a syntax, I'll volunteer to write the parser. Long
term maintainability is critical here - after all, lack of
maintainability is (a large part of) what's wrong with the current
system.
> You need to handle optional arguments in your scheme (that's how I
> handle some switches like "-g" at present, with an "o" flag). What
> would you suggest?
Blast, I forgot about that.
Someone else suggested using rewrite rules to deal with that. Or, for
at least some of these options, it works to have a default argument:
backend,cpp -O% default=1 O
making -O equivalent to -O1.
And if you can distinguish -I- from -I%, it seems to me you can
distinguish -I from -I% as well, if you see what I mean?
> > [For straight up aliases, where multiple options mean the same thing,
> > why not simply tag them all with the same group code? The
> > contradictory-switches-in-same-group issue can be handled through
> > group values only; frex, --shared and -shared both set the 'shared'
> > group to true, so no conflict.]
>
> Yes, there are 2 ways to do it. I did some one way, some the other,
> for variety :-)
This isn't Perl here; let's keep the number of ways to do things to a
minimum.
> > help {
> > -Dname Define a macro with value 1
> > -Dname=expansion Define a macro with value EXPANSION
> > ...
> > }
>
> Help in it's own section might be a good idea. If we put texinfo in
> too, we'd need some way to break it into the separate menus under the
> Invocation section, too.
Generating .texi files at build time may be a non-starter, since we
don't require people to have makeinfo.
In the abstract, I like the idea, though.
> > validate {
> > falign_jumps_eq posint Argument of "-falign-jumps" must be a positive integer.
> > ...
> > }
>
> OK, but is this an improvement on just making the check with a
> parse_integer subroutine called from a large switch statement (much
> like we do now)?
Maybe not. I threw out the idea for reactions, mostly.
> > Concerns about losing run-time configurability are a problem. We need
> > to know just what the libjava people and the embedded people need to
> > do with their add-on specs. Looking at libgcj.spec, it appears to be
> > simply a matter of injecting extra options under certain conditions.
>
> I am hoping that they are only simple transformations. They can't be
> complicated after all, because anything complicated like a new
> category of switch would require a driver recompile anyway.
It seems to me that the real issue here is that we have all sorts of
/ad hoc/ ways of tweaking driver behavior, none of which is really
adequate to the job.
I don't have a problem with breaking what the embedded people do
temporarily. I have more of a problem with breaking libjava; however,
if it's not immediately clear how to do what they need, breaking it
for a short time would be preferable to locking ourselves into a
nonviable model.
I'd like to squash any suggestion of shell script wrappers right here
and now. For one thing, you can forget any performance improvement.
For another, the Bourne shell is rather bad at argument lists,
especially if they have "interesting" characters in them - and the
list of "interesting" characters is much too large.
We had a shell script wrapper for /usr/bin/cpp instead of a custom
driver, for awhile. It was crap, and I'm fairly sure it was crap
because sh was the wrong tool for the job.
So I think we need to make an effort to ensure that people *don't*
need to use shell script wrappers.
Just for reference, this is the libgcj.spec installed by 3.0 libgcj
(from the libgcj2-dev package from Debian unstable):
# This spec file is read by gcj when linking.
# It is used to specify the standard libraries we need in order
# to link with libgcj.
#
%rename lib liborig
*lib: -lgcj -lm -lgcjgc -lpthread -lz -ldl %(libgcc) %(liborig)
*jc1: -fuse-divide-subroutine -fuse-boehm-gc -fnon-call-exceptions
# On some systems we force in a data_start symbol so that the GC will work
# with shared libraries.
#
%rename startfile startfileorig
*startfile: %(startfileorig)
They appear to use a slightly different one for the testsuite; my
knee-jerk guess as to why is that it's another place we have to work
around libtool.
> > #! /usr/bin/gccdriver-3.1
> > # Tweaks for cpp.
> > stage E
> > gcc 0
> > default-lang c
> > .s assembler-with-cpp
...
> It's a nice idea. Again, I don't want to attempt too much before we
> have something concrete in CVS. It just takes longer and is more
> fragile. When we have something in place, it also becomes clearer how
> to refine it further. With nothing there, there is some guesswork
> involved.
Sure, as long as we can start with an agreement of what it eventually
does need to do, and a reasonably working prototype.
> > You haven't said anything about two other things which are currently
> > handled, badly, by specs. One is the logic which decides which
> > series of programs is to act on any given file. You know, this mess:
> >
> > %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) ... }}}}}}
> >
> > I don't have a good idea what to do about this, but it needs to handle
> > -M -MF properly.
>
> All that logic is really easy. Sorry I didn't explain the use of the
> returned structure from parse_switches() fully, I thought it was
> clear. The structure that is filled in on return from
> parse_switches() has an array (0 ... N_GROUPS-1) with one entry for
> each option group, that contains the index of the first command line
> argument (1 ... argc) where it appears. Zero means didn't appear.
You realize that that is going to be a huge vector.
If it can replace a bunch of the global variables currently being set
from the command line, however, that won't be a problem.
> This allows O(1) checks if a switch appeared. Also, Chains like -I
> are easy traversible since they appear in a singly-linked list,
> starting wherever this index points. [Note this would completely
> remove all the crud in cppinit.c to do with appending stuff into
> chains. In fact, cppinit.c becomes a lot simpler.]
Oh yeah. I'd like to shove -iprefix and friends completely into the
driver, if that's feasible. Matter of fact, I'd like to shove the
entire default include path into the driver, such that cpplib has *no*
hardwired paths in it.
> So the above SPEC would become something like
>
> if (array[GP_f_syntax_only] == 0
> && array[GP_stage] != 'c' (assuming 'c' is in a stage group)
> && ...)
> do_linker_stuff ();
>
> Since much of this conditional logic is repeated, the driver could
> even put common stuff in boolean variables, like want_compiler, and
> want_assembler. That would simplify the conditional statements even
> more.
That sounds good to me, particularly with the common booleans.
--
zw But your argument is simply post hoc ergo ante hoc.
-- Umberto Eco, _Foucault's Pendulum_