Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

idea: Runtime constant #1001

Open
shirok opened this issue Mar 17, 2024 · 0 comments
Open

idea: Runtime constant #1001

shirok opened this issue Mar 17, 2024 · 0 comments

Comments

@shirok
Copy link
Owner

shirok commented Mar 17, 2024

Some procedure are known to be constant, but the value may depend on the running platform (e.g. (least-positive-flonum) can be a least normalized positive flonum if the processor doesn't support denormalized flonums). We cannot replace them for constants at compile-time, since compilation may be done on a different platform.

We can do better than call it every time, however, by adpoting a similar mechanism as GREF. We resolve global variable reference at runtime, but once it is resolved, the identifier saved in the VM code is replaced with the result of resolution (gloc) so the same code will skip resolving for the second time and after.

A simple hack is that we compile a call to such runtime-constant procedure as a global variable reference, but put a hook on the variable so that it is initialized when it is referenced for the first time. This mechanism can be exposed to the user so that one can define a variable that's initialized on-demand.

We can further generalize it with "global variable reference with constant arguments" (GREFC) instruction. For a procedure that is referentially transparent but can't be computed at compile time. When a compiler sees all the arguments are constant, it emits GREFC , identifier, and an array of constant arguments. GREFC tries to fetch the value, and if the value hasn't been computed, call the original function with the constant arguments and cache the result. From the second time and after, GREFC just fetches the cached result.

GREFC can be used for partial evaluation, e.g. (f a b c d) is known to be computed as ((f1 a b) c d) and the compiler knows f1 is referentially transparent and a, b are constants, the compiler can use GREFC for (f1 a b) part. This is effectively the same as the kludge we employed for format---if the format string is constant, we can compute formatter once. It is now hardwired to format but we can generalize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant