* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 [not found] <E1SHjzo-0005oe-8t@vcs.savannah.gnu.org> @ 2012-04-13 14:22 ` Mark H Weaver 2012-04-13 15:18 ` Noah Lavine 2012-04-13 16:28 ` Andy Wingo 0 siblings, 2 replies; 10+ messages in thread From: Mark H Weaver @ 2012-04-13 14:22 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-devel Hi Andy, > commit 59c557056cff1ce6146b4d689eeee922300b6278 > Author: Andy Wingo <wingo-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org> > Date: Tue Apr 10 15:56:23 2012 -0700 > > peval: elide redundant predicates; eliminate some common subexpressions > > * module/language/tree-il/peval.scm (fold-constants): Returns #f instead > of the expression, as all continuations handle #f themselves. > (negate, bailout?, extract-facts, infer, infer-defined?) > (infer-struct-vtable): New helpers. I haven't looked at the code, but it sounds like you are trying to eliminate redundant 'struct-vtable' checks. Unfortunately, it seems to me that this cannot be done safely. In practice, the checks look like: (eq? (struct-vtable s) <foo>) Both of the values being compared here are fetched from mutable locations. The 'struct-vtable' field is mutable, and <foo> is usually a top-level variable that is also mutable. Furthermore, both of these things are mutated in practice when a GOOPS class is redefined, IIUC. Am I missing something? Thanks, Mark ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-13 14:22 ` GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 Mark H Weaver @ 2012-04-13 15:18 ` Noah Lavine 2012-04-13 19:59 ` Ludovic Courtès 2012-04-13 16:28 ` Andy Wingo 1 sibling, 1 reply; 10+ messages in thread From: Noah Lavine @ 2012-04-13 15:18 UTC (permalink / raw) To: Mark H Weaver; +Cc: Andy Wingo, guile-devel At first I thought you were right. But then I realized there's an even deeper problem here. Imagine implementing a record mutator like this: (define (set-foo-a! foo new-value) (if (is-foo? foo) (%unsafe-set-foo-a! foo new-value) (error))) That code is incorrect, by the same logic you used: something could change the class of foo in between the is-foo? call and the %unsafe-set-foo-a! call. You need some atomic check-and-set operation in order to do this safely. Unfortunately, I don't see a correct way short of some sort of mutex. A mutex for each record would be a lot of overhead, but what about a mutex per class, that has to be acquired to change any instance of the class to or from a different class? Changing a class is a rare enough operation that we should not optimize for it, I think. Also, if we had such a mutex, we could use it to eliminate redundant struct-vtable checks correctly, by acquiring it at the beginning of a function and releasing it at the end. I'm somewhat afraid, however, that the real solution is changing how we deal with parallelism, and that is a much bigger problem. Noah On Fri, Apr 13, 2012 at 10:22 AM, Mark H Weaver <mhw@netris.org> wrote: > Hi Andy, > >> commit 59c557056cff1ce6146b4d689eeee922300b6278 >> Author: Andy Wingo <wingo-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org> >> Date: Tue Apr 10 15:56:23 2012 -0700 >> >> peval: elide redundant predicates; eliminate some common subexpressions >> >> * module/language/tree-il/peval.scm (fold-constants): Returns #f instead >> of the expression, as all continuations handle #f themselves. >> (negate, bailout?, extract-facts, infer, infer-defined?) >> (infer-struct-vtable): New helpers. > > I haven't looked at the code, but it sounds like you are trying to > eliminate redundant 'struct-vtable' checks. Unfortunately, it seems to > me that this cannot be done safely. In practice, the checks look like: > > (eq? (struct-vtable s) <foo>) > > Both of the values being compared here are fetched from mutable > locations. The 'struct-vtable' field is mutable, and <foo> is usually a > top-level variable that is also mutable. Furthermore, both of these > things are mutated in practice when a GOOPS class is redefined, IIUC. > > Am I missing something? > > Thanks, > Mark > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-13 15:18 ` Noah Lavine @ 2012-04-13 19:59 ` Ludovic Courtès 2012-04-13 20:36 ` Noah Lavine 0 siblings, 1 reply; 10+ messages in thread From: Ludovic Courtès @ 2012-04-13 19:59 UTC (permalink / raw) To: guile-devel Noah Lavine <noah.b.lavine@gmail.com> skribis: > I'm somewhat afraid, however, that the real solution is changing how > we deal with parallelism, and that is a much bigger problem. And this is where functional setters come in. ;-) Ludo’. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-13 19:59 ` Ludovic Courtès @ 2012-04-13 20:36 ` Noah Lavine 0 siblings, 0 replies; 10+ messages in thread From: Noah Lavine @ 2012-04-13 20:36 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guile-devel On Fri, Apr 13, 2012 at 3:59 PM, Ludovic Courtès <ludo@gnu.org> wrote: > Noah Lavine <noah.b.lavine@gmail.com> skribis: > >> I'm somewhat afraid, however, that the real solution is changing how >> we deal with parallelism, and that is a much bigger problem. > > And this is where functional setters come in. ;-) Yes, functional data structures solve this. But the trouble is that you can't take advantage of this to generate better code unless your compiler knows that you will never mutate certain variables. Maybe you could put something together with lots of caching code and invalidating it if the assumptions change. Noah ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-13 14:22 ` GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 Mark H Weaver 2012-04-13 15:18 ` Noah Lavine @ 2012-04-13 16:28 ` Andy Wingo 2012-04-13 17:07 ` Mark H Weaver 1 sibling, 1 reply; 10+ messages in thread From: Andy Wingo @ 2012-04-13 16:28 UTC (permalink / raw) To: Mark H Weaver; +Cc: guile-devel Hi, On Fri 13 Apr 2012 07:22, Mark H Weaver <mhw@netris.org> writes: >> * module/language/tree-il/peval.scm (fold-constants): Returns #f instead >> of the expression, as all continuations handle #f themselves. >> (negate, bailout?, extract-facts, infer, infer-defined?) >> (infer-struct-vtable): New helpers. > > I haven't looked at the code, but it sounds like you are trying to > eliminate redundant 'struct-vtable' checks. Unfortunately, it seems to > me that this cannot be done safely. The identity of the vtable does not change when it is redefined. If the vtable is redefined, the equality check still succeeds. There are comments in the source. In the end though, that branch is turning into a more general effects analysis + CSE pass, for which I'll push a different branch shortly. Regards, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-13 16:28 ` Andy Wingo @ 2012-04-13 17:07 ` Mark H Weaver 2012-04-15 0:28 ` Andy Wingo 0 siblings, 1 reply; 10+ messages in thread From: Mark H Weaver @ 2012-04-13 17:07 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-devel Hi Andy, Andy Wingo <wingo@pobox.com> writes: > On Fri 13 Apr 2012 07:22, Mark H Weaver <mhw@netris.org> writes: >>> * module/language/tree-il/peval.scm (fold-constants): Returns #f instead >>> of the expression, as all continuations handle #f themselves. >>> (negate, bailout?, extract-facts, infer, infer-defined?) >>> (infer-struct-vtable): New helpers. >> >> I haven't looked at the code, but it sounds like you are trying to >> eliminate redundant 'struct-vtable' checks. Unfortunately, it seems to >> me that this cannot be done safely. > > The identity of the vtable does not change when it is redefined. If the > vtable is redefined, the equality check still succeeds. There are > comments in the source. Okay, I've just reread: http://wingolog.org/archives/2009/11/09/class-redefinition-in-guile and I see that I had some misconceptions about this. Point taken: when a class is redefined, the result of 'struct-vtable' on the instances remain the same. Nonetheless, the vtable checks involve comparisons with a mutable top-level variable. Whenever unknown code is run (e.g. when a top-level procedure is called) you must assume the worst: that any top-level variable might have been 'set!'. Regards, Mark ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-13 17:07 ` Mark H Weaver @ 2012-04-15 0:28 ` Andy Wingo 2012-04-15 7:53 ` David Kastrup 2012-04-15 21:26 ` Ludovic Courtès 0 siblings, 2 replies; 10+ messages in thread From: Andy Wingo @ 2012-04-15 0:28 UTC (permalink / raw) To: Mark H Weaver; +Cc: guile-devel Hi, On Fri 13 Apr 2012 10:07, Mark H Weaver <mhw@netris.org> writes: > Nonetheless, the vtable checks involve comparisons with a mutable > top-level variable. Whenever unknown code is run (e.g. when a top-level > procedure is called) you must assume the worst: that any top-level > variable might have been 'set!'. You probably saw, but wip-cse does effects analysis to prove that the toplevel hasn't been set! by intervening expressions. There is of course the question of what optimizations like this may be made in the presence of concurrently executing threads. For example, in wip-cse the following expression folds: (if (eq? x y) (eq? x y) #f) => (eq? x y) This is because there was no toplevel-set! in between the first and second checks. The possible side effects of referencing X or Y would happen on the first check or not at all, so the second expression can cause no effects. (If CSE sees a call to an unknown procedure, it's assumed that it can cause any effect, and thus such a call does not commute with anything but a "constant" expression.) But OK, the question here is, what if another thread is concurrently mutating X and Y? If this were C++ or Java, the answer would be that they can still fold, because access to a multithreaded mutable needs to be synchronized. I think this is reasonable. What do you think? Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-15 0:28 ` Andy Wingo @ 2012-04-15 7:53 ` David Kastrup 2012-04-15 21:26 ` Ludovic Courtès 1 sibling, 0 replies; 10+ messages in thread From: David Kastrup @ 2012-04-15 7:53 UTC (permalink / raw) To: guile-devel Andy Wingo <wingo@pobox.com> writes: > But OK, the question here is, what if another thread is concurrently > mutating X and Y? If this were C++ or Java, the answer would be that > they can still fold, because access to a multithreaded mutable needs > to be synchronized. I think this is reasonable. What do you think? You don't even need multithreading for undefined effects of sequence ordering in C/C++. i = i++; is already undefined. Scheme has several non-guarantees regarding execution order as well (like the order in which function arguments will get evaluated). History time: Fortran specifies that if array arguments to a function do not point to distinct objects, the results are undefined. C passes arrays (actually, vectors) using pointers, and a pointer is a memory reference that can point anywhere in an array, and there are no restrictions about the same-object relations (whether at the same address or with an offset) of several arguments: the behavior is well-defined either way. The C99 standard or whatever it was allows passing multidimensional arrays to functions. In addition, you can use the "restrict" pointer syntax (total hell to use, by the way) to tell the compiler that a pointer argument to a function is not in an aliasing relation to other pointers accessible to the function. As a result, it has now become theoretically possible to write C code for multidimensional array manipulations that can be optimized as well as naively written Fortran code from 1960. In practice, however, it turns out that both code writers as well as compiler writers are not quite up to the task yet. Lesson: make hard to find and optimize corner cases undefined behavior if you don't want to make it almost impossible to write code that can be optimized well. The more assumptions an optimizer is allowed to make by default, the better it can do its work. _Without_ special help by the programmer. And if we wanted to rely on special help by the programmer, it would be more straightforward if we let the programmer write the assembly code rather than the compiler. -- David Kastrup ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-15 0:28 ` Andy Wingo 2012-04-15 7:53 ` David Kastrup @ 2012-04-15 21:26 ` Ludovic Courtès 2012-04-16 6:36 ` David Kastrup 1 sibling, 1 reply; 10+ messages in thread From: Ludovic Courtès @ 2012-04-15 21:26 UTC (permalink / raw) To: guile-devel Hi, Andy Wingo <wingo@pobox.com> skribis: > But OK, the question here is, what if another thread is concurrently > mutating X and Y? If this were C++ or Java, the answer would be that > they can still fold, because access to a multithreaded mutable needs to > be synchronized. I think this is reasonable. What do you think? I agree. Ludo’. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 2012-04-15 21:26 ` Ludovic Courtès @ 2012-04-16 6:36 ` David Kastrup 0 siblings, 0 replies; 10+ messages in thread From: David Kastrup @ 2012-04-16 6:36 UTC (permalink / raw) To: guile-devel ludo@gnu.org (Ludovic Courtès) writes: > Andy Wingo <wingo@pobox.com> skribis: > >> But OK, the question here is, what if another thread is concurrently >> mutating X and Y? If this were C++ or Java, the answer would be that >> they can still fold, because access to a multithreaded mutable needs to >> be synchronized. I think this is reasonable. What do you think? > > I agree. I just reread what I replied, and it was probably hard to detect the implicit "I too" between the lines of the diatribe. -- David Kastrup ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-04-16 6:36 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <E1SHjzo-0005oe-8t@vcs.savannah.gnu.org> 2012-04-13 14:22 ` GNU Guile branch, wip-peval-predicates, created. v2.0.5-100-g59c5570 Mark H Weaver 2012-04-13 15:18 ` Noah Lavine 2012-04-13 19:59 ` Ludovic Courtès 2012-04-13 20:36 ` Noah Lavine 2012-04-13 16:28 ` Andy Wingo 2012-04-13 17:07 ` Mark H Weaver 2012-04-15 0:28 ` Andy Wingo 2012-04-15 7:53 ` David Kastrup 2012-04-15 21:26 ` Ludovic Courtès 2012-04-16 6:36 ` David Kastrup
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).