| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (clean-file): Under a log-level
of 1 or more, report clean-file removes a file.
(compile-update-file): Under a log level of 1 or more,
report when a compiled file was skipped due to being
up-to-date.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With log-level, we can obtain trace messages about
what file is being compiled and individual forms
within that file.
* autoload.c (compiler_set_entries): Intern the slot
symbol log-level.
* stdlib/compiler.tl (compile-opts): New slot, log-level.
(%warning-syms%): Add log-level to %warning-syms%.
Probably we need to rename this variable.
(compile-file-conditionally): Implement the two log
level messages.
(with-compile-opts): Allow/recognize integer option values.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function simplifies cleaning, by allowing a file to
be cleaned to be identified in much the same way as an input
file to load or compile-file.
* autoload.c (compiler_set_entries): The clean-file symbol
is interned and becomes an autoload trigger for the
compiler module.
* stdlib/compiler.tl (clean-file): New function.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The file compiler combines compiled forms into a single
list as much as possible so that objects in the list can
share structure (e.g. merged string literals). However,
when package-manipulating forms occur, like defpackage,
it has to spit these lists, since the package manipulations
of an earlier form affect the processing of a later form,
such as whether symbols in that form are valid.
This splitting does not take care of the case that an
empty piece may result when the very last form is a package
manipulation form. A nil gets written to the .tlo file,
which the load function does not like; load thinks that since
this is not a valid list of compiled forms, it must be the
version number field of a catenated .tlo file, and proceeds
to find it an invalid, incompatible version.
* stdlib/compiler.tl (dump-to-tlo): Use partition* rather than
split*. partition* doesn't leave empty pieces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/expander-let.tl: New file.
* autoload.c (expander_let_set_entries, expander_let_instantiate);
New static functions.
(autoload_init): Register autoloading of above new file via
above new functions.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
| |
* stdlib/awk.tl (awk-compile-time): New slot, funs.
(awk-expander): Gather :fun clauses info funs slot.
(awk): Include a labels form which injects the functions.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (comp-fbind): When after removing unused
functions we are left with an empty list (or the list of
functions was empty to begin with), let's only emit the body
fragment without any frame wrapping. We can't just return
bfrag because that was compiled in the environment which
matches the frame. Instead of the expense of compiling the
code again, we rely on eliminate-frame to move all v registers
up one level.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This change makes it possible to use the redirection macros
like -> and ->> everywhere in the awk macro, including the
init-forms of the :let clause.
* stdlib/awk.tl (sys:awk-mac-let-outer): New macro.
(sys:awk-mac-let): Move redirection macros into
awk-mac-let-outer.
(awk): Rearrange the order of wrapping. We split the
let so the awk-retval and aws-sym are bound outermost.
Then we have the outer macros that provide the
redirection operators. Then the application-defined
lets inside of that.
* txr.1: Documented wide scope of redirection macros.
|
|
|
|
|
|
|
| |
* stdlib/awk.tl (awk-state ensure-stream): Fix missing
handling for the :apf kind symbol used by appending.
* tests/015/awk-redir.tl: New file.
|
|
|
|
|
|
|
| |
* stdlib/awk.tl (sys:awk-redir): Fix regression from April
2018. The gensym variable introduced must be parallel bound,
since it is referenced by the init expression of the other
variable. This breaks all awk redirection operators.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The with-compile-opts macro is rewritten such that
it cad occur inside code that is being compiled, and
change compiler options for individual subexpressions.
It continues to work as before in scripted build steps
such as when calls to (compile-file ...) are wrapped
in it. However, for the time being, that now only works
in interpreted code, because with this change, when
a with-compile-opts form is compiled, it no longer
arranges for the binding of *compile-opts* to be visible
to the subforms; the binding affects the compiler's
own environment.
* stdlib/compiler.tl (with-compile-opts): Rewrite.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (compiler_let_s): New symbol variable.
(op_let): Recognize compiler-let for sequential
binding.
(do_expand): Traverse and diagnose compiler-let
form.
(eval_init): Initialize compiler_let_s and register
the interpreted version of the operator.
* stdlib/compiler.tl (compiler compile): Handle
compiler-let form.
(compiler comp-compiler-let): New method.
(no-dvbind-eval): New function.
* autoload.c (compiler-set-entries): Intern the
compiler-let symbol in the user package.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adding a progv operator, similar to the Common Lisp one.
* eval.c (progv_s): New symbol variable.
(op_progv): New static function.
(do_expand): Recognize and traverse the progv form.
(rt_progv): New static function: run-time support
for compiled progv.
(eval_init): Initialize progv_s, and register the the
op_progv operator interpreting function.
* stdlib/compilert (compiler compile): Handle progv
operator ...
(compiler comp-progv): ... via this new method.
* tests/019/progv.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We have a problem. If v is a dynamic variable, then
the form
(let (v)
(set (symbol-value 'v) 3))
is not behaving correctly; it's updating the top-level
value of v not the rebound one.
* eval.c (set_symbol_value): New static function.
(eval_init): Register sys:set-symbol-value intrinsic.
The top-vb variable, though no longer referenced by
the symbol-value place, because existing compiled
code depends on it.
* stdlib/place.tl (symbol-value): Rewrite the place
logic to use symbol-value to access the variable,
and set-symbol-value to update it, instead of referencing
sys:top-vb.
(sys:get-vb): This function has to stay, because it
provides run-time support for code compiled with the
buggy version of the place.
* tests/019/symbol-value.tl: New file.
|
|
|
|
|
| |
* stdlib/compiler.tl (with-compile-opts): Remove stray
character from "uncrecognized".
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.tl (defstruct): When generating the lambda that
initializes slots from boa arguments, instead of we use (set
(qref obj slot) val) instead of slotset. The qref macro will
diagnose use of nonexistent slots.Thus warnings are produced
for, say:
(defstruct (point x y) nil)
where x and y have not been defined, using the imperfect
approach of the qref implementation, which is better than
nothing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a defmacro form is compiled, the entire form is retained
as a literal in the output. This is wasteful and gives away
the source code. In spite of that, errors in using the
macro are incorrectly reported against defmacro, because
that is the first symbol in the form. These issues arise with
what arguments are passed as the first two parameters of the
compiler's expand-bind-mac-params function, and what exactly
it does with them. We make a tweak to that, as well as some
tweaks to all the calls.
* stdlib/compiler.tl (expand-bind-mac-params): There is
a mix-up here in that both the ctx-form and err-form
arguments are ending up in the compiled output. Let's
have only the first agument, ctx-form going into the
compiled output. Thus that is what is inserted into
the sys:bind-mach-check call that is generated.
Secondly, ctx-form should not be passed to the constructor
for mac-param-parser. ctx-form is a to-be-evaluated
expression which might just be a gensym; we cannot use
it at compile time for error reporting. Here we must
use the second argument. Thus the second argument is now
used only for two purposes: copying the source code info
to the output code, and for error reporting in
the mac-param-parser class. This second purpose is minor,
because the code has been passed through the macro expander
before being compiled, which has caught all the errors.
Thus the argument is changed to rlcp-form, reflecting its
principal use.
(comp-tree-bind, comp-tree-case): Calculate a simplified
version of the tree-bind or tree-case form for error reporting
and pass that as argument the ctx-form argument of
expand-bind-mac-params. Just pass form as the second argument.
(comp-mac-param-bind, comp-mac-env-param-bind):
Just pass form as the second argument of
expand-bind-mac-params.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks late-peephole):
The test whether lab2 is used is bogus, and will
never be true. The correct test is simply whether
the block has two or more rlinks. This makes no
difference in the standard library images. When
the bug appears, the manifestation would be that
a needed label is deleted, resulting in an exception
from the assembler.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
2022-09-13 commit 6e354e1c2d5d64d18f527d52db75e344a9223d95,
subject "compiler: bugfixes in dead code elimination",
introduced a problem. By allowing the closure body blocks to
be included in the links of the previous basic block that ends
in the close instruction, it caused liveness info to flow out
out of close blocks into the close instruction, which is
wrong. Thus registers used inside a closure, which are
entirely private, wrongly appear live outside of the closure,
interfering with optimizations like eliminating dead
registers.
We can't simply roll back the commit because the bug it
fixes will reappear. The fix is to pair the next field
with a prev field, and maintain them; don't rely on
the rlinks to point to the previous block.
* stdlib/optimize.tl (basic-block): New slot, prev.
(back-block join-block): As we delete the next block,
we must update that block's next block's prev link.
(basic-blocks link-graph): Build the prev links.
Fix the bug in handling the close instruction:
do not list the close body code among the links,
only the branch target of the close.
(basic-blocks do-peephole-block): In a few cases in
which we set the bl.next to nil, we also set the
bl.next.prev to nil, if bl.next exists.
(basic-blocks elim-dead-clode): Reset the bl.prev
of every block also.
(basic-block check-bypass-empty): Here, we no longer
depend on rlinks containing the previous block;
the prev gives it to us. So we move that fixup out
of the link, and also fix up the next blocks prev
pointer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For array-like objecgts, these objects use an
array-based merge sort, using an auxiliary array
equal in size to the original array.
To provide the auxiliary array, a new kind of very simple
vector-like object is introduced into the gc module: protected
array. This looks like a raw dynamic C array of val type,
returned as a val *. Under the hood, there is a heap object
there, which makes the array traversable by the garbage
collector.
The whole point of this exercise is to make the new mergesort
function safe even if the caller-supplied functions misbehave
in such a way that the auxiliary array holds the only
references to heap objects.
* gc.c (struct prot_array): New struct,
(prot_array_cls): New static variable.
(gc_late_init): Register COBJ class, retaining in
prot_array_cls.
(prot_array_mark, prot_array_free): New static functions.
(prot_array_ops): New static structure.
(prot_array_alloc, prot_array_free): New functions.
* gc.h (prot_array_alloc, prot_array_free): Declared.
* lib.c (mergesort, ssort_vec): New static function.
(snsort, ssort): New functions.
* lib.h (snsort, ssort): Declared.
* tests/010/sort.tl: Cover ssort.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We don't have a function in the hash table module which can
create a populated hash table in one step without requiring
the caller to create auxiliary lists. This new function fills
that gap, albeit with some limitations.
* hash.c (hash_props): New function.
(hash_init): Register hash-props intrinsic.
* tests/010/hash.tl: New tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* time.c (time_str_local, time_str_utc): New static functions.
(time_fields_local, time_fields_utc, time_struct_local,
time_struct_utc): Time argument
becomes optional, defaulted to current time.
(time_init): Use time_s symbol instead of interning
twice. Register new time-str-local and time-str-utc
intrinsics. Fix registration of functions that take
optional args.
* txr.1: New functions documented; optional arguments
documented; existing documentation revised.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Quasiquote patterns not containing unquotes are not
working, because the parser transforms them into
quoted objects. For instance ^#S(time) becomes
the form (quote #S(time)) and not the
form (sys:qquote (sys:struct-lit time)).
The pattern matching compiler doesn't treat quote
specially, only sys:qquote.
* parser.y (unquotes_occur): Function removed.
(vector, hash, struct, tree, json_vals, json_pairs):
Remove use of unquotes_occur. Thus vector, hash,
struct, tree and JSON syntax occurring within a
backquote will be turned into a special literal
whether or not it contains unquotes.
* lib.c (obj_print_impl): Do not print the
form (sys:hash-lit) as #Hnil, but #H().
* stdlib/match.tl (transform-qquote): Add a case
which will handle ^#H(), as if it were ^H(()).
Bugfix in the ^H(() ...) case. The use of @(coll)
means it fails to match the empty syntax when
no key/value pairs are specified, whereas
@(all) respects vacuous truth.
* test/011/patmatch.tl: A few tests.
* y.tab.shipped, y.tab.h.shipped: Updated.
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks local-liveness): Just
store the mask of defined registers into each live-info.
Do not propagate the defined mask from the next instruction
backwards. The way the defined mask is used in calc-liveness,
this makes no difference, and is simpler and faster.
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (compiler comp-call-impl): We can no longer
free the temporary registers as-we-go based on whether the
argument expression frag uses them as the output register
frag. Let's just put them all into the aoregs list to be freed
afterward.
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks rename): When we stop
the renaming due to an end instruction and the src
being a v-reg, we can still do the rename in that end
instruction itself. If the v-reg becomes invalid, that
doesn't happen until after the instruction.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (subst-preserve): Rename list param
to insn for clarity.
(careful-subst-preserve): New function. This is like
subst-preserve, but used only for instructions that
have destination registers. It performs a rewrite
such that those destination positions are avoided.
(basic-blocks rename): When the instruction has src
or dst as a target, don't just stop before that
insn. Do the substitution in the source operands using
careful-subst-preserve.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks do-peephole-block):
Remove the local function only-locally-used-treg.
This is unnecessary because the optimization is valid
even if the treg is used in downstream basic blocks.
It was necessary previously in the old version of
this optimization in which we deleted the first
instruction which sets the treg's value. We are now
depending on it being identified as a dead register.
Also, moving the rule to the end. The reason is
that there are cases when the pattern matches, but
it returns insns. That causes the rewrite macro to
march down to the next instruction, skipping other
patterns. This could be bad, unless the pattern is the
last one tried before the @else fallback.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of the conservative strategy in compiler comp-var of
loading variables into t-registers, and relying on optimization
to remove them, let's just go back to the old way: variables
are just registers. For function calls, we can detect mutated
variables and generate the conservative code.
* stdlib/compiler.tl (frag): New slots vbin and alt-oreg.
When a variable access is compiled, the binding is recorded
in vbin, and the desired output register in alt-oreg.
(simplify-var-spy): New struct type, used for detecting
mutated lexical variables when we compile a function argument
list.
(compiler comp-var): Revert to the old compilation strategy
for lexicals: the code fragment is empty, and the output
register is just the v-reg. However, we record the variable
binding and remember the caller's desired register in the
new frag fields.
(compiler comp-setq): Also revert the strategy here.
Here we get our frag from a recursive compilation, so
we just annotate it.
(compiler comp-call-impl): Use the simplify-var-spy to
obtain a list of the lexical variables that were mutated.
This is used for rewriting the frags, if necessary.
(handle-mutated-var-args): New function. If the mutated-vars
list is non-empty, it rewrites the frag list. Every element
in the frag which is a compiled reference to a lexical
variable which is mutated over the evaluation of the arg list
is substituted with a conservative frag which loads the
variable into a temporary register. That register thus
samples the value of the variable at the correct point in the
left-to-right evaluation, so the function is called with
the correct values.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This change is now possible due to the previous bugfix.
* stdlib/optimize.tl (basic-blocks rename): If
the source register is a v-reg, do not allow
the propagation past an end instruction. This
is a precaution because the end instruction
could be the end of the frame in which the
v-register is valid; we don't want to propagate
it outside of that frame.
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks rename): When
we encounter a close instruction, we must leave
it alone. The registers named in the argument area
of the instruction do not belong to the current
instruction stream or basic block; they belong to
the function body.
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks local-liveness): Handle all
instructions explicitly with no catch-all behavior. Make a
copy of the live-info even for instructions that have no
source or destination operands, so that they don't mistakenly
marked as having defs or refs.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (live-info): Slot def replaced by def0
and def1.
(basic-blocks local-liveness): The local function def becomes
defs: it can take two defs. These become def0 and def1. In the
catch instruction case, we use both arguments, capture the
resulting live-info and use it to call refs.
(basic-blocks rename): Check whether either def0 or def1 is
the source or destination.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks local-liveness): When
processing a pure def, we don't copy the live-info
unconditionally, which is waseteful since if the destination
register is a t-reg, we will invoke (new live-info) to
make yet another live info. Instead, let's destructively
mutate the incoming live info from the instruction below,
and return a copy that is made before that is done.
In the def-ref case, the local copy is entirely superfluous,
because in all cases we return a new object.
We also eliminate redundant (set [bb.li-hash insn] li)
evaluations.
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks local-liveness):
The exception symbol and argument registers in the
catch instruction are clobbers, not references.
We must treat them as defs. Unfortunately, the
instruction has two clobbers but live-info has
only one def slot, which should be fixed.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* optimize.tl (rename): Instead of a mapping operation,
we perform the substitution only until we hit an
instruction that defines either the src or dst register.
(basic-blocks do-peephole-block): Drop the conditions
for doing the rename: that neither register can be
defined somewhere in the rest of the block. This
restriction is too limiting. We have to be careful now;
we cannot delete the first instruction, and must only
set the recalc flag and add to the rescan list if the
substitution did something, to avoid looping.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks do-peephole-block): In the
unnecessary copying t-reg case, let's just stay away from
doing it if the source operand is a v-reg. It breaks under the
recent "eval order of variables" commit, indicating that the
conditions that it uses for replacing a v-reg with the t-reg
are not correct. The most likely reason is that the v-reg
can be assigned, but this doesn't show up in the liveness
info which tracks only t-regs.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/build.tl (sys:list-builder-flets, sys:build-expander,
build, buildn): Move to top of file. This resolves a circular
dependency triggered by the defstruct macro: it autoloads
struct.tl which autoloads other things, some of which depend
on the build macro. If we provide the build macro at the top,
everything is cool. The compiled version of build.tl doesn't
have this problem, because macro-time dependencies don't
affect compiled code. With this change, it's possible to
run the tests/012/compile.tl test case without stdlib
being compiled.
|
|
|
|
|
|
| |
* stdlib/optimizer.tl (basic-blocks do-peephole-block): Use
pushnew instead of push in one peephole case, so the block
isn't pushed onto the tryjoin and rescan lists twice.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We have the following problem: when function call argument
expressions mutate some of the variables that are being
passed as arguments, the left-to-right semantics isn't
obeyed. The problem is that the funcction call simply refers
to the registers that hold the variables, rather than to
the evaluated values. For instance (fun a (inc a)) will
translate to something like (gcall <n> (v 3) (v 3))
which is incorrect: both argument positions refer to the
current value of a, whereas we need the left argument
to refer to the value before the increment.
* stdlib/compiler.tl (compiler comp-var): Do not assert the
variable as the output register, with null code. Indicate
that the value is in the caller's output register, and
if necessary generate the move.
(compiler comp-setq): When compiling the right-hand-side,
use the original output register, so that we don't end
up reporting the variable as the result location.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (compiler): Remove discards slot.
(compile-in-toplevel, compile-with-fresh-tregs):
Do not save and restore discards.
(compiler maybe-mov): Method removed. It doesn't
require the compiler object so it can just be a function.
(maybe-mov): New function.
(compiler alloc-discard-treg): Method removed.
(compiler free-treg): No need to do anything with discards.
(compiler maybe-alloc-treg): No need to check discards.
(compiler (comp-setq, comp-if, comp-ift, comp-switch,
comp-block, comp-catch, comp-let, comp-fbind,
comp-lambda-impl, comp-or, comp-tree-case,
comp-load-time-lit): Use maybe-mov function instead of method.
(compiler comp-progn): Use alloc-treg rather than
alloc-discard-treg, and use maybe-mov function.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks num-blocks): New
method.
* stdlib/compiler.tl (compiler optimize): At optimization
level 6, instead of performing one extra pass of
jump threading, dead-code elimintation and peephole
optimizations, keep iterating on these until the number
of basic blocks stays the same.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks peephole-block): Drop the
code argument, and operate on bl.insns, which is stored
back. Perform the renames in the rename list after the
peephole pass.
(basic-blocks rename): New method.
(basic-blocks do-peephole-block): Implementation of
peephole-block, under a new name. The local function called
rename is removed; calls to it go to the new rename method.
(basic-blocks peephole): Simplify code around calls to
peephole-block; we no longer have to pass bl.insns to it,
capture the return value and store it back into bl.insns.
* stdlib/compiler.tl (*opt-level*): Initial
value changes from 6 to 7.
(compiler optimize): At optimization level 6,
we now do another jump threading pass, and
peephole, like at levels 4 and 5. The peephole
optimizations at level 5 make it possible
to coalesce some basic blocks in some cases,
and that opens up the possibility for more
reductions. The previously level 6 optimizations
are moved to level 7.
* txr.1: Updated documentation of optimization levels,
and default value of *opt-level*.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
| |
* stdlib/optimize.tl (basic-blocks peephole-block): Move local
rename function into main labels block, so other optimizations
will be able to use it. Remove an unused argument, and change
the recursion to a mapcar, since that's what it's doing.
|
|
|
|
|
|
|
|
|
|
|
| |
Contrary to the documentation, the later clauses of a condlet
have the earlier clause variables in scope.
* stdlib/ifa.tl (sys:if-to-cond): Change to different,
non-nesting expansion strategy. We lose the cond-oper
parameter.
(conda, condlet): Drop second parameter from calls
to if-to-cond.
|