ChezScheme icon indicating copy to clipboard operation
ChezScheme copied to clipboard

Add `single-valued` flag to primitives to help reduce `call-with-values` expressions

Open gus-massa opened this issue 6 years ago • 3 comments

In particular this is useful to reduce begin0 expressions that have a single valued result, to avoid the creation of an intermediate lambda or list to save the value.

The single-valued flag is autodetected from the signature, so it would be useful to add the signatures to the system procedures.

This needs new bootfiles, so the checks in travis-ci fails. Look at this test instead.

I'm optimistic and I think this PR is correct, but I have a lot of related questions anyway:

I made a memoized version of single-valued? instead of a direct one because it detect many more opportunities during the compilation of the compiler, specially in cpnanopass.ss

There is no memoized version of true-valued?. I don't expect that it would be very useful, so I didn't modify it.

The functions simple? and simple/profile? use the same flag for memoization. Is that correct?

I added a special case to single-valued? to detect call-with-values, apply and $apply and go inside the procedure, because they always call the procedure and the result is the result of the call to the procedure. I think it's ok to avoid the arity check here. There are a few (5) similar functions, like call-with-port, but I didn't add them because they are probably not used too much.

I made a similar change to boolean-valued? because it also doesn't need too much checks. (It's possible to make a similar extension to pure? and the other memoized functions, but they must ensure that there are no errors, so I didn't modify them.)

I was thinking about adding the single-valued flag to the true and boolean-valued flags (like pure, that implies discard). I finally didn't change that.

gus-massa avatar May 02 '18 01:05 gus-massa

Update:Ijust added an special case for dynamic-wind.

gus-massa avatar May 12 '18 19:05 gus-massa

I rebased the commit. The second commit has some improvements based in code by @mflatt , but I made some changes. (I think they should be squashed before merging.)

I made the flags boolean and true imply single-valued. I think it make more sense, specially because boolean is autodetected from the signature, and true can also be autodetected in the future.

I'd like to make abort-op imply boolean, true and single-valued too. It can be helpful to detect the boolean result in code like

(if (something) (list? x) (error))

I didn't make mifoldable imply single-valued. I'm not sure what is better here. The code for the reduction of mifoldable expressions with multiple results is wrong (it generates an exception that is catched and discarded, so the net effect is nothing). It can be fixed modifying the reduction for mifoldable or adding a cp02 version for exact-integer-sqrt that is the only case.

I didn't make pure imply single-valued neither. I'm not sure what is better here. I tried to follow the code but I was confused, so I'm not sure if the pure functions with multiple return values are reduced or not. Anyway, there are only a few (5?) primitives that would be affected.

gus-massa avatar Jan 24 '19 04:01 gus-massa

Tiny update: Change the signature of exact-integer-sqrt to use uint instead of integer. (This should be squashed before merging.)

gus-massa avatar Feb 05 '19 17:02 gus-massa

Included in v9.9.9 merge 47daa9b34016de84fd111801d9d589d15a523abe.

mflatt avatar Oct 17 '23 17:10 mflatt