* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
(*effect-free-primitives*, *effect+exception-free-primitives*): Detect
use of exact-integer?.
* module/language/tree-il/compile-cps.scm (canonicalize): Compile
exact-integer? to a fixnum?-or-bignum? check.
* module/language/cps/types.scm (thunk?, integer?): Remove predicates;
they were inferring incorrectly. I don't think they were being used
though (these primcalls don't reach here).
* module/language/cps/types.scm (logand): We were computing the wrong
ranges when either argument was negative; a terrible bug!
(logsub): Also fix range when A is negative and B is non-negative.
(ulogand): Tighten up range.
* module/language/cps/type-fold.scm (u64->scm, scm->u64): Fix
type-safety by adding casts.
* module/language/tree-il/compile-cps.scm (convert, canonicalize):
Simplify rsh and lsh compilation by not trying to avoid scm->u64 in
the early stages of the compiler.
* module/language/cps/types.scm: Remove some more needless type checker
definitions.
(u64-imm-=, u64-imm-<, imm-u64-<): Separate from the s64 definitions.
(s64-imm-=, s64-imm-<, imm-s64-<): New definitions.
* module/language/cps/specialize-numbers.scm (specialize-operations):
Before, this pass would reify e.g. uadd for an addition of s64 values
if it could prove that the result would be within the s64 range. But
this is really confusing if later we want to do range analysis over
the result. Additionally it would sometimes reify diamond control
patterns that weren't really amenable to CSE. So instead we now reify
instructions that can pass type checks, like "sadd" instead of
"uadd".
* module/language/cps/primitives.scm (*macro-instruction-arities*):
Declare new u64->s64, s64->u64, sadd, ssub, smul, sadd/immediate,
ssub/immediate, smul/immediate, slsh, and slsh/immediate primcalls
that don't have corresponding VM instructions.
* module/language/cps/effects-analysis.scm: The new instructions are
effect-free.
* module/language/cps/reify-primitives.scm (wrap-unary, wrap-binary):
(wrap-binary/exp, reify-primitives): Add horrible code that turns
e.g. sadd into a series of s64->u64, uadd, and then u64->s64. This
way we keep our ability to do range inference on unboxed signed
arithmetic, but we still bottom out to the same instructions for both
unboxed signed and unboxed unsigned arithmetic.
* module/language/cps/types.scm: Add type inferrers for new
instructions. Remove type checkers for some effect-free primitives.
* module/language/cps/compile-bytecode.scm (compile-function): Add
pseudo-emitter for u64->s64 and s64->u64 no-ops.
* module/language/cps/specialize-numbers.scm
(compute-specializable-fixnum-vars, compute-specializable-phis)
(apply-specialization): Don't specialize phis as fixnums. Need to try
again with some proper range analysis, as a variable defined with
tag-fixnum can indicate either a u64 or a s64.
* module/language/cps/reify-primitives.scm (reify-primitives): Remove
cases for ursh/immediate etc, as these should all be within range, by
construction.
* module/language/cps/specialize-numbers.scm (specialize-operations):
Only reify ursh/immediate, etc if the shift count is less than 64.
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
Remove specialization cases for ursh/immediate etc; this is the domain
of specialize-numbers.
* module/language/cps/types.scm (ursh, srsh, ulsh): Limit arguments to
be less than 63.
(ulsh/immediate): Assume parameter is in range.
* libguile/vm-engine.c (s64-imm=?, u64-imm<?, imm-u64<?, s64-imm<?)
(imm-s64<?): New instructions.
* libguile/instructions.c (FOR_EACH_INSTRUCTION_WORD_TYPE): Add new
X8_S12_Z12 word type used by the new S64/immediate instructions. A
Z12 is a 12-bit signed integer immediate.
* module/system/vm/assembler.scm: Export new instructions, and add
X8_S12_Z12 support. Also, add missing shufflers for X8_S12_C12.
* module/language/bytecode.scm (compute-instruction-arity):
* module/system/vm/disassembler.scm (unpack-s12, disassembler): Add
support for X8_S12_Z12.
* module/language/cps/types.scm (define-predicate-inferrer/param): New
helper.
(u64-=, u64-<, s64-<): Remove type checkers; this procedure does not
cause &type-check.
(u64-imm=?, s64-imm=?, u64-imm<?, imm-u64<?, s64-imm<?, imm-s64<?):
New type inferrers.
* module/language/cps/type-fold.scm (define-unary-branch-folder*): New
helper.
(u64-imm=?, s64-imm=?, u64-imm<?, imm-u64<?, s64-imm<?, imm-s64<?):
New branch folders.
* module/language/cps/reify-primitives.scm (reify-primitives): Reify
constants for new immediate branching primcalls if values out of
range.
* module/language/cps/effects-analysis.scm: Add support for new
primcalls.
* module/language/cps/compile-bytecode.scm (compile-function): Add
support for new primcalls and instructions. Compile u64-imm-= to
s64-imm=?.
* module/language/cps/type-fold.scm (compare-integer-ranges): Rename
from compare-ranges, as we can't compare ranges that might include a
NaN.
(<, =): Update uses.
* module/language/cps/compile-bytecode.scm (compile-function): Add
support for tag-fixnum/unlikely.
* module/language/cps/cse.scm (compute-equivalent-subexpressions): Add
equivalent subexpressions for tag-fixnum.
* module/language/cps/effects-analysis.scm:
* module/language/cps/primitives.scm (*macro-instruction-arities*): Add
tag-fixnum/unlikely.
* module/language/cps/specialize-numbers.scm (specialize-u64-unop)
(specialize-u64-binop, specialize-u64-shift)
(specialize-u64-comparison): Make the arg unboxers and result boxers
into keyword arguments.
(specialize-s64-unop): New helper.
(specialize-fixnum-comparison, specialize-fixnum-scm-comparison)
(specialize-scm-fixnum-comparison): Rename from
specialize-s64-comparison et al. Perhaps this should be expanded
again to include the whole s64 range, once we start to expand scm->s64
et al.
(specialize-operations): Specialize arithmetic, etc on signed
operands and results. Use less powerful unboxing/boxing ops if
possible -- e.g. tag-fixnum instead of u64->scm. Prefer fixnum
comparisons over u64 comparisons.
(compute-specializable-fixnum-vars): New helper.
(compute-specializable-phis): Specialize fixnum phis as well.
(specialize-primcalls): Specialize untag-fixnum of a constant to
load-s64.
* module/language/cps/type-fold.scm (u64->scm, s64->scm):
(scm->s64, scm->u64): Reduce to fixnum ops where possible.
* module/language/cps/types.scm: Remove type checkers for ops that don't
throw type errors. Alias tag-fixnum/unlikely to tag-fixnum.
* module/language/cps/types.scm (&fx32-min, &fx32-max, &fx64-min)
(&fx64-max): New internal definitions.
* module/language/cps/types.scm (type-entry-saturating-union): Add more
stops as we saturate ranges towards infinity.
* module/language/cps/slot-allocation.scm (compute-var-representations):
If an optimization pass decided to e.g. use untag-fixnum for one
definition of a variable and e.g. vector-length for the other, assume
that their values are compatible. We don't know at this point whether
the values are meant to be s64 (e.g. because vector-length is a subset
of the s64 range) or u64 (e.g. because although we're calling
untag-fixnum on the value, actually we now that the value is
non-negative, or actually we just want the unsigned bits). Anyway we
default to u64. In the future we can perhasps be more precise.
* libguile/vm-engine.c (srsh, srsh/immediate): New instructions.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/effects-analysis.scm:
* module/language/cps/reify-primitives.scm (reify-primitives):
* module/language/cps/slot-allocation.scm (compute-var-representations):
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
* module/language/cps/types.scm (srsh, srsh/immediate):
* module/system/vm/assembler.scm: Add support for new instructions.
* module/language/cps/types.scm (ulsh, ursh): Remove type checkers, as
these are effect-free. Limit range of ursh count.
* module/language/cps/type-fold.scm (*primcall-macro-reducers*):
(define-primcall-macro-reducer, define-unary-primcall-macro-reducer):
(define-binary-primcall-macro-reducer): New facility, for reductions
on which reductions should run. Define macro reducers for mul, lsh,
and rsh. Move mul reducer to be a mul/immediate reducer.
(logbit?): Use target fixnum range.
(local-type-fold): Adapt to call macro reducers first.
* module/language/cps/reify-primitives.scm (reify-primitives): Reify
mul/immediate back to mul.
* module/language/cps/effects-analysis.scm: Remove case for "ash".
* module/language/cps/types.scm (ash): Remove.
* module/language/tree-il/compile-cps.scm (convert, canonicalize):
Convert "ash" to "lsh"/"rsh" early on.
* module/system/base/target.scm (target-fixnum?): New procedure.
* module/system/base/target.scm (target-most-negative-fixnum):
(target-most-positive-fixnum): New definitions.
* module/language/cps/types.scm (constant-type, define-exact-integer!)
(&min/fixnum, &max/fixnum): Use new definitions.
(&max/vector): Use target-max-vector-length.
* module/language/cps/specialize-numbers.scm (specialize-s64-comparison)
(specialize-s64-scm-comparison, specialize-scm-s64-comparison): New
helpers.
(specialize-scm-u64-comparison, specialize-u64-scm-comparison):
Remove. Comparing SCM as s64 is better as fixnums are a subset of
s64, not u64.
(specialize-operations): Prefer s64 comparisons when we can't
specialize both arguments; this at least inlines the fixnum case.
* module/language/tree-il/compile-cps.scm (canonicalize): Convert <=,
>=, and > primcalls to <.
* module/language/cps/primitives.scm (*comparisons*):
* module/language/cps/effects-analysis.scm: Remove superfluous
primcalls.
* module/language/cps/specialize-numbers.scm
(specialize-u64-scm-comparison): Only emit < primcalls for ordered
comparisons.
(specialize-scm-u64-comparison): New helper.
* module/language/cps/specialize-numbers.scm (specialize-operations):
Remove support for >=, <=, and the like.
* module/language/cps/type-fold.scm: Remove folders for <= and so on.
* module/language/cps/types.scm (define-=-inferrer, define-<-inferrer):
New helpers; use them for all = and < variants. Remove checkers and
inferrers for <= and the like.
* module/language/cps/compile-bytecode.scm (compile-function): Remove
unnecessary cases.
* libguile/throw.h (scm_ithrow, scm_throw): Mark as SCM_NORETURN.
* libguile/throw.c (scm_throw, scm_ithrow): Adapt to not return.
* libguile/vm-engine.c (throw, throw/value, throw/value+data): New
instructions.
* libguile/vm.c (vm_throw, vm_throw_with_value)
(vm_throw_with_value_and_data): New helpers.
* module/language/cps/compile-bytecode.scm (compile-function): Add cases
for new instructions.
* module/language/cps/prune-bailouts.scm (prune-bailouts): More simple,
now that there are no $kreceives in play.
* module/language/cps/reify-primitives.scm (reify-clause): Update
reification of no-clause functions to use new throw op.
* module/language/tree-il/compile-cps.scm (convert): Convert invocations
of the variable-arity 'throw primitive from Tree-IL to the new
fixed-arity CPS instructions.
* module/system/vm/assembler.scm (emit-throw/value*)
(emit-throw/value+data*, emit-throw): Export new instructions.
* module/system/vm/disassembler.scm (code-annotation): Add annotation.
* libguile/vm-engine.c (lsh, rsh, lsh/immediate, rsh/immediate): New
instructions taking unboxed bit counts.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/effects-analysis.scm:
* module/language/cps/specialize-numbers.scm (specialize-f64-unop):
(specialize-u64-unop): Add ability to specialize add/immediate, etc,
and add lsh/immediate as well.
(specialize-u64-binop, specialize-u64-shift): Move rsh/lsh
specialization to its own procedure, given that the bit count is
already unboxed.
(specialize-operations): Adapt to support more /immediate
instructions.
* module/language/cps/type-fold.scm (mul): Reify an lsh/immediate
instead of an ash.
* module/language/cps/types.scm (compute-ash-range): Add type inferrers
for lsh, rsh, and their immediate variants.
* module/system/vm/assembler.scm: Export emit-lsh and so on.
* module/language/tree-il/compile-cps.scm (convert): Convert "ash" on
immediates to rsh/immediate or lsh/immediate.
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
Don't restrict /imm params to encodeable immediates; specialize any
imm. Rely on reify-primitives to undo the transformation if needed.
* module/system/base/target.scm (target-max-size-t):
(target-max-size-t/scm, target-max-vector-length): New public
functions.
* module/language/cps/types.scm (type-entry-saturating-union): Remove
restriction of polymorphic types to be within max-size-t; this could
incorrectly apply constraints on numeric values.
(&max/size, &max/scm-size): Use target-max-size-t.
(*max-size-t*): Remove; replace uses with (target-max-size-t).
* module/language/cps/optimize.scm (optimize-first-order-cps): Move up
the simplify-primcalls pass, to allow DCE to take away unneeded
constants. An incremental step
* module/language/cps/reify-primitives.scm (reify-primitives): Add pass
to re-reify constant arguments for primcalls with immediate parameters
that can't be encoded as bytecode.
* module/language/cps/compile-bytecode.scm (compile-function): Update
add/immediate, etc.
* module/language/cps/slot-allocation.scm (compute-needs-slot):
Simplify.
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
Rework for add/immediate, etc.
* module/language/cps/types.scm (define-unary-result!)
(define-binary-result!): Take types as params instead of variables, so
we can share this code with /imm variants.
(add/immediate, sub/immediate, uadd/immediate, usub/immediate)
(umul/immediate, ulsh/immediate, ursh/immediate): Update type
inferrers.