This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Linux and aliasing?



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]