Messages in this thread | | | Subject | Re: [PATCH] proc: use #pragma once | From | Rasmus Villemoes <> | Date | Fri, 4 May 2018 01:23:12 +0200 |
| |
On 2018-05-04 00:42, Al Viro wrote: > On Fri, May 04, 2018 at 12:14:57AM +0200, Rasmus Villemoes wrote: > >> FWIW, it's not just removing some identifiers from cpp's hash tables, it >> also reduces I/O: Due to our header mess, we have some cyclic includes, >> e.g mm.h -> memremap.h -> mm.h. While parsing mm.h, cpp sees the #define >> _LINUX_MM_H, then goes parsing memremap.h, but since it hasn't reached >> the end of mm.h yet (seeing that there's nothing but comments outside >> the #ifndef/#endif pair), it hasn't had a chance to set the internal >> flag for mm.h, so it goes slurping in mm.h again. Obviously, the >> definedness of _LINUX_MM_H at that point means it "only" has to parse >> those 87K for comments and matching up #ifs, #ifdefs,#endifs etc. With >> #pragma once, the flag gets set for mm.h immediately, so the #include >> from memremap.h is entirely ignored. This can easily be verified with >> strace. And mm.h is not the only header getting read twice. > > Which gcc version it is?
When I stumbled on this a few years ago (I was stracing gcc for some reason), 4.something. Verifying today, 5.4.
> Does it *really* read anything twice?
Yes, just do "strace -f" and grep 'open.*= [0-9]'.
> After all, you are going to read (and tokenize) the rest of mm.h anyway, so if it > throws away the file it has read, only to reread it again, it's bloody > dumb.
Hm, yes, gcc should be able to hang the buffer off of the structure it keeps around anyway for tracking the status of mm.h. But it doesn't.
> Note that sequence of preprocessor tokens does not depend upon the ifdefs; > anything under #if 0 *is* tokenized all the same. So it's not even that > "parsing" (tokenizing, actually) has to be repeated.
Are you sure about that? Maybe formally it has to (if the phases are done strictly sequentially), but can't it go into some fast-forward mode under #if 0 (or #ifndef $some-defined-macro) where it only looks for string and char literals, comments and "control-flow" directives? libcpp/internal.h does have
/* True if we are skipping a failed conditional group. */ unsigned char skipping;
Rasmus
| |