ok@quintus.UUCP (Richard A. O'Keefe) (12/21/87)
'register' is a promise to the compiler: "I faithfully promise not to take the address of this, and if that helps you, fine." This is something the compiler can verify, and if you break your promise the compiler can and should warn you. 'const' is a promise to the compiler: "I faithfully promise not to store through THIS path, and if that helps you, fine." This is something the compiler can verify, and if you break your promise the compiler can and should warn you. This is a positive help to programmers, as if you don't intend to change a parameter, you should declare it const, and the compiler will warn you about a mistaken change (the only known way of catching the writing-"="-instead-of-"==" bug). 'volatile' is a warning to the compiler: "watch out, this thing may change at any time". The compiler cannot verify this, but it is safe for the compiler to believe you; the worst that can happen is loss of speed. 'noalias', however, is a promise to the compiler which the compiler cannot check, which it is NOT safe for the compiler to take on faith. So we have two problems with "noalias" (1) "noalias" does NOT mean "no alias", as Doug Gwyn showed in an example. It means something like "there may be any number of aliases for this thing, one of which has the noalias property, and some of which, due to casting, have not, but changes will only be done through the version having the noalias property, so the compiler may rely on that version not changing unexpectedly." Whatever the exact rule is, it is something quite different from and more complex than a simple "no aliases" rule, so the name is misleading. (2) Believing the programmer is not a safe approximation. Judging from some of the examples so far, the intended property may not be computable. Having some way of telling a compiler that something has no aliases sounds like a really good idea. (Euclid did this by making all aliasing illegal. One of the reasons for having storage pools explicit in that language was so that a compiler could tell that two pointers to different pools couldn't possibly be aliases.) But the right way to do this is to come up with some property which the compiler (or a separate checker) can verify, and which implies the property of interest. This is a non-trivial task in language design, especially in the case of C. Rushing it in at the last minute is not a good idea. (3) A snag with things like volatile and noalias is that they clutter up the language. There are a great many things that one might want to tell a compiler. There should be one generic mechanism for all of them. The simplest scheme I can think of is to replace the rule type_qualifier : CONST | VOLATILE ; by type_qualifier : CONST | PRAGMA '(' praginfo ')' ; praginfo : /* empty */ | praginfo primary_expr ; so that one could declare extern pragma(volatile) struct device tty_device; or static pragma(signal_handler) void my_sigfpe_handler(...) { ... } or whatever. The definition of 'praginfo' was carefully designed so that #define pragma(x) could be used in a compiler which didn't yet understand pragma(), but in general a compiler would accept some pragmas and warn about the others. This approach takes one reserved word in the language, but imposes no bound on the number of hints you can give the compiler. If the FORTRAN committee have not found a need to introduce a 'noalias' mechanism into that language (aliasing is quite possible in FORTRAN), what makes C so special? I have seen the February '87 draft of the FORTRAN 8X (they'd better hurry) standard. That's getting to be a very complicated language indeed (user-defined types, with parameters yet!) but they still hadn't put 'noalias' in. The approach taken by the majority of other programming languages is that if you change one alias of a location and then access it via another location it's your own silly fault if you don't get the answer you expected. I can't think of any of my own C programs where it would not have been appropriate to declare ALL variables 'noalias'. So that's a fourth problem with noalias: it's back to front. Why not simply say that the compiler is entitled to assume 'noalias' for everything, and that if the programmer wants unsafe aliases s/he should declare the variables in question to be 'volatile'? Doesn't "volatile" mean that a variable may change behind the compiler's back, and isn't that exactly what we want here? This might perhaps be a "Quiet Change", but nobody ever told me that aliasing was supposed to be legal in C, so even that isn't clear. I don't see why having noalias as the basic assumption should be any more of a burden on me in C than it is in FORTRAN.
mmengel@cuuxb.ATT.COM (Marc W. Mengel) (12/23/87)
<> In article <485@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: ... >'noalias', however, is a promise to the compiler which the > compiler cannot check, which it is NOT safe for the > compiler to take on faith. > Actually, I thought the whole point was to put noalias in simply because the compiler cannot check it... That is, there are optimizations possible if you know that a pointer isn't aliased, and the only person who can possibly tell this for real is the programmer. Now you tell me the compiler cannot "safely" take this "on faith". Well, the compler can't "safely" take pointer casts like converting a (char *) to a (float *) "safely", after all, there could be allignment problems. A C compiler *has* to take things like noalias and pointer casts on faith because there is *not* any way to check for them in the language. >So we have two problems with "noalias" >(1) "noalias" does NOT mean "no alias", as Doug Gwyn showed in > an example. It means something like "there may be any number of > aliases for this thing, one of which has the noalias property, > and some of which, due to casting, have not, but changes will > only be done through the version having the noalias property, > so the compiler may rely on that version not changing > unexpectedly." Whatever the exact rule is, it is something > quite different from and more complex than a simple "no aliases" > rule, so the name is misleading. Mark Twain used to say that "a man who doesn't read is no better off than a man who can't read". If there is another pointer to the location pointed to by a "noalias" pointer that the programmer is certain can't end up being used in the scope of the "noalias" pointer, that means the programmer knows the optimizations are okay, and the programmer can *tell* the compiler he knows that they're okay. >(2) Believing the programmer is not a safe approximation. > Judging from some of the examples so far, the intended property > may not be computable. Right. It is NOT computable. Therfore you (the compiler) *have* to believe the programmer, since you can't figure it out yourself. In C, we believe the programmer about a lot of things: Pointer casts Function arguments (pre ANSI,anyhow) Array Subscripts etc. etc. All of a sudden you think we can't believe the programmer anymore. > >Having some way of telling a compiler that something has no aliases >sounds like a really good idea. (Euclid did this by making all >aliasing illegal ... >) But the right way to do this is to come up with some property which the >compiler (or a separate checker) can verify, and which implies the >property of interest. This is a non-trivial task in language >design, especially in the case of C. Rushing it in at the last >minute is not a good idea. > >(3) A snag with things like volatile and noalias is that they >clutter up the language. There are a great many things that one >might want to tell a compiler. There should be one generic >mechanism for all of them. The simplest scheme I can think of >is to replace the rule ...[long discussion of how we should use pragmas for volatile, noalias, etc.] volatile and noalias are built in to make them mandatory. pragma is there to allow optional extensions. > >If the FORTRAN committee have not found a need to introduce a 'noalias' >mechanism into that language (aliasing is quite possible in FORTRAN), >what makes C so special? I have seen the February '87 draft of the >FORTRAN 8X (they'd better hurry) standard. That's getting to be a >very complicated language indeed (user-defined types, with parameters >yet!) but they still hadn't put 'noalias' in. Fortran uses copy-in copy-out address passing, and (in current implementations) doesn't have an address-of operator. Therefore aliasing is much less of a problem. Take the classic example of complex numbers: typedef float complex[2]; mult( c1, c2, c3 ) complex c1, c2, c3; { c3[0] = c1[0] * c2[0] + c1[1] * c2[1]; c3[1] = c1[1] * c2[0] + c1[1] * c2[0]; } in C this leads to an incorrect complex multiply (by definition) if you call it as: complex c1, c2; ... mult(c1,c2,c1); This is due to "aliasing". Fortran, since it uses copy-in, copy-out argument passing, does not have this problem. (i.e. you get a correct complex multiply implementing complex numbers with arrays this way, since you deal with 3 copies, 2 of c1, one of c2, whose values are copied back out at the end of the procedure.) >The approach taken by the majority of other programming languages is >that if you change one alias of a location and then access it via >another location it's your own silly fault if you don't get the >answer you expected. I can't think of any of my own C programs >where it would not have been appropriate to declare ALL variables >'noalias'. So that's a fourth problem with noalias: it's back to front. The way C is defined, if p1==&a, and p2==&a, then *p1 == *p2 at any given time. This means the compiler is forced to always update the location at the end of a pointer, even when it would be more efficient to hang onto it for a little while, and store it later: p1=&a; p2=&a; *p1 = b; *p1 &= 0xff; printf("%d\n",*p2); *p1 |= 0x100; would be less code if we didn't have to have the right value for *p2. The way C is defined, however, we *do* have to have the right value for *p2 here. "noalias" gives us a way to tell the compiler that its okay not to worry about keeping the memory location at *p1 always in sync, to keep that value of b&0xff around in a register until we compute (b&0xff)|0x100, and then maybe get around to storing it in memory. >Why not simply say that the compiler is entitled to assume 'noalias' >for everything, and that if the programmer wants unsafe aliases s/he >should declare the variables in question to be 'volatile'? Doesn't >"volatile" mean that a variable may change behind the compiler's >back, and isn't that exactly what we want here? Because it breaks existing code, like that above. > >This might perhaps be a "Quiet Change", but nobody ever told me that >aliasing was supposed to be legal in C, so even that isn't clear. >I don't see why having noalias as the basic assumption should be any >more of a burden on me in C than it is in FORTRAN. It is legal, entirely because of the way address of is defined in C. Sure nobody told you it was "legal", nobody said it wasn't, and the operators and syntax allow you to do it. You just assumed it wasn't because you have used languages which prohibit it. -- Marc Mengel attmail!mmengel ...!{moss|lll-crg|mtune|ihnp4}!cuuxb!mmengel
ok@quintus.UUCP (Richard A. O'Keefe) (12/23/87)
In article <1453@cuuxb.ATT.COM>, mmengel@cuuxb.ATT.COM (Marc W. Mengel) writes several times that > Fortran uses copy-in copy-out address passing and says onces that > (in current implementations) doesn't have an address-of operator. Several current implementations DO have an address-of operator, not that it matters. The statement that Fortran uses pass-by-value-return (anyone remember Algol W?) is simply false. >>Some Fortran implementations<< use valret. They are allowed to. Some Fortran implementations use pass-by-reference. They are allowed to. Two Fortran compilers I have used pick different methods for different functions, depending on optimisation level. They are allowed to. If someone writes a Fortran subroutine SUBROUTINE CPXMPY(RA,IA, RB,IB, RC, IC) REAL RA,IA, RB,IB, RC,IC RC = RA*RB - IA*IB IC = RA*IB + RB*IA RETURN END then he is in precisely the same sort of trouble as the C programmer who writes the C function you exhibited. If you CALL CPXMPY(RA,IA, RB,IB, RA,IA) then you are going to have trouble in some Fortran implementations, and it is YOUR fault, not theirs. In fact, just now I tried this with the f77 compiler on a SUN-3/50 running SunOS 3.2. With optimisation off, it gives the "incorrect" answers, due to using pass-by-reference. But with optimisation on (f77 -O foo.f), it gives the "correct" answers, because it is making local copies. BOTH behaviours are in conformance with the standard; it is the >program< which is non-conforming, not the compiler. I would claim that aliasing is a worse problem in Fortran than in C. For example, the option of having cpxmpy accept records and return a record is not available in Fortran 77 (it IS available in Fortran 8X), so there simply isn't any safe way to write this in Fortran, while there is in C. So my question: if people care about optimising Fortran (and they DO) and they care about writing correct programs in Fortran (and they DO) and if aliasing is a problem in Fortran (and I've just shown that it IS), what is so special about C that it needs a 'noalias' declaration? (By the way, there exist tools such as PFORT which can check that the Fortran no-aliasing rules are not violated. But then Fortran is a much simpler language than C.) The point that the C compiler already takes a great deal on blind faith is quite right, and it takes a lot of the steam out of my objections to 'noalias'. But I think that explains the increasing popularity of C interpreters (one that sounded impressive was just announced on the net). My experience has been that programs which use casts a lot are significantly harder to debug than ones which lint is happy with; has yours been any different? Ok, so the boat is leaky; is that any reason to bore more holes in it? I should make it plain that my objection to 'noalias' was more vehement than perhaps was warranted, because on the whole I am tremendously impressed by the work of the ANSI C committee. I am also watching the British Standards Institute working group on Prolog; that is being done in a most unprofessional fashion. I have repeatedly begged them (given that their mandate was to create a standard based on Edinburgh Prolog) to do exactly that, and after some years they finally explicitly rejected the idea. They are busily inventing their own language. After watching that outfit bumble around, the ANSI C committee look amazingly good. -- 'nolias' still does not mean "no alias" so the >name< is bad -- it is still back-to-front -- if "other languages do it" was a good enough argument for giving parentheses more than merely grouping effect, then "other languages do it" is a good enough argument for having "noalias" be the default -- pragma(noalias) is still a better approach {what does #pragma do? Surely a macro processor which may be completely separate from the compiler is the wrong place for such things?} and Marc Mengel has not refuted these claims.
chris@mimsy.UUCP (Chris Torek) (12/23/87)
In article <1453@cuuxb.ATT.COM> mmengel@cuuxb.ATT.COM (Marc W. Mengel) writes: >Fortran uses copy-in copy-out address passing.... Some FORTRAN compilers may indeed use copy-in/copy-out (I believe this is usually called `value-result'), but I think it is not mandated. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
ksb@j.cc.purdue.edu (Kevin Braunsdorf) (12/24/87)
In article <492@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >The statement that Fortran uses pass-by-value-return is simply false. .... Some Fortran implementations use valret. .... .... tools such as PFORT which can check that the aliasing ... .... Fortran no-aliasing rules are not violated .... .... But then Fortran is a much simpler language than C .... .... there simply isn't any safe way to write this in Fortran .... .... while there is in C. FORTRAN? Right: they chose *not* to deal with the aliasing issue by waving their collective hands at it: "You can't do that!" they said! Then the compiler should check for it: we are back to cc/lint with f77 & pfort? If it requires more info than the compiler has it is not relevent to a compiler discussion. Clearly. Enough about FORTRAN: I could *not* care any less. This shows how C is *trying* to deal with a problem that FORTRAN and other languages just gave up on... read on. .... what is so special about C that it needs a 'noalias' declaration? The aliasing problems in C happen at "deeper" levels due to the pointer to a pointer to a widgit constructs. C is trying to cope with the aliases rather than "forbid" them. > The point that the C compiler already takes a great deal on blind > faith is quite right, and it takes a lot of the steam out of my > objections to 'noalias'. > .... <and> casts <make code> significantly harder to debug ... Yes: this hole has positive pressure behind it. When trying to insert a noalias assertion into the code a good programmer will prove to themself that it is not true. And we are still coping with the problem here. > I should make it plain that my objection to 'noalias' was more vehement > than perhaps was warranted, because on the whole I am tremendously > impressed by the work of the ANSI C committee. I am not: recently they have begun to bag things. (#pragma, (char *) == (void *), unary +, enum ~= int) > -- 'noalias' still does not mean "no alias" so the >name< is bad See [Below]. > -- if "other languages do it" was a good enough argument for > giving parentheses more than merely grouping effect, then > "other languages do it" is a good enough argument for > having "noalias" be the default I agree completely: the "other languages do it" was *never* good enough for the (..) "feature". C should re-a range expressions with impunity. (I'd rather see the bag-on "unary +" for goodness sake!) > -- pragma(noalias) is still a better approach > {what does #pragma do? Surely a macro processor which may be > completely separate from the compiler is the wrong place for > such things?} Pragma is the largest BAG-ON I have ever seen in a compiler. It can do anything & nothing all at the same time. (Stop it with the bags!) This noalias type modifier can *really* change the ADT (set of ops & data). >and Marc Mengel has not refuted these claims. OK, I will. [Below] is here. The "noalias" assertion *should* mean that there is no other *active* handle on the data item. It should also tell the compiler that if you see me giving this handle to a function: a) you must sync the data b) compute the required handle (could be address arith here) c) process function call d) mark any temps as invalid (based on this data); the subroutine could have changed it, but we have control again (for now). So basically: diddle(pi) exclusive int *pi; { *pi = 0; /* here we can move 0 to a temp */ while (something()) { *pi += someexpr(); /* here we can use the temp */ } /* possible sync for *pi */ g(*pi); /* *pi in sync yet, use temp? */ /* forced sync point for *pi */ f(pi); /* we sync before the call */ /* force sync before we return */ } You see how the compiler (even in a simple case) can make a register save or no-save choice around the call to g()? In more complex code *only* the compiler is going to be able to keep track of all of the registers and sync points involved. The whole key to the "exclusive" access (Marc and I call it) restriction is that the handle must be the only *active* handle; others may exist; but they may not be in use (even better is that a runtime checker *can* be written for this. {Keep a back pointer to the active handle with the data... really slow but it will find the bugs. And changes the ADT}). Just like checking array bounds, right? Marc has already pointed out the the compiler believes the programmer about pointer casts, pointer references (through nil), array bounds, parameter prototypes (pre-ANSI). What about memory allocation: pi = (int *) malloc(sizeof(char)); ^^^^^ ^^^^ or deallocation: free(& BagMe); /* for a good time */ free(main); /* for a core dump */ or any of a number of other very important semantic restrictions? A C programmer cannot code without thinking of all of these. This feature makes one more aspect of the programmers job clear (alias control). Finally: I do not feel the feature belongs in ANSI C. It is not C. It is too late to add it. It is a bag-on addition. It is a poor choice of keywords. And for all the good it could do it will cause more harm to add it this late in the game. Wait for D or K. Kevin Braunsdorf ksb@j.cc.purdue.edu K Project pur-ee!gawk!klang
roger@celtics.UUCP (Roger B.A. Klorese) (12/29/87)
In article <492@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >I would claim that aliasing is a worse problem in Fortran than in C. Probably true. >So my question: if people care about optimising Fortran (and they DO) >and they care about writing correct programs in Fortran (and they DO) >and if aliasing is a problem in Fortran (and I've just shown that it >IS), what is so special about C that it needs a 'noalias' declaration? Because many people have *already* extended their FORTRAN compilers to handle aliasing properly. Quoting from the Celerity Computing Tools and Applications Reference Manual, Volume III, Book 2 (Languages, Kernel), which is Copyright 1986 Celerity Computing, on page 1-14: "However, even programs that contain hidden aliasing can be safely optimized if the optimization control '-Oc s' is specified. It causes the optimizer to refrain from placing in registers any expressions that depend on common-block variables or incoming parameters." When parameters and common block allocations are eliminated from consideration, and proper subscripting is observed, FORTRAN aliases should all be detectable. (Any cases left out?) -- ///==\\ (Your message here...) /// Roger B.A. Klorese, CELERITY (Northeast Area) \\\ 40 Speen St., Framingham, MA 01701 +1 617 872-1552 \\\==// celtics!roger@necntc.nec.com - necntc!celtics!roger
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)
In article <485@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
-If the FORTRAN committee have not found a need to introduce a 'noalias'
-mechanism into that language (aliasing is quite possible in FORTRAN),
-what makes C so special?
Pointers!
-Why not simply say that the compiler is entitled to assume 'noalias'
-for everything, and that if the programmer wants unsafe aliases s/he
-should declare the variables in question to be 'volatile'?
The existing (K&R) C language does not permit the "noalias" property
(i.e. hyperoptimization) to be the default.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/06/88)
In article <1453@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes: >Right. It is NOT computable. Therfore you (the compiler) *have* to believe >the programmer, since you can't figure it out yourself. That is the key philosophical point about specifying "noalias". If it were just like the other type qualifiers, it wouldn't have been invented. As a matter of fact, it arose as the resolution of an attempt to overload the semantics of one of the other type qualifiers ("const"). P.S. Good article, Marc!
mmengel@cuuxb.ATT.COM (Marc W. Mengel) (01/06/88)
In article <492@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >In article <1453@cuuxb.ATT.COM>, mmengel@cuuxb.ATT.COM (Marc W. Mengel) [several corrections of my limited experience with FORTRAN] I was intending to give an example of aliasing caused by call-by-reference argument passing, and how it can lead to different results from essentially identical code. All of the FORTRANs I have used use call by copy-in copy-out. I never considered versions of f77 I have worked with ( the one from V7 unix, which was kinda broken ) correct FORTRAN implementations, this should not neccesarily reflect on SUN's f77, which I have never used. >I would claim that aliasing is a worse problem in Fortran than in >C. For example, the option of having cpxmpy accept records and >return a record is not available in Fortran 77 (it IS available in >Fortran 8X), so there simply isn't any safe way to write this in >Fortran, while there is in C. Aliasing is not a problem at all in the current C implementations. There does not exist the call by reference/copy-in-copy-out ambiguity, since all calls are by value, and explicit call by reference can only be done using the address-of operator. I never claimed that it was. The problem is that the neccesity of avoiding aliasing by always updating values at the end of pointers (the way C currently behaves in all cases) is expensive, and it would be useful to be able to tell the compiler that it was "okay" to not do this updating in some cases. >So my question: if people care about optimising Fortran (and they DO) >and they care about writing correct programs in Fortran (and they DO) >and if aliasing is a problem in Fortran (and I've just shown that it >IS), what is so special about C that it needs a 'noalias' declaration? >(By the way, there exist tools such as PFORT which can check that the >Fortran no-aliasing rules are not violated. But then Fortran is a >much simpler language than C.) Aliasing is not a problem in C. Ensuring that it is not a problem is expensive. People want to be able to turn off this expensive behavior in specific cases where they know that it won't make a difference. >The point that the C compiler already takes a great deal on blind >faith is quite right, and it takes a lot of the steam out of my >objections to 'noalias'. But I think that explains the increasing >popularity of C interpreters (one that sounded impressive was just >announced on the net). My experience has been that programs which >use casts a lot are significantly harder to debug than ones which >lint is happy with; has yours been any different? Ok, so the boat >is leaky; is that any reason to bore more holes in it? lint is often perfectly happy with type casts; explicit casts are often useful. Programs that lint doesn't like are often buggy. Your argument is really that we shouldn't give C programmers another way to "shoot themselves in the foot." [ discussion of how ANSI is nonetheless doing a far better job than other standards orginizations] > -- 'nolias' still does not mean "no alias" so the >name< is bad I agree a better name would be nice, alas I haven't thought of one. Have you? > -- it is still back-to-front > -- if "other languages do it" was a good enough argument for > giving parentheses more than merely grouping effect, then > "other languages do it" is a good enough argument for > having "noalias" be the default not regrouping parenthesis is legal in all current C definitions. assuming pointer references won't be aliased is not legal in any C spec I've seen. thats a big difference in my book. > -- pragma(noalias) is still a better approach > {what does #pragma do? Surely a macro processor which may be > completely separate from the compiler is the wrong place for > such things?} pragma(noalias) and pragma(const) and pragma(volatile) are functionally equivalent to having keywords, the only difference is that in one case we are creating more keywords (and we still have undefined ones like "entry" lying around...). We have a conflict between more keywords or longer definitions. A trade-off. ANSI chose keywords, I don't think it makes a whole lot of difference either way. >and Marc Mengel has not refuted these claims. I still haven't refuted two of them, nor do I care to. I do maintain that 1) C currently assumes that pointers can point anywhere, and therefore updates memory at the end of pointer references before using other non-register variables on the assumption that the pointer may point to those variables. 2) Changing this behavior in general will break many existing programs which intentionally use aliasing. 3) The optizations possible when the compiler knows pointer references are not aliased are signifigant. and that this means we need a noalias-type solution. The people who care whether it looks like: noalias int *pi; versus pragma(noalias) int *pi; can decide which they like better, it makes no difference to me whatsoever. -- Marc Mengel attmail!mmengel ...!{moss|lll-crg|mtune|ihnp4}!cuuxb!mmengel
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/07/88)
In article <1469@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes: > Aliasing is not a problem in C. Ensuring that it is not a problem is > expensive. People want to be able to turn off this expensive behavior > in specific cases where they know that it won't make a difference. (This is such a beautiful statement of what "noalias" is all about that I wanted to make sure everyone noticed it. Please excuse the reposting.)
ray@micomvax.UUCP (Ray Dunn) (01/08/88)
In article <9934@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >In article <1453@cuuxb.ATT.COM> mmengel@cuuxb.ATT.COM (Marc W. Mengel) writes: >>Fortran uses copy-in copy-out address passing.... > >Some FORTRAN compilers may indeed use copy-in/copy-out (I believe this >is usually called `value-result'), but I think it is not mandated. >-- ^^^^^^ Chris! This is VERY unlike you! You reply to a VERY descriptive, VERY well written posting which clears up MUCH of the confusion on the meaning/impact of the aliasing question, by a nit-picking criticism of a point irrelevant to the central theme the poster was expounding, and OF WHICH YOU ARE NOT EVEN SURE OF THE CORRECTNESS!! I should, of course, have passed this (small) flame privately. Forgive me, but I wanted anyway to publicly thank Mark Wendel for his posting. It was clear and very informative. Bravo! Ray Dunn. ..philabs!micomvax!ray
ok@quintus.UUCP (Richard A. O'Keefe) (01/08/88)
In article <6971@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <1469@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes: > > > Aliasing is not a problem in C. Ensuring that it is not a problem is > > expensive. People want to be able to turn off this expensive behavior > > in specific cases where they know that it won't make a difference. > > (This is such a beautiful statement of what "noalias" is all about that > I wanted to make sure everyone noticed it. Please excuse the reposting.) This is such a CONFUSING statement that I too want to make sure everyone notices it. Is he talking about the compile-time cost of checking whether something is aliased or not, or about the usually small run-time cost of picking up another copy of something from memory just in case it was aliased? [If someone has an example of a real program where adding 'noalias' to fewer than 10% of the variables makes a factor of 2 difference to run time, let's see it!] If whatever-it-is is so expensive, shouldn't the cheap version be the default (as it is in Fortran, Pascal, COBOL, ADA, BASIC, Euclid, and so on) and the expensive version be the one you have to say explicitly? What we need at this point is a CLEAR description of exactly what the difference is between volatile int x; int x; noalias int x; Are they points on a scale: volatile: may change at any time {plain}: may change in any *procedure call* noalias: may only change by explicit assignment If I say cat >>foo.h <<'EOF' extern noalias int x; extern void set_x(int i); EOF cat >>foo.c <<'EOF' noalias int x; void set_x(int i) { x = i; } EOF cat >>main.c <<'EOF' #include <stdio.h> #include "foo.h" main() { x = 0; set_x(1); printf("x = %d\n", x); } EOF cc main.c foo.c a.out is the output x = 0 legal? {Presumably such a program is non-conforming, but is a conforming compiler allowed to do this to it?}
mmengel@cuuxb.ATT.COM (Marc W. Mengel) (01/13/88)
In article <512@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >In article <6971@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: >> In article <1469@cuuxb.ATT.COM> mmengel@cuuxb.UUCP (Marc W. Mengel) writes: >> >> > Aliasing is not a problem in C. Ensuring that it is not a problem is >> > expensive. People want to be able to turn off this expensive behavior >> > in specific cases where they know that it won't make a difference. >> >> (This is such a beautiful statement of what "noalias" is all about that >> I wanted to make sure everyone noticed it. Please excuse the reposting.) > >This is such a CONFUSING statement that I too want to make sure everyone >notices it. Is he talking about the compile-time cost of checking whether >something is aliased or not, or about the usually small run-time cost of >picking up another copy of something from memory just in case it was >aliased? Actually, I was referring to BOTH sets of costs -- run time and compile time; at compile time there are lots of headaches about synchronizing whats in registers with whats in memory every time code for a pointer indirection is generated; and at run time, the cost of performing the "usually small" costs of picking up another copy of something from memory can add up quite a bit. >[If someone has an example of a real program where adding 'noalias' >to fewer than 10% of the variables makes a factor of 2 difference to run >time, let's see it!] If whatever-it-is is so expensive, shouldn't the >cheap version be the default (as it is in Fortran, Pascal, COBOL, ADA, >BASIC, Euclid, and so on) and the expensive version be the one you have >to say explicitly? Lets say I agree with you on your assumption that the best I can get with noalias is a factor of 2 difference in run time... are you claiming that optimizations that halve my run time are not worth putting in??? Next, lets look at a nice piece of code... vecadd( v1, v2, v3 , n) noalias int *v1, *v2, *v3; int n; { register int i; for( i = 0; i < n ; i++, v1++, v2++, v3++ ){ *v3 = *v2 + *v1; } } On certain machines like CDC Cyber 205's or other vector processors, I could encode this as 1 instruction *if* i know that my 3 vectors don't overlap. noalias is the only way to efficiently tell the compiler this. (you may note in this example the compiler could generate code that tests for vector overlap and branch to do either the single vector instruction or the loop, in practice the logic needed to make that kind of decision in the general case is arbitrarily complex and may involve solving the (insoluble) halting problem...) The noalias==cheap-version as a default will break existing code so that is *not* an option. > What we need at this point is a CLEAR description of exactly what > the difference is between > volatile int x; > int x; > noalias int x; >Are they points on a scale: > volatile: may change at any time Right... > {plain}: may change in any *procedure call* or through *any* pointer indirection if the plain item is not a register variable and the address of it is taken *anywhere*... It can only change in procedure calls that indirect pointers or use it directly (if it's global), if your compiler wants to keep that kind of bookkeeping, you can restrict your statement about procedure calls more. > noalias: may only change by explicit assignment right. >If I say > cat >>foo.h <<'EOF' > extern noalias int x; > extern void set_x(int i); > EOF > cat >>foo.c <<'EOF' > noalias int x; > > void set_x(int i) { x = i; } > EOF > cat >>main.c <<'EOF' > #include <stdio.h> > #include "foo.h" > main() { > x = 0; > set_x(1); > printf("x = %d\n", x); > } > EOF > cc main.c foo.c > a.out >is the output > x = 0 >legal? {Presumably such a program is non-conforming, but is a conforming >compiler allowed to do this to it?} I don't see any aliasing in the code you have written... The global variable x is everywhere refered to as x, this causes no problems of any sort that I can see, noalias or not. The program you list will output "x = 1\n" on stdout. It sounds like you misunderstand what aliasing is, and hence miss seeing when noalias would allow a valuable optimaztion... -- Marc Mengel attmail!mmengel ...!{moss|lll-crg|mtune|ihnp4}!cuuxb!mmengel