1 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; and now
for something completely different
...
3 ;; UrForth
/C Forth Engine
!
4 ;; Copyright
(C
) 2023 Ketmar Dark
// Invisible Vector
6 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 ;; simple superinstruction optimiser
8 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 this is very simple peephole optimiser
. it is called by
"INTERPRET" after
12 compiling a literal or a word. also, compiler words which create branches
13 take care of resetting the optimiser
, to avoid optimising things like
14 "7 begin and" to "(lit-and)" (to avoid breaking branches
).
16 compiler words to mark/resolve branches are aware of the optimiser. you
17 should use those words in your code instead of direct poking
.
19 we are using the ring buffer
to record recent commands
, because it is cheap
.
20 reseting the buffer is cheap too
: just
write "0" to the current ring buffer
21 entry
. it works because all optimisers check buffer validity first
.
25 vocabulary
(sinopt
-peephole
) (hidden
)
26 also
-defs
: (sinopt
-peephole
)
29 \ $DEFINE DEBUG
-SINOPT
31 $DEFINE DEBUG
-SINOPT
-SIMPLE
-BITWISE
32 $DEFINE DEBUG
-SINOPT
-SIMPLE
-SWAP
-INC
-SWAP
33 $DEFINE DEBUG
-SINOPT
-SIMPLE
-INC
-DEC
34 $DEFINE DEBUG
-SINOPT
-SIMPLE
-CELLS
35 $DEFINE DEBUG
-SINOPT
-SIMPLE
-CELLS
-INC
-DEC
36 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
37 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
-INCS
38 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKE
-INCS
39 $DEFINE DEBUG
-SINOPT
-SIMPLE
-SHIFTS
40 $DEFINE DEBUG
-SINOPT
-SIMPLE
-MULS
41 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIVS
42 $DEFINE DEBUG
-SINOPT
-VARS
43 $DEFINE DEBUG
-SINOPT
-STACK
-OPS
49 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53 ;; last compiled word address
54 : prev
-cw
( -- addr
) postpone here postpone
8- ; immediate
55 : prev
-lit
-cw
( -- addr
) postpone here postpone
12 postpone
- ; immediate
56 \ debug
:decompile prev
-lit
-cw
58 : last
-cw
( -- addr
) postpone here postpone cell
- ; immediate
60 : 2cells
( n
-- n
-8 ) compiler
:?comp
[ 2 cells
] imm
-literal literal
; immediate
61 : 3cells
( n
-- n
-8 ) compiler
:?comp
[ 3 cells
] imm
-literal literal
; immediate
62 : 2:-cells
( n
-- n
-8 ) postpone
8- ; immediate
63 : 3:-cells
( n
-- n
-8 ) compiler
:?comp
[ 3 cells
] imm
-literal literal postpone
- ; immediate
66 : compile
! ( val addr
-- ) compiler
:?comp compile
! ; immediate
69 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
70 ;; ring buffer with instruction addresses
73 ;; ring buffer
for 8 instructions
.
74 ;; WARNING
! should be power of
2!
75 8 constant buffer
-size
76 buffer
-size cells
1- constant buffer
-pos
-mask
78 create buffer buffer-size cells allot create;
79 buffer buffer
-size cells erase
81 ;; positions are byte offsets
!
82 0 value buffer
-lit
-pos
;; position of the last compiled
(LIT
); -1 means
"not there"
83 0 value buffer
-tail
;; last used buffer entry
87 ;; put zeroes
to the last ring buffer element
.
88 ;; this way any check will definitely fail
.
89 buffer
-tail buffer
+ 0!
92 : (put
-addr
) ( addr newofs
-- ) buffer
+ ! ;
93 : (advance
-buf
) ( -- newofs
) buffer
-tail cell
+ buffer
-pos
-mask and dup
to buffer
-tail
;
94 : lit
-reset
( -- ) -1 to buffer
-lit
-pos
;
96 ;; called when new literal compiled
97 : push
-literal
( addr
-- ) (advance
-buf
) dup
to buffer
-lit
-pos
(put
-addr
) ;
99 ;; push last compiled word address
to the ring buffer
.
100 ;; this will reset
"lit-pos" if necessary
.
101 : push
-last
-instr
( addr
-- ) (advance
-buf
) dup buffer
-lit
-pos
= if lit
-reset
endif (put
-addr
) ;
103 ;; rollback one instruction
104 : buffer
-rollback
-one
( -- ) buffer
-tail cell
- buffer
-pos
-mask and
to buffer
-tail
;
106 : buffer
-tail@
( -- ) buffer
-tail buffer
+ @
;
107 : buffer
-prev@
( -- ) buffer
-tail cell
- buffer
-pos
-mask and buffer
+ @
;
108 : buffer
-third@
( -- ) buffer
-tail
8- buffer
-pos
-mask and buffer
+ @
;
110 ;; set by checker
, for speed
111 0 value lit
-instr
-addr
114 0 value last
-instr
-addr
115 0 value last
-instr
-cfa
117 : prepare
-globals
( lit
-instr
-addr last
-instr
-addr
-- )
118 dup
to last
-instr
-addr @
to last
-instr
-cfa
119 dup
to lit
-instr
-addr cell
+ dup
to lit
-arg
-addr @
to lit
-value
122 ;; check
if we have a valid
"(LIT)" and instructions without arguments
.
123 ;; they must be two latest instructions at HERE
.
124 ;; explicit
"exit" used
for slight speedup
. sorry
.
125 : lit
-and
-instr?
( -- bool
)
126 buffer
-lit
-pos dup
-if drop false exit
endif
127 buffer
+ @ dup prev
-lit
-cw
= ifnot drop false exit
endif ( lit
-instr
-addr
)
128 buffer
-tail@ dup last
-cw
= ifnot
2drop false exit
endif ( lit
-instr
-addr last
-instr
-addr
)
132 : dp
! ( addr
-- ) forth
:(dp
-here
) @
! ;
134 ;; replace last
"(LIT)" value
, remove other instructions
.
135 : set
-lit
-value
-only
( value
-- )
137 buffer
-lit
-pos
to buffer
-tail
138 lit
-arg
-addr cell
+ dp
!
141 ;; replace last
"(LIT)" value
, replace last instruction
.
142 : set
-lit
-value
-instr
( value cfa
-- )
143 last
-instr
-addr compile
!
147 ;; replace last
"(LIT)" with lit
-arg instruction
.
148 ;; remove last instruction
.
149 : replace
-lit
-with
-arginstr
( cfa
-- )
150 lit
-instr
-addr compile
!
151 last
-instr
-addr dp
! lit
-reset buffer
-rollback
-one
154 ;; replace last
"(LIT)" with simple instruction without operands
.
155 : replace
-lit
( cfa
-- )
156 lit
-instr
-addr compile
!
157 buffer
-lit
-pos
to buffer
-tail lit
-reset
161 ;; remove last
"(LIT)", and everything after it
.
162 : remove
-lit
( cfa
-- )
164 buffer
-lit
-pos cell
- buffer
-pos
-mask and
to buffer
-tail lit
-reset
168 ;; check
if we have a valid
"(LIT)" and instruction with one argument
.
169 ;; they must be two latest instructions at HERE
.
170 ;; explicit
"exit" used
for slight speedup
. sorry
.
171 : lit
-and
-one
-arg?
( -- bool
)
172 buffer
-lit
-pos dup
-if drop false exit
endif
173 buffer
+ @ dup here
[ 4 cells
] imm
-literal
- = ifnot drop false exit
endif ( lit
-instr
-addr
)
174 buffer
-tail@ dup here
8- = ifnot
2drop false exit
endif ( lit
-instr
-addr last
-instr
-addr
)
178 ;; remove last
"(LIT)". set direct poke instead
.
179 ;; note that
"(LIT)" must be followed by direct poke
.
180 : remove
-lit
-set
-direct
( cfa
-- )
181 lit
-instr
-addr compile
!
182 last
-instr
-addr cell
+ @ lit
-arg
-addr
! ;; copy argument
183 last
-instr
-addr dp
! lit
-reset buffer
-rollback
-one
187 0 value prev
-instr
-addr
190 ;; check
if we have a valid
"(LIT)" and instruction with one argument
.
191 ;; they must be two latest instructions at HERE
.
192 ;; explicit
"exit" used
for slight speedup
. sorry
.
193 : true
/false
-and
-one
-arg?
( -- bool
)
194 buffer
-tail@ dup here
8- = ifnot drop false exit
endif ( last
-instr
-addr
)
195 buffer
-prev@ dup here
[ 3 cells
] imm
-literal
- = ifnot
2drop false exit
endif ( lia pia
)
197 ['] true of true to t/f-value endof
198 ['] false of false
to t
/f
-value endof
199 otherwise drop
2drop false exit endcase
201 dup
to last
-instr
-addr @
to last
-instr
-cfa true
204 ;; replace previous instruction with direct poke
.
205 ;; last instruction must be a direct poke
.
206 : replace
-prev
-with
-direct
( cfa
-- )
207 prev
-instr
-addr compile
!
208 last
-instr
-addr cell
+ @ prev
-instr
-addr cell
+ ! ;; copy argument
209 prev
-instr
-addr cell
+ dp
!
210 buffer
-reset
;; don
't bother
213 : remove-prev-and-direct ( -- )
215 buffer-reset ;; don't bother
219 0 value v
/c
-value
;; var
/const value
221 ;; check
if we have a variable
/constant as previous instruction
,
222 ;; folowed by simple instruction
.
223 ;; they must be two latest instructions at HERE
.
224 : prev
-var
/const
-and
-instr?
( -- bool
)
225 buffer
-tail@ dup here
4- = ifnot drop false exit
endif ( last
-instr
-addr
)
226 buffer
-prev@ dup here
8- = ifnot
2drop false exit
endif ( lia pia
)
227 dup @ dup compiler
:variable
-word?
if drop false
228 else compiler
:constant
-word?
if true
229 else 2drop false exit
endif endif
230 over
to prev
-instr
-addr
231 swap @ cfa
->pfa swap
if @
endif to v
/c
-value
232 dup
to last
-instr
-addr @
to last
-instr
-cfa true
235 ;; use v
/c
-value as address
236 : replace
-v
/c
-with
-direct
( cfa
-- )
237 prev
-instr
-addr compile
!
238 prev
-instr
-addr cell
+ v
/c
-value over
! cell
+ dp
!
243 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
247 : .curr
-word
( -- ) latest
-nfa id
-count xtype
;
248 : .last
-instr
( -- ) last
-instr
-cfa cfa
->nfa id
-count xtype
;
249 : .optim
( addr count
-- ) ." ***SINOPT(" here
0 u
.r
." ) at `" .curr
-word
." `:" type
." : " ;
253 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
254 ;; {lit
} <and|or|xor|~and
> --> (lit
-...)
257 : optimise
-direct
-bitwise
( -- done?
)
260 lit-value dup 0xff = if
261 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-BITWISE
262 " direct-bitwise" .optim ." LO-BYTE" cr
264 drop ['] forth
:lo
-byte replace
-lit true exit
267 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-BITWISE
268 " direct-bitwise" .optim
." LO-WORD" cr
270 ['] forth:lo-word replace-lit true exit
274 ['] forth:~and of ['] forth
:(lit
-~and
) endof
275 ['] forth:or of ['] forth
:(lit
-or
) endof
276 ['] forth:xor of ['] forth
:(lit
-xor
) endof
277 otherwise drop false exit endcase
278 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-BITWISE
279 " direct-bitwise" .optim lit
-value
0 .r cr
281 replace
-lit
-with
-arginstr true
285 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
290 -find
-required dup compiler
:constant
-word?
if cfa
->pfa @
endif ,
293 ;; special table values
294 -2 constant tbl
-remove
299 : process
-table
( tbl index repl
-cfa
-- did
-repl?
)
301 tbl
-remove of drop remove
-lit true exit endof
302 tbl
-keep of drop false exit endof
303 tbl
-lit
-0 of drop
0 set
-lit
-value
-only true exit endof
304 tbl
-lit
-1 of drop
1 set
-lit
-value
-only true exit endof
305 otherwise swap execute true exit endcase
308 : simple
-replace
-from
-table
( tbl index
-- did
-repl?
)
309 ['] replace-lit process-table
312 : direct-replace-from-table ( tbl index -- did-repl? )
313 ['] remove
-lit
-set
-direct process
-table
317 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
343 : optimise
-inc
-dec
( -- done?
)
344 lit
-value
-8 9 within ifnot false exit
endif
345 inc
-cfa
-tbl last
-instr
-cfa case
346 ['] forth:+ of lit-value endof
347 ['] forth
:- of lit
-value negate endof
348 otherwise
2drop false exit endcase
349 8+ simple
-replace
-from
-table
350 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-INC
-DEC
352 " inc-dec" .optim lit
-value
. cr
358 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
365 tw
: forth
:negate
;; -1
377 : optimise
-mul
( -- done?
)
378 lit
-value
-1 9 within ifnot false exit
endif
380 ['] * of lit-mul-tbl endof
381 ['] u* of lit
-mul
-tbl endof
382 otherwise drop false exit endcase
383 lit
-value
1+ simple
-replace
-from
-table
384 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-MULS
386 " mul" .optim lit
-value
0 .r cr
392 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
399 tw
: forth
:negate
;; -1
425 : optimise
-div
( -- done?
)
426 lit
-value
-1 9 within ifnot false exit
endif
428 ['] / of lit-div-tbl endof
429 ['] u
/ of lit
-udiv
-tbl endof
430 otherwise drop false exit endcase
431 lit
-value
1+ simple
-replace
-from
-table
432 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-MULS
434 " div" .optim lit
-value
0 .r cr
440 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
470 : optimise
-shifts
( -- done?
)
471 lit
-value
-3 4 within ifnot false exit
endif
472 lit
-value last
-instr
-cfa case
473 ['] forth:lsh of 3 + lit-lsh-tbl endof
474 ['] forth
:ash of
3 + lit
-ash
-tbl endof
475 ['] forth:lshift of dup -if drop false exit endif lit-lsh-tbl endof
476 ['] forth
:rshift of dup
-if drop false exit
endif negate lit
-lsh
-tbl endof
477 ['] forth:arshift of dup -if drop false exit endif negate lit-ash-tbl endof
478 otherwise 2drop false exit endcase
479 swap simple-replace-from-table
480 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-MULS
482 " shift" .optim lit-value 0 .r cr
488 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
492 : optimise-cells ( -- done? )
493 last-instr-cfa ['] cells
= ifnot false exit
endif
494 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-CELLS
495 " cells" .optim lit
-value
0 .r cr
497 lit
-value cells set
-lit
-value
-only true
501 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
506 : optimise
-cells
-inc
-dec
( -- done?
)
508 ['] +cells of ['] + endof
509 ['] -cells of ['] - endof
510 otherwise drop false exit endcase
511 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-CELLS
-INC
-DEC
512 " cells-inc-dec " .optim lit
-value
0 .r cr
514 lit
-value cells swap set
-lit
-value
-instr true
518 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
522 : optimise
-direct
-poke
( -- done?
)
523 last
-instr
-cfa
['] (direct:!) = ifnot false exit endif
525 -1 of ['] forth
:(direct
:-1:!) endof
526 0 of
['] forth:(direct:0:!) endof
527 1 of ['] forth
:(direct
:1:!) endof
528 otherwise drop false exit endcase
529 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
530 " direct-poke" .optim lit
-value
0 .r cr
532 remove
-lit
-set
-direct true
536 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
542 create direct-inc-tbl
543 tw
: (direct
:8-!) ;; -8
547 tw
: (direct
:4-!) ;; -4
549 tw
: (direct
:2-!) ;; -2
550 tw
: (direct
:1-!) ;; -1
552 tw
: (direct
:1+!) ;; +1
553 tw
: (direct
:2+!) ;; +2
555 tw
: (direct
:4+!) ;; +4
559 tw
: (direct
:8+!) ;; +8
562 : optimise
-direct
-poke
-inc
( -- done?
)
563 lit
-value
-8 9 within ifnot false exit
endif
565 ['] (direct:+!) of lit-value endof
566 ['] (direct
:-!) of lit
-value negate endof
567 otherwise drop false exit endcase
568 8+ direct
-inc
-tbl swap direct
-replace
-from
-table
569 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKE
-INCS
571 " direct-poke-inc" .optim lit
-value
0 .r cr
577 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
582 : optimise
-direct
-poke
-bool
( -- done?
)
583 prev
-instr
-addr @
['] (direct:!) = ifnot false exit endif
584 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-DIRECT-POKES
585 " direct-poke-bool" .optim lit-value 0 .r cr
588 -1 of ['] forth
:(direct
:-1:!) endof
589 0 of
['] forth:(direct:0:!) endof
590 1 of ['] forth
:(direct
:1:!) endof
591 otherwise
" wuta?!" error endcase
-- assertion
592 replace
-prev
-with
-direct true
596 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
597 ;; false
(direct
:+!) --> none
598 ;; false
(direct
:-!) --> none
599 ;; true
(direct
:+!) --> (direct
:1-!)
600 ;; true
(direct
:-!) --> (direct
:1+!)
603 : optimise
-direct
-poke
-inc
-bool
( -- done?
)
604 prev
-instr
-addr @ case
606 t/f-value ifnot remove-prev-and-direct true exit endif
610 t
/f
-value ifnot remove
-prev
-and
-direct true exit
endif
613 otherwise drop false exit endcase
614 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
615 " direct-poke-inc-bool" .optim dup
0 .r cr
618 -1 of
['] forth:(direct:1-!) endof
619 1 of ['] forth
:(direct
:1+!) endof
620 otherwise
" wuta?!" error endcase
-- assertion
621 replace
-prev
-with
-direct true
625 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
630 ;; with this optimisation
, vars are as fast as direct memory access
633 : optimise
-vars
( -- done?
)
635 ['] @ of ['] forth
:(direct
:@
) endof
636 ['] ! of ['] forth
:(direct
:!) endof
637 ['] +! of ['] forth
:(direct
:+!) endof
638 ['] -! of ['] forth
:(direct
:-!) endof
639 otherwise drop false exit endcase
640 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-VARS
642 ." var:`" prev
-instr
-addr @ cfa
->nfa id
-count xtype
643 ." `; op:" last
-instr
-cfa cfa
->nfa id
-count xtype
644 \
." addr: " v
/c
-value
0 u
.r
647 replace
-v
/c
-with
-direct true
651 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
657 : optimise
-stack
-ops
( -- done?
)
658 buffer
-tail@ dup last
-cw
= ifnot drop false exit
endif
659 buffer
-prev@ dup prev
-cw
= ifnot
2drop false exit
endif
660 @ swap @ case
;; prev tail
662 ['] swap
= ifnot false exit
endif
666 ['] rot = ifnot false exit endif
670 ['] swap
= ifnot false exit
endif
673 otherwise 2drop false exit endcase
674 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-STACK-OPS
676 dup cfa->nfa id-count xtype
679 buffer-prev@ swap over compile! cell+ dp!
680 buffer-reset true ;; don't bother restoring the buffer
for now
684 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
685 ;; swap
1+ swap
--> (swap
:1+:swap
)
688 : optimise
-swap
-1+-swap
( -- done?
)
690 buffer
-tail@ dup last
-cw
= ifnot drop false exit
endif
691 @
['] swap = ifnot false exit endif
693 buffer-prev@ dup prev-cw = ifnot drop false exit endif
694 @ ['] 1+ = ifnot false exit
endif
696 buffer
-third@ dup here
12 - = ifnot drop false exit
endif
697 @
['] swap = ifnot false exit endif
698 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-SWAP-INC-SWAP
699 " swap-1+-swap" .optim cr
701 buffer-third@ ['] forth
:(swap
:1+:swap
) over compile
! cell
+ dp
!
702 buffer
-reset true
;; don
't bother restoring the buffer for now
706 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
710 : instr-compiled ( addr -- )
712 lit-and-instr? if ;; we just compiled a literal
713 optimise-direct-bitwise if exit endif
714 optimise-cells-inc-dec drop -- keep optimising, inc/dec might do more
715 optimise-inc-dec if exit endif
716 optimise-mul if exit endif
717 optimise-div if exit endif
718 optimise-cells if exit endif
719 optimise-shifts if exit endif
721 prev-var/const-and-instr? if
722 optimise-vars drop \ if exit endif -- direct optimisers below will do more this way
726 optimise-direct-poke if exit endif
727 optimise-direct-poke-inc if exit endif
729 true/false-and-one-arg? if
730 optimise-direct-poke-bool if exit endif
731 optimise-direct-poke-inc-bool if exit endif
733 optimise-swap-1+-swap if exit endif
734 optimise-stack-ops if exit endif
739 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
747 ;; called by "compiler:(<j-mark)"
748 ;; erase literal address, so "lit begin and" will not be optimised to shit
749 ['] buffer
-reset
to compiler
:(jump
-here
-marked
)
750 ['] buffer-reset to compiler:(reset-sinopt)
751 ['] push
-literal
to compiler
:(after
-compile
-lit
)
752 ['] instr-compiled to compiler:(after-compile-word)
760 ;; called by "compiler:(<j-mark)"
761 ;; erase literal address, so "lit begin and" will not be optimised to shit
762 ['] forth
:noop
to compiler
:(jump
-here
-marked
)
763 ['] forth:noop to compiler:(reset-sinopt)
764 ['] forth
:drop
to compiler
:(after
-compile
-lit
)
765 ['] forth:drop to compiler:(after-compile-word)
771 : temp-disable ( -- )
773 ['] forth
:drop
to compiler
:(after
-compile
-lit
)
774 ['] forth:drop to compiler:(after-compile-word)
778 : temp-restore ( -- )
780 ['] push
-literal
to compiler
:(after
-compile
-lit
)
781 ['] instr-compiled to compiler:(after-compile-word)
788 : sinopt-enable ( -- ) forth:(sinopt-peephole):install ;
789 : sinopt-disable ( -- ) forth:(sinopt-peephole):uninstall ;
790 : sinopt-enabled? ( -- bool ) forth:(sinopt-peephole):enabled? ;
791 : sinopt-enabled! ( bool -- ) if forth:(sinopt-peephole):install else forth:(sinopt-peephole):uninstall endif ;
793 ;; optimising compiled UrAsm code slows everything down a lot
794 : sinopt-temp-restore ( -- ) forth:(sinopt-peephole):temp-restore ;
795 : sinopt-temp-disable ( -- ) forth:(sinopt-peephole):temp-disable ;