| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
* txr.1: Improved description of quote operator.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Jump threading just needs to looks at the last instruction in
a basic blocks now; it's a waste of cycles to be pattern
matching on jump intruction patterns while peephole scanning.
* share/txr/stdlib/compiler.tl (compiler optimize): Invoke
new thread-jumps after peephole.
* share/txr/stdlib/optimize.tl (basic-blocks
thread-jumps-block): New method.
(basic-blocks peephole-block): Remove jump-threading cases;
they are in thread-jumps block.
(basic-blocks thread-jumps): New method.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks peephole-block):
Remove the special optimization involving an unconditional
jump followed by an if, to a block which tests the same
register with another if. This optimization can't match
because a jmp and if cannot be in a basic block together.
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks peephole-block):
If we move a frame instruction past a jump into the next
block, we must add that block's label to the rescan list.
There may be an opportunity to propagate the frame instruction
deeper into that block. I'm not seeing a difference from this
change in the compilation of the standard library, which
indicates that this is happening by fluke; the alteration of
that block is happening before it has been visited.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (struct basic-blocks): Include
the close instruction in the set which terminate a basic
block. A close is an unconditional jump; execution never
continues after a close instruction, but goes unconditionally
to a branch target.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If cut-block is called during peephole optimization, it can
introduce blocks that can be missed, in which there might be
some opportunity for peephole reduction. Let's keep track
of newly added blocks in a re-scan list.
* share/txr/stdlib/optimize.tl (struct basic-blocks): New
slot, rescan.
(basic-blocks cut-block): Add new block's label to
rescan list.
(basic-blocks peephole-block): New method, formed out of the
bulk of basic-blocks peephole.
(basic-blocks peephole): After processing the blocks from
the hash table, iterate on the rescan list.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (struct basic-blocks):
jump-ops, new static member.
(basic-blocks :postinit): Cut the code into basic blocks
rather than extended basic blocks. This means that the
insruction which follows every jumping instructions is now a
block leader. Every block needs a label, so we add them.
(basic-blocks peephole): The optimization which slides a frame
instruction past a jump must be refactored to move the frame
instruction into the next block. Firstly, moving anything
past a jump instruction is no longer allowed, because the
result is no longer a basic block. Secondly, doing so prevents
further frame movements, because the block no longer has any
instructions after the jump over which the frame can be moved.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The jend pseudo-instruction is a simple alias for end. It
indicates a jumping end: an end that does not fall through to
the next instruction but could go somewhere else.
This is for "future correctness" as well as clarity. The
difference is important in analysis of code into basic blocks.
Currently this won't make a difference because all the jend
instructions except for the one at the end of compiled
top-level form are followed by a label which kicks off a basic
block anyway.
* share/txr/stdlib/asm.tl (defopcode-alias): New macro.
(jend): New opcode, defined as alias for end.
* share/txr/stdlib/compiler.tl (comp-unwind-protect,
comp-lambda-impl, compile-toplevel): Use jend instruction for
a jumping end: the one after the protected code block of a
uwprot, the one at the end of a function, and the one at the
end of a top-level form.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since we have are breaking binary compatibility in the
upcoming TXR 252, we might as well take the opportunity to
remove deprecated opcodes that the compiler doesn't use.
* share/txr/stdlib/asm.tl (op-fin): Opcode removed.
(op-pprof): Derive directly from op-end rather than op-fin.
(op-movrsi, op-movsmi, op-movrbi, op-movi-pseudo): Opcodes
removed.
* vm.c (vm_fin, vm_movrsi, vm_movsmi, vm_movrbi): Functions
removed.
(vm_execute): FIN, MOVRSI, MOVSMI, MOVRBI cases removed.
* vmop.h: Regenerated.
(vm_op_t): Enum members FIN, MOVRSI, MOVSMI, MOVRBI removed.
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (obj_print_impl): Don't pass non-symbols to fboundp.
This causes a problem in the case where we are printing an
object like ((lambda ...) ...). The car of this object is
the (lambda ...) form. When when pass this to fboundp, the
underlying function lookup mechanism wants to turn it into
a function object and tries to expand it. This can error out
if the lambda has bad syntax, which can happen because it's
just data that we are trying to print.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The block elimination logic doesn't work for self-recursive
functions, even if they invoke no block returning, and use
only system functions that don't have anything to do with
block returns. This is because the recursive call is not
recognized, and treated as a call to an unknown function.
Let's put in a simple hack. The defun and defmacro operators
will use a new secret special operator called sys:blk instead
of block to generate the block. The compilation of sys:blk
will assume that (sys:blk name ...) is only used in a defun or
defmacro by that same name, and include name in the list of OK
functions.
So that functions created using the interpreter and then
dynamically compiled will also benefit, we add this operator
to the interpreter.
* eval.c (sys_blk_s): New symbol variable.
(op_defun): For defun and defmacro, use sys:blk for the block
for the block
(eval_init): Initialize sys_blk_s with the interned symbol
sys:blk. Register the sys:blk operator.
* share/txr/stdlib/compiler.tl (compiler compile): Recognize
the sys:blk special form and handle via comp-block.
(comp-block): If sys:blk is being compiled, then include the
block name in the list of functions that do not perform block
returns. (If this is false, other checks will fail before use
that.)
(expand-defun): Use sys:blk for defun and defmacro.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Closures do not share t-registers with surrounding code; they
do not store a value into such a register that code outside
the closure would read and vice versa.
When compiling closures, we can can temporarily reset the
compiler's t-register allocator machinery to get low
t-register values. Then, when executing the closure, we
reserve space just for the registers it needs, not based off
the containing vm description.
Here we make a backwards-incompatible change. The VM close
instruction needs an extra parameter indicating the number of
t-regisers. This is stored into the closure and used for
allocating the frame when it is dispatched.
* parser.c (read_file_common): We read nothing but version 6
tlo files now.
* share/txr/stdlib/asm.tl (op-close asm): Parse new ntreg
argument from close syntax, and put it out as an extra word.
Here is where we pay for this improvement in extra code size.
(op-close dis): Extract the new argument from the machine code
and add it to the disassembled format.
* share/txr/stdlib/compiler.tl (compile-in-toplevel): Save and
restore the t-reg discards list also. Don't bother with a
gensym for the compiler; the argument is always a symbol,
which we can use unhygienically like in with-var-spy.
(compile-with-fresh-tregs): New macro based on
compile-in-toplevel: almost the same but doesn't reset the
level.
(comp-lambda-impl): Use compile-with-fresh-tregs to compile
the entire closure with a minimized register set.
Place the treg-cntr into the closure instruction to indicate
the number of registers the closure requires.
* vm.c (struct vm): New member, nreg.
(vm_make_closure): New parameter, nreg, stored into the
closure.
(vm_close): Extract a third opcode word, and pull the nreg
value from the bottom half. Pass this to vm_make_closure.
(vm_execute_closure, vm_funcall_common): Calculate frame size
based on the closur's nreg rather than the VM description's.
* txr.1: Document that the upcoming version 252 produces
version 6.0 object files and only loads version 6.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This optimization identifies let blocks whose variables are
not captured by closures. The variables are relocated to
registers and the frame M N ... end reg wrapping is removed.
* parser.c (read_file_common): Load version 6 files.
We remain backwards-compatible.
* share/txr/stdlib/compiler.tl (var-spy, capture-var-spy): New
structure types.
(struct compiler): New slot, var-spies.
(with-var-spy): New macro.
(compiler (alloc-new-treg, unalloc-reg-count, push-var-spy,
pop-var-spy)): New methods.
(compiler (comp-atom, compt-setq, comp-list-setq,
comp-lisp1-value)): Inform the spies in the spy notification
stack about assignments and accesses.
(compiler eliminate-frame): New method.
(compiler comp-let): Use spies to determine which variables
from this frame are captured, and if none are, then use
eliminate-frame to rename all the variables to t-registers and
drop the frame setup/teardown.
(compiler comp-lambda): Set up a capture-var-spy which
intercepts accesses and assignments within a lambda, and
informs other spies about the captures.
(%tlo-ver%): Bump compiled file version to to (6 0), because
of some behavioral changes necessary in the VM. We might
revert this if the issues are solved differently.
* vm.c (vm_getz): Do not null out T registers.
(vm_execute_toplevel, vm_execute_closure): Use zalloca to
allocate the register part of the frame, so T registers are
initialized to nil.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (dedup-labels): Use
rewrite-case macro defined in the same file instead of
rewrite/lambda/match-case. Also change two-argument list*
to cons.
|
|
|
|
|
|
|
|
|
|
| |
* genvmop.txr: Define VM_LEV_SIZE from %lev-size%.
* vm.c (vm_make_desc): Use VM_MAX_LEV and VM_LEV_SIZE instead
of incorrect hard-coded values of 256 that were right for an
old version of the vm.
* vmop.h: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Bad test case:
(unwind-protect 42 1 2 3) -> 3 ;; should be 42
* share/txr/stdlib/compiler.tl (compile comp-unwind-protect):
In the case when the protected code compiles to zero code,
because it is a simple variable or constant, the code that
we return must still nominate the that fragment's output
register as its output, and not the output register of the
cleanup forms.
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-hash-match): Use
mac-param-bind instead of tree-bind, like in the other
functions.
|
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks peephole): Rename
jlabel3 variable to jlabel2, so it is in sequence after
jlabel0 and jlabel1.
|
|
|
|
|
| |
* txr.1: Replace obsolete @[...] predicate notation in the
my-cond example with working code.
|
| |
|
|
|
|
| |
* txr.1: "the match-case macro", not "the match-case".
|
|
|
|
|
|
| |
* txr.1: Explain that the dot position of a variable in a
predicate pattern corresponds to the usual application
syntax. Add an example of this from the test case file.
|
|
|
|
|
| |
* txr.1: Better wording is that the object is added as an
implicit rightmost argument.
|
|
|
|
| |
* txr.1: "three two" should be "second three".
|
|
|
|
|
| |
* txr.1: Clarify that expr is not evaluated if the
main-pattern fails to match.
|
|
|
|
| |
* txr.1: Fix "atom pattern nil nil".
|
|
|
|
|
|
|
|
| |
* txr.1: Improving text about variables. Removing obsolete
reference to parallel scoping behavior of @(and) and
mentioning that @(as) binds fresh variables, which could cause
multiple occurrences of a variable in the same patter not to
refer to the same variable.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Until now, the obj.[fun ...] syntax has uselessly denoted
exactly the same thing as [obj.fun ...]. This latter syntax
is what should be used for that meaning.
The new meaning of obj.[fun ...] will be that it performs
method dispatch, where obj is passed to obj.fun as
the leftmost argument: obj.[fun ...] is [obj.fun obj ...],
with obj evaluated once.
* share/txr/stdlib/struct.tl (qref): Expansion change done
here, with backward compat switch.
* share/txr/stdlib/termios.tl (termios (go-raw, go-cbreak)):
Some a.[b c] turned to [a.b c] here.
* tests/012/oop.tl (animal print): Likewise.
* tests/012/struct.tl: Likewise, and some expansion tests
updated to reflect the new expansion.
* txr.1: Documentation revised in multiple places and compat
note added.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (wrap-expr): Remove wrg local
function. Replace call with simple reduce-right,
which doesn't require a reversal of the original list.
(compiled-match): Likewise.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (match-guards wrap-expr): New
method.
(guard-distinction wrap-expr): New method.
(compiled-match wrap-guards): Reduce type-case to wrap-expr
method call.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (match-guard assignments): Use
simpler op expression to generate a function that produces set
assignments.
(match-guard lets): Use zip function instead of mapcar with
ret and quasiquote.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-match): Remove the rcons
entry which was supposed to be already gone in version 250,
and is no longer documented.
(compile-range-match): Edit parameter name to remove
misleading reference to rcons.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Re-synced to 251.
* txr.vim, tl.vim: Regenerated.
|
| |
|
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: New test case showing that existing
variables that don't match in an @(or) retain their values;
they do not become nil, unlike freshly bound variables in
non-matching or-clauses.
|
|
|
|
|
|
| |
* tests/011/patmatch.tl: back-referencing between the
expressions in an @(and) patter has recently been introduced,
and needs some coverage.
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-predicate-match): Always
allocate res-var as a gensym; do not use resvar. Otherwise we
will freshly bind resvar as a local, failing to back-reference.
* tests/011/patmatch.tl: Add test cases, the second of which
fails before this change.
|
|
|
|
| |
* tests/011/patmatch.tl: New test case.
|
|
|
|
|
| |
* share/txr/stdlib/optimize.tl (basic-blocks peephole): Use or
pattern to look for dframe as well as frame.
|
|
|
|
|
|
| |
* txr.1: Document that multi-sort takes a single function
in place of a list of one function. This has been a feature of
the implementation from the beginning.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If an (if reg label0) target branches due to reg being nil,
and the target of the branch is another branch instrution
of the form (ifq reg nil label1), we know that that branch is
not taken: the code following that instruction is executed.
THus can jump right to that code.
(if reg label0) (if reg xlabel)
... ...
label0 label0
(ifq reg nil label1) --> (ifq reg nil label1)
... xlabel
...
* share/txr/stdlib/optimize.tl (basic-blocks peephole): New
sub-case under (jmp @reg @jlabel).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These optimizations have to do with moving a (frame x y)
instruction past the next instruction. The goal is to move the
frame past a conditional branch, under the right
circumstances, so that the frame is eliminated when the branch
is taken.
* share/txr/stdlib/optimize.tl (basic-blocks (cut-block,
next-block)): New methods.
(basic-block peephole): Add two patterns: one to move a frame
past a mov, call or gcall. Another more complicated one to
move it past an if which jumps to an end.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-exprs-match): Sort the
expressions and patterns so trivial matches are processed
first. The original order is used for evaluating the
expressions.
|
|
|
|
|
|
|
| |
* lib.c (multi_sort): If any of the input lists is empty, then
there is an empty list of tuples to sort, producing a an
empty list that doesn't transpose back to a list of empty
lists. We code this as a special case.
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (if-match, match-case,
lambda-match): Instead of returning the result from the
case(s), which gets stored in a result variable, and setting a
flag to t, set the result variable inside the case, and return
t. This eliminates the flag. In match-case and lambda-match,
the cases can then be combined into an or form.
|
|
|
|
|
| |
* txr.1: The @avar variable may be in the dot position of the
form, denoting application.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All he typical uses of this are better served by the new
predicate match. If op is really needed, it can be used with
the DWIM form of the predicate, as in @[(op ...) ...].
* share/txr/stdlib/match.tl (compile-op-match): Function
removed.
(compile-match): Remove op case.
* tests/011/patmatch.tl: Keep op test cases by converting them
to predicate test cases.
* txr.1: Documentation removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/match.tl (compile-dwim-predicate-match):
Function removed. There is no more special @(dwim ...)
or @[...] pattern.
(compile-predicate-match): Function rewritten, providing
different syntax and semantics.
(compile-match): dwim dispatch removed.
(non-triv-pat-p): Replaced @(op ...) calls with new-style
predicate syntax.
(var-pat-p): Likewise, and upgraded one instance of old-style
predicate syntax to new.
* share/txr/stdlib/compiler.tl (reduce-or): Adjust predicate
pattern to new style.
* share/txr/stdlib/optimize.tl (dedup-labels): Likewise.
* tests/011/patmatch.tl: All test cases with predicate syntax
are updated to new style. One test case removed; some added.
* txr.1: Predicate patterns re-documented. All examples
involving predicate patterns updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
And binds left to right now; only or is parallel.
* share/txr/stdlib/match.tl (compile-and-mach): Do not compile
the patterns with copies of the var list, but with he one and
only incoming var-list. Consequently, there are not var lists
to merge. par-pat parameter renamed to and-pat.
* txr.1: Improve and/or documentation, clarifying scope
rules. Also, clarify that variables in non-matching patterns
of an or are no set to nil, if they are existing bindings from
before the or.
|