From mboxrd@z Thu Jan 1 00:00:00 1970 From: Linus Torvalds To: Joe Buck Cc: craig@jcb-sc.com, mark@codesourcery.com, davem@redhat.com, chip@perlsupport.com, egcs@egcs.cygnus.com Subject: Re: Linux and aliasing? Date: Wed, 30 Jun 1999 15:43:00 -0000 Message-ID: References: <199906041700.KAA19279@atrus.synopsys.com> X-SW-Source: 1999-06n/msg00161.html Message-ID: <19990630154300.SHx2mkOk4PfvtycwJeFCRWo-Wo1uLYi2sLTUsIWUFFc@z> Ok. Only real technical details. Please shoot it down on technical issues. On Fri, 4 Jun 1999, Joe Buck wrote: > > > _I_ think my simple extension was perfectly legitimate, adn a _lot_ more > > obvious than a lot of things people are discussing on the lists. > > Your "simple extension" will have the effect of -fno-strict-aliasing > for any function that does any pointer cast (there may be marginal > differences if there are loops before the first cast). So why not just use > -fno-strict-aliasing and get the same code? Well, the biggest advantage I see for having the alias type checking is that it allows re-ordering of operations _everywhere_, even if there is no other a priori reason to allow it. A function that does a pointer cast would _not_ be affected globally even under my scheme. It would just mean that that particular access that is affected would be marked as being in alias set zero. Hmm.. I really expected this to be simple, but judging by the amount of traffic it has generated it is obvious that I went about this the wrong way. Sorry. I really didn't mean to start a flame war, and let me back up a bit. To me, the fact that the scheme should be easy to implement is actually really important. I'm not a gcc hacker, and it's been several years since I actually submitted patches to gcc (and even then they weren't always accepted, although I can claim credit for some of the alpha fixes). But I really tried to come up with something that wasn't just easy for the users but that I thought would be easy to do inside gcc. So with that background, and the further explanation that if I _am_ wrong (entirely possible), and it's a rats nest to implement in gcc, then it very obviously _should_ be discarded out-of-hand. It really wasn't a case of me just trying to make life harder for people. Let me explain what my concept was on a more technical level, and then people can shoot holes in it on a technical level and maybe we can avoid too much more flamage. Sorry. I kind of took the technical part for granted. So on a technical level, let me explain it the way I thought gcc might implement this rather than explaining the end result as I initially went about. Maybe people would understand (and accept) what my idea was better this way. What I would actually do if I knew gcc better is do something like this: - add a new type attribute bit. There are plenty of these already, so this isn't a big issue. I didn't worry about naming, because although it _could_ probably be used in typedefs directly, it probably never would be. But who knows? Somebody might have a good reason to make some type always have the "this can alias anything" behaviour, and it could in fact be used for the C "char *" type, so that the ANSI special "char *" rules would be just a subset of this. Let's call the attribute "noalias" just for obvious reasons. - the attribute bit magically gets set by any explicit cast when (and this obviously _would_ be controlled by a gcc option like "-fcast-invalidates-alias", so people who don't like the extended semantics wouldn't be affected). This can be done at parse time, it looks pretty trivial to me. I may be wrong. Think of this part as another simple rule: a typecast always implies the "noalias" attribute if the global flag is set. Nothing else would imply that attribute. - the attribute percolates down normal pointer arithmetic, but NOTHING else. It doesn't inherit across a assignment (although with a named attribute the assigned variable migth have that attribute natively). You already have the notion of attribute inheritace, this is nothing new. In fact, I think the inheritance rules are basically the same as for the "volatile" attribute, but I haven't really verified that. - a alias set query will always return zero for a expression with that attribute set. And that's it. The above doesn't really explain what I'm trying to _achieve_, it only explains the way I thought those goals would be achieved. So for example, just to make the suggestion more "tangible" to the people who actually think in terms of gcc code, look at int get_alias_set (t) tree t; in tree.c, and mentally imagine adding a simple condition that just says something like if (!flag_strict_aliasing || !lang_get_alias_set) /* If we're not doing any lanaguage-specific alias analysis, just assume everything aliases everything else. */ return 0; + else if (lookup_attribute("noalias", t->attribute)) + return 0 else return (*lang_get_alias_set) (t); and that's the only real place where it is tested. The attribute is set when parsing the type casting, and in my "clean up 'char *' semantics" extension it would also always be set for any "char *" type. In that case the special casing of "char *" can go away, so you'd actually _remove_ the code in c-common.c that says else if (signed_variant == signed_char_type_node) /* The C standard guarantess that any object may be accessed via an lvalue that has character type. We don't have to check for unsigned_char_type_node or char_type_node because we are specifically looking at the signed variant. */ TYPE_ALIAS_SET (type) = 0; but that's a detail that I just show to point out the ramifications of the _idea_ rather than advocating as something that should necessarily be done. But it would conceptually put the decision in one place, which is nice. (To me, when I judge peoples ideas about kernel changes, a personally important criterion is always "does it conceptually solve _multiple_ problems?", and an idea that can be used to solve another thing is something that I consider more interesting and consider to be more "flexible". I don't know if the egcs people use that same strategy, but I wanted to point it out in case others have similar decision making methods to the ones I use). > OK, maybe we can get somewhere. It seems to me that there are only two > options for gcc-2.95 on this issue: > > Either > 1. Leave it as it is (the Linux kernel will need -fno-strict-aliasing). > > or > > 2. Don't enable the new optimization for C unless the user says > -fstrict-aliasing. > > Since C++ is fussier about type safety, we could make it the default for > C++ (nice to get those C++ critics who falsely claim C++ is slower than > C ;-). > > Which would you recommend? If I did the same decision, I would just make the new feature the default, to make sure it got tested. I don't really disagree about that - it _does_ rub peoples faces into the issue, and it _will_ make others complain too and you'll end up explaining to a lot of people what the aliasing issues really are, but it still makes sense to enable it by default to get better coverage on it. Have an open mind, and be ready to decide that if there turns out to be a lot of people that get bitten by it you should just turn it off by default (and for example the eventual decision might be to only turn it on at optimization level 3 instead of 2, as -O2 tends to be a fairly common optimization level because it does so much else on gcc too..). I really only want to make sure that _eventually_ I can take advantage of type-aliasing, while at the same time having a convenient back door for when the kernel does the ugly things.. Do people see any obvious problems in the technical idea above? It looks very maintainable and clean to me, but I'll readily admit that I only look at the problem from ten thousand feet when it comes to the compiler side. Maybe it is just completely unusable for some reason I missed.. Linus