* module/language/cps/compile-bytecode.scm (compile-function): Expect
eq-constant? instead of eq-null?, etc.
* module/language/cps/effects-analysis.scm: Likewise.
* module/language/cps/reify-primitives.scm (reify-primitives): For
eq-constant?, reify a $const unless the constant is an immediate whose
encoding fits in 16 bits.
* module/language/cps/type-fold.scm (materialize-constant): Helper to
make a constant from a type, min, and max.
(fold-eq-constant?): New helper.
(eq-constant?): New folder.
(undefined?): Define specifically.
(define-nullish-predicate-folder): Renamd from
define-special-immediate-predicate-folder. Use only for null?, false,
and nil?.
(*branch-reducers*): New mechanism. Reduce eq? to eq-constant? if
possible.
(local-type-fold): Refactor to use materialize-constant, and to allow
reducing branches.
* module/language/cps/types.scm (constant-type): Return three values
instead of a type entry.
(constant-type-entry): New function that returns a type entry. Adapt
callers.
(infer-constant-comparison): New helper.
(eq-constant?): New inferrer.
(undefined?): New inferrer.
* module/language/tree-il/compile-bytecode.scm (eq-constant?): Fix
truncate-bits signed arg.
(define-immediate-type-predicate): Adapt to visit-immediate-tags
change.
* module/language/tree-il/compile-cps.scm (convert): Convert eq? to
constant to eq-constant?. Advantaged is that it gets fixnums and
chars in addition to special immediates.
* module/language/tree-il/cps-primitives.scm (define-immediate-type-predicate):
Adapt to allow #f as pred.
* module/system/base/types/internal.scm (immediate-tags): Use #f as pred
for false, nil, etc.
(immediate-bits->scm): Adapt.
* module/system/vm/assembler.scm (emit-eq-null?, emit-eq-nil?)
(emit-eq-false?, emit-eq-true?, emit-unspecified?, emit-eof-object?):
Remove specialized emitters.
* module/system/vm/assembler.scm (define-immediate-tag=?-macro-assembler):
Allow for pred to be #f.
* module/system/vm/disassembler.scm (define-immediate-tag-annotation):
Adapt to pred being #f.
* module/language/cps/cse.scm (eliminate-common-subexpressions-in-fun):
I think it's possible to get an orphan loop, with predecessors
after successors in the original RPO. Handle that here.
* module/language/cps/cse.scm (propagate-analysis): New helper.
(eliminate-common-subexpressions-in-fun): Recompute avail and bool set
in response to simplifications in predecessor CFG. Allows much better
compilation of pattern-matching idioms!
* module/language/cps/cse.scm (forward-cont, forward-branch)
(compute-avail-and-bool-edge): New helpers.
(add-equivalent-expression!): Allow idempotent adds; can happen now
when revisiting a cont after changes to its predecessors.
(fold-branch): New helper.
(eliminate-common-subexpressions-in-fun): Allow for reductions to
branch predecessors. In that case, revisit the branch, as the CFG
will have changed.
* module/language/cps/cse.scm (elide-predecessor, prune-branch)
(prune-successors, term-successors): New helpers.
(eliminate-common-subexpressions-in-fun): When we modify the CFG,
update the analysis. Also, thread the substs map through CSE so that
closures in high-level CPS can take advantage of eliminated variables.
(fold-renumbered-functions): Take multiple seeds.
(eliminate-common-subexpressions): Thread var substs map through CSE.
* module/language/cps/cse.scm (<analysis>): New data type, grouping
available expression analysis, predecessor map, etc.
(eliminate-common-subexpressions-in-fun): Instead of having a static
analysis, thread it through the CSE pass so that we can update the CFG
as we go.
* module/language/cps/cse.scm (compute-available-expressions): Take a
clobber map instead of an effects map.
(compute-singly-referenced): Remove unused function.
(eliminate-common-subexpressions-in-fun): Keep a preds map. Use it
add entries to the equiv-set and var-substs at expression
continuations instead of at the expression terms themselves.
* module/language/cps/cse.scm (compute-truthy-expressions): Operate on a
single function.
(eliminate-common-subexpressions-in-fun): Instead of computing a set
of labels to eliminate, go ahead and do the elimination as we go.
(fold-renumbered-functions): Can just use a single seed now.
(eliminate-common-subexpressions): Simplify to just fold over
functions, building up renamed output as we go.
* module/language/cps/cse.scm (fold-renumbered-functions): New helper.
(compute-equivalent-expressions): Use new helper.
(compute-equivalent-expressions-in-fun): Lift to top-level.
(eliminate-common-subexpressions): Adapt.
* module/language/cps/optimize.scm (define-optimizer):
(optimize-higher-order-cps, optimize-first-order-cps):
(make-cps-lowerer):
* module/language/tree-il/optimize.scm (optimize, make-lowerer): In an
embarrassing bug, after parsing optimization arguments, we were
aconsing them instead of the expected cons*. This meant the bootstrap
was running all Tree-IL optimizations! Change to have optimizers not
have defaults and use alists after parsing.
* module/language/cps/optimize.scm (cps-optimizations):
* module/language/tree-il/optimize.scm (tree-il-optimizations):
* module/system/base/optimize.scm (available-optimizations): Invert the
dependency tree to hold the names and default optimization levels in a
central place instead of in the optimizers. It moves definitions
farther from uses, but it avoids us having to load the CPS optimizer
if we don't need it, which improves bootstrap times.
* module/language/cps/reify-primitives.scm (reify-lookup):
* module/language/tree-il/compile-cps.scm (toplevel-box): Instead of
checking that the result of module-variable is a variable, and
possibly checking that it's bound, we just call intrinsics that throw
exceptions if the variable isn't bound. This reduces useless inlining
that can't inform CPS optimizations, as they are tangled in diamond
control flow.
* module/language/cps/compile-bytecode.scm (compile-bytecode):
* module/language/tree-il/compile-bytecode.scm (compile-bytecode):
* module/language/tree-il/compile-cps.scm (compile-cps): Rely on
compiler to lower incoming term already.
* module/language/tree-il/optimize.scm (make-lowerer): New procedure.
* module/system/base/compile.scm (compute-lowerer): New procedure,
replaceing add-default-optimizations.
(compute-compiler): Lower before running compiler.
* module/system/base/language.scm (<language>): Change
optimizations-for-level field to "lowerer".
* module/scripts/compile.scm (%options, compile): Parse -O0, -O1 and so
on to #:optimization-level instead of expanding to all the
optimization flags.
* module/language/cps/optimize.scm (lower-cps): Move here from
compile-bytecode.scm.
(make-cps-lowerer): New function.
* module/language/cps/spec.scm (cps): Declare lowerer.
The old name was wonky and had bad argument order.
* NEWS: Add entry.
* doc/ref/api-data.texi (Bit Vectors): Update.
* libguile/bitvectors.h:
* libguile/bitvectors.c (scm_bitvector_position): New function.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_bit_position): Deprecate.
* module/ice-9/sandbox.scm (bitvector-bindings): Replace bit-position
with bitvector-position.
* module/language/cps/intset.scm (bitvector->intset): Use
bitvector-position.
* module/system/vm/frame.scm (available-bindings): Use
bitvector-position.
* test-suite/tests/bitvectors.test ("bitvector-position"): Add test.
* module/language/cps/specialize-numbers.scm (preserve-eq?): New
helper.
(sigbits-union): Use the new helper. Fixes bugs.gnu.org/38486.
Thanks to Zack Marvel for the bug report and Matt Wette for tracking
it down.
* module/language/cps/closure-conversion.scm (convert-one):
Strongly-connected components of letrec bindings that do not share a
closure may include member functions that have a single free variable,
or even no free variables as a result of free variable pruning.
Handle this case instead of erroring out. Thanks to Stefan Israelsson
Tampe for the report.
* module/language/cps/effects-analysis.scm (&header): New memory kind,
for the fixed parts of objects. Distinguishing init-only memory
allows us to determine that vector-set! doesn't stomple
vector-length.
(annotation->memory-kind*): New helper, mapping references to fixed
offsets to &header. Use for scm-ref/immediate et al.
* module/language/cps/types.scm (div-result-range): It is possible for a
max value to be less than a minimum. In this bug from zig:
(define (benchmark x)
(let loop ((count 0)
(sum 0))
(if (= count 10)
(exact->inexact (/ sum 10)))
(loop (+ count 1) x)))
Here the first iteration gets peeled, and thus the first "if" can't be
true, because "count" is zero. However on the true branch of the if,
range inference produces bogus ranges -- notably, the variable bound
to 10 is inferred to have a min of 10 and a max of 0. This is fine,
because it's unreachable; but that then infects the division, because
the same variable bound to 10 is used there, resulting in division by
zero.
* module/language/cps/cse.scm (compute-equivalent-subexpressions): When
CSE sees a definition like `(cons a b)', it will also record an
"auxiliary definition" for `(car x)', where x is the variable defined
by the cons, whereby calling `(car x)' can reduce to `a' if there is
no intervening effect that clobbers the definitions. However, when
the successor of the cons is a control-flow join, then any variables
defined there have multiple definitions. It's incorrect to add the
aux definition in that case.
* test-suite/tests/compiler.test ("cse auxiliary definitions"): New
test.
This fixes a bug whereby the compiler would sometimes allocate floats in
marked space.
* libguile/gc-inline.h (scm_inline_gc_malloc_pointerless_words): New
internal helper.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (allocate_pointerless_words):
(allocate_pointerless_words_with_freelist): New intrinsics.
* libguile/jit.c (compile_allocate_pointerless_words):
(compile_allocate_pointerless_words_immediate): New compilers.
* libguile/vm-engine.c (allocate_pointerless_words)
(allocate_pointerless_words_immediate): New opcodes.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/effects-analysis.scm (param):
* module/language/cps/reify-primitives.scm (reify-primitives):
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
* module/language/cps/types.scm (allocate-words):
(allocate-words/immediate):
* module/system/vm/assembler.scm (system): Add support for the new
opcodes.
* libguile/intrinsics.c (scm_atan1): New intrinsic, wrapping scm_atan.
(scm_bootstrap_intrinsics): Add new intrinsics.
* libguile/intrinsics.h (scm_t_f64_from_f64_f64_intrinsic): New
intrinsic type.
(SCM_FOR_ALL_VM_INTRINSICS): Add intrinsics for floor, ceiling, sin,
cos, tan, asin, acos, atan, and their unboxed counterparts.
* libguile/jit.c (sp_f64_operand): New helper.
(compile_call_f64_from_f64, compile_call_f64_from_f64_f64): Call out
to intrinsics.
* libguile/vm-engine.c (call-f64<-f64-f64): New opcode.
* module/language/cps/effects-analysis.scm: Add new intrinsics.
* module/language/cps/reify-primitives.scm (compute-known-primitives):
Add new intrinsics.
* module/language/cps/slot-allocation.scm (compute-var-representations):
Add 'f64 slot types for the new unboxed intrinsics.
* module/language/cps/specialize-numbers.scm (specialize-operations):
Support unboxing the new intrinsics.
* module/language/cps/types.scm: Define type inferrers for the new
intrinsics.
* module/language/tree-il/cps-primitives.scm: Define CPS translations
for the new intrinsics.
* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
(*effect-free-primitives*, atan): Define primitive resolvers.
* module/system/vm/assembler.scm: Export assemblers for the new
intrinsics.
(define-f64<-f64-f64-intrinsic): New helper.
* module/language/cps/compile-bytecode.scm (compile-function): When
shuffling return values, we need to reset the frame after any "extra"
values are read and before any "extra" values may be set.
Some components of this have been wired up for a while; this commit
finishes the compiler, runtime, and JIT support.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (scm_bootstrap_intrinsics): Declare the new
intrinsics.
* libguile/jit.c (compile_call_f64_from_f64): Define code generators for
the new intrinsics.
* libguile/vm-engine.c (call-f64<-f64): New instruction.
* module/language/cps/effects-analysis.scm:
* module/language/cps/reify-primitives.scm (compute-known-primitives):
* module/language/cps/slot-allocation.scm (compute-var-representations):
* module/language/cps/specialize-numbers.scm (specialize-operations):
* module/language/tree-il/cps-primitives.scm (abs):
* module/system/vm/assembler.scm (system, define-f64<-f64-intrinsic):
(sqrt, abs, fsqrt, fabs):
* module/language/cps/types.scm (fsqrt, fabs): Add new f64<-f64
primitives.
* module/language/cps/closure-conversion.scm (compute-elidable-closures):
New function.
(convert-one, convert-closures): Add ability to set "self" variable of
$kfun to $f, hopefully avoiding passing that argument in some cases.
* module/language/cps/compile-bytecode.scm (compile-function): Pass the
has-closure? bit on through to the assembler.
* module/system/vm/assembler.scm (begin-standard-arity)
(begin-opt-arity, begin-kw-arity): Only reserve space for the closure
as appropriate.
* module/language/cps/slot-allocation.scm (allocate-args)
(compute-defs-and-uses, compute-needs-slot)
(compute-var-representations): Allow for closure slot allocation
differences.
* module/language/cps/cse.scm (compute-defs):
* module/language/cps/dce.scm (compute-live-code):
* module/language/cps/renumber.scm (renumber, compute-renaming):
(allocate-args):
* module/language/cps/specialize-numbers.scm (compute-significant-bits):
(compute-defs):
* module/language/cps/split-rec.scm (compute-free-vars):
* module/language/cps/types.scm (infer-types):
* module/language/cps/utils.scm (compute-max-label-and-var):
* module/language/cps/verify.scm (check-distinct-vars):
(compute-available-definitions): Allow closure to be #f.
* module/language/cps/simplify.scm (eta-reduce): Fix renaming of labels
referenced by prompts. Thanks a million to Stefan Israelsson Tampe
for the report and the fix! Fixes#33652.