* module/language/tree-il/peval.scm (peval): The <dynwind> compiler will
copy the winder and unwinder values, so make sure that they are
constant, and if not, create lexical bindings. Fixes
http://debbugs.gnu.org/9844.
* test-suite/tests/tree-il.test ("partial evaluation"): Add a couple
<dynwind> tests.
* module/language/tree-il/peval.scm (peval): Since constant-expression?
is used to determine whether to copy values, return #f if any lexical
is assigned.
* module/ice-9/psyntax.scm (chi-top-sequence): Detect bindings to
identifiers introduced by macros. In that case, in order to preserve
hygiene, uniquify the variable's name, but in a way that is
reproduceable (i.e., yields the same uniquified name after a
recompile).
* module/ice-9/psyntax.scm (id-var-name): For mapping identifiers to
toplevel definitions, also compare against the module.
(resolve-identifier): Pass the module to id-var-name when looking up
identifiers.
(free-id=?): Adapt to id-var-name change.
(chi-top-sequence): When adding a mapping from the given identifier
to a toplevel definition, make the name be a pair.
* module/ice-9/psyntax.scm (resolve-identifier): Take an additional
argument, indicating whether syntax parameters should be resolved or
not. Just return three values: the binding type and value, and the
module for resolving toplevels.
(chi-install-global): Take an extra arg, the type. If we are defining
a syntax parameter, construct a pair for the binding.
(chi-body): Syntax parameters now use a per-parameter unique value (a
pair) as a key in the expansion-time environment `r'.
(syntax-parameterize): Don't allow parameterization of
non-parameters. This is an incompatible change, but it is for the
better; you don't want to allow users to parameterize `lambda', after
all.
* module/ice-9/psyntax.scm (define-syntax-parameter): New toplevel form.
Will be used to implement syntax parameters, following Barzilay,
Culpepper, and Flatt's 2011 SFP workshop paper, "Keeping it Clean with
syntax-parameterize". Adds a new binding type and definition form.
* module/ice-9/psyntax.scm (id-var-name): Add a nice long comment.
(lookup): Remove, as it is no longer used.
(resolve-identifier): New helper, replaces most uses of id-var-name
then `lookup'.
(syntax-type, syntax, set!, fluid-let-syntax): Adapt to use
resolve-identifier.
(free-id=?): Adapt to id-var-name returning syntax objects.
* module/ice-9/psyntax.scm (chi-top-sequence): Reimplement, more like
chi-body. Instead of adding empty definitions to the toplevel, add
toplevel definitions to the wrap shared by all forms in the sequence.
* module/language/tree-il/primitives.scm (resolve-primitives!): Don't
resolve toplevels defined in the same compilation unit to primitives,
as it could be that the module doesn't have those bindings yet.
* libguile/_scm.h (SCM_OBJCODE_MAJOR_VERSION): Bump the major version,
indicating the first incompatibility between 2.0 and 2.2.
* libguile/vm-i-scheme.c (string-length, string-ref, vector-length): New
instructions.
* module/language/tree-il/compile-glil.scm (*primcall-ops*): Add
primcall ops for the new instructions.
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*, *effect-free-primitives*): Recognize
vector-length as an effect-free primitive.
* module/language/tree-il/primitives.scm (*primitive-expand-table*):
Remove a hack to compensate for the lack of a good inliner, now that
we do have a good inliner.
* module/language/tree-il/peval.scm (peval): Accessor primitives applied
to constants are pure if the call type-checks. Also, fold constants
in accessor primcalls.
* test-suite/tests/tree-il.test ("partial evaluation"): Fix the "yo"
test.
* libguile/weak-vector.c:
* libguile/weak-vector.h: Renamed from weaks.[ch]. Remove weak pairs.
They were not safe to access with `car' and `cdr'. Remove weak alist
vectors, as we have weak tables and sets. Reimplement weak vectors,
moving the implementation here.
* libguile/vectors.c:
* libguile/vectors.h: Remove the extra header word. Use
scm_c_weak_vector_ref / scm_c_weak_vector_set_x to access weak
vectors.
* libguile/snarf.h: Remove the extra header word in vectors.
* libguile/threads.c (do_thread_exit, fat_mutex_lock, fat_mutex_unlock):
Instead of weak pairs, store thread-owned mutexes in a list of
one-element weak vectors.
* libguile/guardians.c (finalize_guarded): Similarly, store object
guardians in a list of one-element weak vectors.
* libguile/modules.c (scm_module_reverse_lookup): We no longer need to
handle the case of weak references.
* libguile/print.c (iprin1): Use the standard vector accessor to print
vectors.
* libguile.h:
* libguile/Makefile.am:
* libguile/gc-malloc.c:
* libguile/gc.c:
* libguile/goops.c:
* libguile/init.c:
* libguile/objprop.c:
* libguile/struct.c: Update includes.
* module/ice-9/weak-vector.scm: Load weak vector definitions using an
extension instead of %init-weaks-builtins.
* test-suite/tests/weaks.test: Use the make-...-hash-table names instead
of the old alist vector names.
* module/language/tree-il/analyze.scm (analyze-lexicals): When stepping
into a non-tail form, we know that labels allocation will be invalid,
so use an empty labels set. Fixes http://debbugs.gnu.org/9769.
* test-suite/tests/tree-il.test ("labels allocation"): Add a test.
* module/language/tree-il/peval.scm (peval): Factor constant folding out
to a helper. Use it in the accessor case in addition to the normal
effect-free-primitive case.
* test-suite/tests/tree-il.test: Add a test.
* module/language/tree-il/peval.scm (peval): Add special handlers for
memq and memv, as inline.scm used to have. This is important for
`case' clauses. It is very ugly, though.
* test-suite/tests/tree-il.test ("partial evaluation"): Add tests.
* module/language/tree-il/primitives.scm (*primitive-accessors*): New
set of primitives: those that access mutable memory, but are otherwise
pure. Include bytevector references here.
(accessor-primitive?): New public predicate.
* module/language/tree-il/peval.scm (peval): Refactor to distinguish
constructor-primitive? from accessor-primitive?.
This commit changes to use <operand> structures to hold the context
needed to visit lexical bindings lazily, in context, instead of eagerly
visiting them for value. This laziness enables inlining of mutually
recursive bindings.
* module/language/tree-il/peval.scm (<var>): Remove comment about copy
propagation having to run build-var-table; things don't work like that
any more.
(build-var-table): Build <var> entries for all variables, even
unreferenced variables.
(alpha-rename): Remove. We will rename bindings on-demand now.
(peval lookup-var): New helper, to fetch the <var> of a gensym.
(peval fresh-gensyms): Fold here, under peval, and in it, handle
updating the store to record a mapping between new names and <var>
entries from the source program.
(peval record-source-expression): Don't call build-var-table on the
new expression, as alpha-renaming happens on-demand now.
(peval prune-bindings): Rewrite to work with mutually-recursive
bindings, while optionally preserving binding order.
(peval extend-env): New helper.
(peval loop): OK, here goes... Remove the `operand' context, as now we
visit operands lazily. Add a `call' context, which does not
copy-propagate lambda expressions, used to residualize a call after
aborting an inlining attempt. Change the `env' to be a mapping of
gensym to <operand>. Instead of looking up the operand's binding then
alpha-renaming it, just rely on the fact that visiting the operand
will rename it if necessary.
If we residualize a lexical, do so with the fresh name from the
environment. If we visit an operand and it doesn't turn out to be
constant, we will never be able to copy it, and so cache that fact in
the operand. If we residualize a binding and we know what the value
should be, record that binding so that prune-bindings won't have to
visit it again. If the operand folds to a constant, cache that too,
to save effort when unrolling loops.
For let, letrec, fix, and lambda-case, instead of visiting the
bindings eagerly for value, simply record the source expressions and
environments in an <operand> and rely on copy-propagation to visit
them later in the right context. In the case of letrec and fix, this
allows mutually-recursive bindings to be inlined.
Refactor folding of "constructors" (which still need renaming) to
avoid visiting operands twice in some contexts.
For applications, if we have to abort, process the procedure in call
context, which allows some folding but avoids copying lambdas. If we
find a recursive procedure, mark intervening counters as recursive
too, to allow for mutual recursion at the top level.
For lambdas, if we are processing for value, record the source
expression so we can detect recursion. This was previously done in
the lexical-ref copy propagator.
* test-suite/tests/tree-il.test ("partial evaluation"): Remove unused
recursive lexicals in a couple of cases. Add a couple test cases for
pruning. Add a few recursive binding cases.