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
-DUMP
-PUSHES
31 \ $DEFINE DEBUG
-SINOPT
33 $DEFINE DEBUG
-SINOPT
-SIMPLE
-BITWISE
34 $DEFINE DEBUG
-SINOPT
-SIMPLE
-SWAP
-INC
-SWAP
35 $DEFINE DEBUG
-SINOPT
-SIMPLE
-INC
-DEC
36 $DEFINE DEBUG
-SINOPT
-SIMPLE
-CELLS
37 $DEFINE DEBUG
-SINOPT
-SIMPLE
-CELLS
-INC
-DEC
38 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
39 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
-INCS
40 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKE
-INCS
41 $DEFINE DEBUG
-SINOPT
-SIMPLE
-SHIFTS
42 $DEFINE DEBUG
-SINOPT
-SIMPLE
-MULS
43 $DEFINE DEBUG
-SINOPT
-SIMPLE
-DIVS
44 $DEFINE DEBUG
-SINOPT
-VARS
45 $DEFINE DEBUG
-SINOPT
-STACK
-OPS
51 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55 ;; last compiled word address
56 : prev
-cw
( -- addr
) postpone here postpone
8- ; immediate
57 : prev
-lit
-cw
( -- addr
) postpone here postpone
12 postpone
- ; immediate
58 \ debug
:decompile prev
-lit
-cw
60 : last
-cw
( -- addr
) postpone here postpone cell
- ; immediate
62 : 2cells
( n
-- n
-8 ) compiler
:?comp
[ 2 cells
] imm
-literal literal
; immediate
63 : 3cells
( n
-- n
-8 ) compiler
:?comp
[ 3 cells
] imm
-literal literal
; immediate
64 : 2:-cells
( n
-- n
-8 ) postpone
8- ; immediate
65 : 3:-cells
( n
-- n
-8 ) compiler
:?comp
[ 3 cells
] imm
-literal literal postpone
- ; immediate
68 : compile
! ( val addr
-- ) compiler
:?comp compile
! ; immediate
71 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
72 ;; ring buffer with instruction addresses
75 ;; ring buffer
for 8 instructions
.
76 ;; WARNING
! should be power of
2!
77 8 constant buffer
-size
78 buffer
-size cells
1- constant buffer
-pos
-mask
80 create buffer buffer-size cells allot create;
81 buffer buffer
-size cells erase
83 ;; positions are byte offsets
!
84 0 value buffer
-lit
-pos
;; position of the last compiled
(LIT
); -1 means
"not there"
85 0 value buffer
-tail
;; last used buffer entry
89 ;; put zeroes
to the last ring buffer element
.
90 ;; this way any check will definitely fail
.
91 buffer
-tail buffer
+ 0!
94 ;; rollback one instruction
95 : buffer
-rollback
-one
( -- ) buffer
-tail cell
- buffer
-pos
-mask and
to buffer
-tail
;
97 : buffer
+@
( ofs
-- ) buffer
+ @
;
99 : buffer
-tail@
( -- ) buffer
-tail buffer
+@
;
100 : buffer
-prev@
( -- ) buffer
-tail cell
- buffer
-pos
-mask and buffer
+@
;
101 : buffer
-third@
( -- ) buffer
-tail
8- buffer
-pos
-mask and buffer
+@
;
103 : (put
-addr
) ( addr newofs
-- ) buffer
+ ! ;
104 : (advance
-buf
) ( -- newofs
) buffer
-tail cell
+ buffer
-pos
-mask and dup
to buffer
-tail
;
105 : lit
-reset
( -- ) -1 to buffer
-lit
-pos
;
107 ;; called when new literal compiled
108 : push
-literal
( addr
-- )
109 (advance
-buf
) dup
to buffer
-lit
-pos
(put
-addr
)
110 $
IF $DEBUG
-SINOPT
-DUMP
-PUSHES
111 ." 3LIT(" buffer
-tail
0 u
.r
." ): " buffer
-tail@
0 u
.r space buffer
-prev@
0 u
.r space buffer
-third@
0 u
.r cr
115 ;; push last compiled word address
to the ring buffer
.
116 ;; this will reset
"lit-pos" if necessary
.
117 : push
-last
-instr
( addr
-- )
118 (advance
-buf
) dup buffer
-lit
-pos
= if lit
-reset
endif (put
-addr
)
119 $
IF $DEBUG
-SINOPT
-DUMP
-PUSHES
120 ." 3BUF(" buffer
-tail
0 u
.r
." ): " buffer
-tail@
0 u
.r space buffer
-prev@
0 u
.r space buffer
-third@
0 u
.r cr
124 ;; set by checker
, for speed
125 0 value lit
-instr
-addr
128 0 value last
-instr
-addr
129 0 value last
-instr
-cfa
131 : prepare
-globals
( lit
-instr
-addr last
-instr
-addr
-- )
132 dup
to last
-instr
-addr @
to last
-instr
-cfa
133 dup
to lit
-instr
-addr cell
+ dup
to lit
-arg
-addr @
to lit
-value
136 ;; check
if we have a valid
"(LIT)" and instructions without arguments
.
137 ;; they must be two latest instructions at HERE
.
138 ;; explicit
"exit" used
for slight speedup
. sorry
.
139 : lit
-and
-instr?
( -- bool
)
140 buffer
-lit
-pos dup
-if drop false exit
endif
141 buffer
+@ dup prev
-lit
-cw
= ifnot drop false exit
endif ( lit
-instr
-addr
)
142 buffer
-tail@ dup last
-cw
= ifnot
2drop false exit
endif ( lit
-instr
-addr last
-instr
-addr
)
146 : dp
! ( addr
-- ) forth
:(dp
-here
) @
! ;
148 ;; replace last
"(LIT)" value
, remove other instructions
.
149 : set
-lit
-value
-only
( value
-- )
151 buffer
-lit
-pos
to buffer
-tail
152 lit
-arg
-addr cell
+ dp
!
155 ;; replace last
"(LIT)" value
, replace last instruction
.
156 : set
-lit
-value
-instr
( value cfa
-- )
157 ;; fix those
, because the only place where this is used is
"+cells" optimisation
,
158 ;; and that optimisation rely on further optimisers
.
160 dup
to last
-instr
-cfa
161 last
-instr
-addr compile
!
165 ;; replace last
"(LIT)" with lit
-arg instruction
.
166 ;; remove last instruction
.
167 : replace
-lit
-with
-arginstr
( cfa
-- )
168 lit
-instr
-addr compile
!
169 last
-instr
-addr dp
! lit
-reset buffer
-rollback
-one
172 ;; replace last
"(LIT)" with simple instruction without operands
.
173 : replace
-lit
( cfa
-- )
176 buffer
-tail@
0 u
.r space buffer
-prev@
0 u
.r space buffer
-third@
0 u
.r
177 4 spaces buffer
-lit
-pos
0 u
.r space buffer
-tail
0 u
.r
180 lit
-instr
-addr compile
!
181 buffer
-lit
-pos
to buffer
-tail lit
-reset
185 ;; remove last
"(LIT)", and everything after it
.
186 : remove
-lit
( cfa
-- )
188 buffer
-lit
-pos cell
- buffer
-pos
-mask and
to buffer
-tail lit
-reset
192 ;; check
if we have a valid
"(LIT)" and instruction with one argument
.
193 ;; they must be two latest instructions at HERE
.
194 ;; explicit
"exit" used
for slight speedup
. sorry
.
195 : lit
-and
-one
-arg?
( -- bool
)
196 buffer
-lit
-pos dup
-if drop false exit
endif
197 buffer
+@ dup here
[ 4 cells
] imm
-literal
- = ifnot drop false exit
endif ( lit
-instr
-addr
)
198 buffer
-tail@ dup here
8- = ifnot
2drop false exit
endif ( lit
-instr
-addr last
-instr
-addr
)
202 ;; remove last
"(LIT)". set direct poke instead
.
203 ;; note that
"(LIT)" must be followed by direct poke
.
204 : remove
-lit
-set
-direct
( cfa
-- )
205 lit
-instr
-addr compile
!
206 last
-instr
-addr cell
+ @ lit
-arg
-addr
! ;; copy argument
207 last
-instr
-addr dp
! lit
-reset buffer
-rollback
-one
211 0 value prev
-instr
-addr
214 ;; check
if we have a valid
"(LIT)" and instruction with one argument
.
215 ;; they must be two latest instructions at HERE
.
216 ;; explicit
"exit" used
for slight speedup
. sorry
.
217 : true
/false
-and
-one
-arg?
( -- bool
)
218 buffer
-tail@ dup here
8- = ifnot drop false exit
endif ( last
-instr
-addr
)
219 buffer
-prev@ dup here
[ 3 cells
] imm
-literal
- = ifnot
2drop false exit
endif ( lia pia
)
221 ['] true of true to t/f-value endof
222 ['] false of false
to t
/f
-value endof
223 otherwise drop
2drop false exit endcase
225 dup
to last
-instr
-addr @
to last
-instr
-cfa true
228 ;; replace previous instruction with direct poke
.
229 ;; last instruction must be a direct poke
.
230 : replace
-prev
-with
-direct
( cfa
-- )
231 prev
-instr
-addr compile
!
233 last
-instr
-addr cell
+ @ prev
-instr
-addr cell
+ dup cell
+ dp
! !
234 \ buffer
-reset
;; don
't bother
238 : remove-prev-and-direct ( -- )
240 buffer-reset ;; don't bother
244 0 value v
/c
-value
;; var
/const value
246 ;; check
if we have a variable
/constant as previous instruction
,
247 ;; folowed by simple instruction
.
248 ;; they must be two latest instructions at HERE
.
249 : prev
-var
/const
-and
-instr?
( -- bool
)
250 buffer
-tail@ dup here
4- = ifnot drop false exit
endif ( last
-instr
-addr
)
251 buffer
-prev@ dup here
8- = ifnot
2drop false exit
endif ( lia pia
)
252 dup @ dup compiler
:variable
-word?
if drop false
253 else compiler
:constant
-word?
if true
254 else 2drop false exit
endif endif
255 over
to prev
-instr
-addr
256 swap @ cfa
->pfa swap
if @
endif to v
/c
-value
257 dup
to last
-instr
-addr @
to last
-instr
-cfa true
260 ;; use v
/c
-value as address
261 : replace
-v
/c
-with
-direct
( cfa
-- )
262 prev
-instr
-addr compile
!
263 prev
-instr
-addr cell
+ v
/c
-value over
! cell
+ dp
!
268 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
272 : .curr
-word
( -- ) latest
-nfa id
-count xtype
;
273 : .last
-instr
( -- ) last
-instr
-cfa cfa
->nfa id
-count xtype
;
274 : .optim
( addr count
-- ) ." ***SINOPT(" here
0 u
.r
." ) at `" .curr
-word
." `:" type
." : " ;
278 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
279 ;; {lit
} <and|or|xor|~and
> --> (lit
-...)
282 : optimise
-direct
-bitwise
( -- done?
)
285 lit-value dup 0xff = if
286 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-BITWISE
287 " direct-bitwise" .optim ." LO-BYTE" cr
289 drop ['] forth
:lo
-byte replace
-lit true exit
292 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-BITWISE
293 " direct-bitwise" .optim
." LO-WORD" cr
295 ['] forth:lo-word replace-lit true exit
299 ['] forth:~and of ['] forth
:(lit
-~and
) endof
300 ['] forth:or of ['] forth
:(lit
-or
) endof
301 ['] forth:xor of ['] forth
:(lit
-xor
) endof
302 otherwise drop false exit endcase
303 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-BITWISE
304 " direct-bitwise" .optim lit
-value
0 .r cr
306 replace
-lit
-with
-arginstr true
310 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
315 -find
-required dup compiler
:constant
-word?
if cfa
->pfa @
endif ,
318 ;; special table values
319 -2 constant tbl
-remove
324 : process
-table
( tbl index repl
-cfa
-- did
-repl?
)
326 tbl
-remove of drop remove
-lit true exit endof
327 tbl
-keep of drop false exit endof
328 tbl
-lit
-0 of drop
0 set
-lit
-value
-only true exit endof
329 tbl
-lit
-1 of drop
1 set
-lit
-value
-only true exit endof
330 otherwise swap execute true exit endcase
333 : simple
-replace
-from
-table
( tbl index
-- did
-repl?
)
334 ['] replace-lit process-table
337 : direct-replace-from-table ( tbl index -- did-repl? )
338 ['] remove
-lit
-set
-direct process
-table
342 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
368 : optimise
-inc
-dec
( -- done?
)
369 lit
-value
-8 9 within ifnot false exit
endif
370 inc
-cfa
-tbl last
-instr
-cfa case
371 ['] forth:+ of lit-value endof
372 ['] forth
:- of lit
-value negate endof
373 otherwise
2drop false exit endcase
374 8+ simple
-replace
-from
-table
375 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-INC
-DEC
377 " inc-dec" .optim lit
-value
. cr
383 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
390 tw
: forth
:negate
;; -1
402 : optimise
-mul
( -- done?
)
403 lit
-value
-1 9 within ifnot false exit
endif
405 ['] * of lit-mul-tbl endof
406 ['] u* of lit
-mul
-tbl endof
407 otherwise drop false exit endcase
408 lit
-value
1+ simple
-replace
-from
-table
409 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-MULS
411 " mul" .optim lit
-value
0 .r cr
417 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
424 tw
: forth
:negate
;; -1
450 : optimise
-div
( -- done?
)
451 lit
-value
-1 9 within ifnot false exit
endif
453 ['] / of lit-div-tbl endof
454 ['] u
/ of lit
-udiv
-tbl endof
455 otherwise drop false exit endcase
456 lit
-value
1+ simple
-replace
-from
-table
457 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-MULS
459 " div" .optim lit
-value
0 .r cr
465 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
495 : optimise
-shifts
( -- done?
)
496 lit
-value
-3 4 within ifnot false exit
endif
497 lit
-value last
-instr
-cfa case
498 ['] forth:lsh of 3 + lit-lsh-tbl endof
499 ['] forth
:ash of
3 + lit
-ash
-tbl endof
500 ['] forth:lshift of dup -if drop false exit endif 3 + lit-lsh-tbl endof
501 ['] forth
:rshift of dup
-if drop false exit
endif negate
3 + lit
-lsh
-tbl endof
502 ['] forth:arshift of dup -if drop false exit endif negate 3 + lit-ash-tbl endof
503 otherwise 2drop false exit endcase
504 swap simple-replace-from-table
505 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-MULS
507 " shift" .optim lit-value 0 .r cr
513 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
517 : optimise-cells ( -- done? )
518 last-instr-cfa ['] cells
= ifnot false exit
endif
519 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-CELLS
520 " cells" .optim lit
-value
0 .r cr
522 lit
-value cells set
-lit
-value
-only true
526 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
531 : optimise
-cells
-inc
-dec
( -- done?
)
533 ['] +cells of ['] + endof
534 ['] -cells of ['] - endof
535 otherwise drop false exit endcase
536 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-CELLS
-INC
-DEC
537 " cells-inc-dec " .optim lit
-value
0 .r cr
539 lit
-value cells swap set
-lit
-value
-instr true
543 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
547 : optimise
-direct
-poke
( -- done?
)
548 last
-instr
-cfa
['] (direct:!) = ifnot false exit endif
550 -1 of ['] forth
:(direct
:-1:!) endof
551 0 of
['] forth:(direct:0:!) endof
552 1 of ['] forth
:(direct
:1:!) endof
553 otherwise drop false exit endcase
554 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
555 " direct-poke" .optim lit
-value
0 .r cr
557 remove
-lit
-set
-direct true
561 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
567 create direct-inc-tbl
568 tw
: (direct
:8-!) ;; -8
572 tw
: (direct
:4-!) ;; -4
574 tw
: (direct
:2-!) ;; -2
575 tw
: (direct
:1-!) ;; -1
577 tw
: (direct
:1+!) ;; +1
578 tw
: (direct
:2+!) ;; +2
580 tw
: (direct
:4+!) ;; +4
584 tw
: (direct
:8+!) ;; +8
587 : optimise
-direct
-poke
-inc
( -- done?
)
588 lit
-value
-8 9 within ifnot false exit
endif
590 ['] (direct:+!) of lit-value endof
591 ['] (direct
:-!) of lit
-value negate endof
592 otherwise drop false exit endcase
593 8+ direct
-inc
-tbl swap direct
-replace
-from
-table
594 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKE
-INCS
596 " direct-poke-inc" .optim lit
-value
0 .r cr
602 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
607 : optimise
-direct
-poke
-bool
( -- done?
)
608 last
-instr
-cfa
['] (direct:!) = ifnot false exit endif
609 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-DIRECT-POKES
610 " direct-poke-bool" .optim lit-value 0 .r cr
613 -1 of ['] forth
:(direct
:-1:!) endof
614 0 of
['] forth:(direct:0:!) endof
615 1 of ['] forth
:(direct
:1:!) endof
616 otherwise
" wuta?!" error endcase
-- assertion
617 replace
-prev
-with
-direct true
621 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
622 ;; false
(direct
:+!) --> none
623 ;; false
(direct
:-!) --> none
624 ;; true
(direct
:+!) --> (direct
:1-!)
625 ;; true
(direct
:-!) --> (direct
:1+!)
628 : optimise
-direct
-poke
-inc
-bool
( -- done?
)
631 t/f-value ifnot remove-prev-and-direct true exit endif
635 t
/f
-value ifnot remove
-prev
-and
-direct true exit
endif
638 otherwise drop false exit endcase
639 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-SIMPLE
-DIRECT
-POKES
640 " direct-poke-inc-bool" .optim dup
0 .r cr
643 -1 of
['] forth:(direct:1-!) endof
644 1 of ['] forth
:(direct
:1+!) endof
645 otherwise
" wuta?!" error endcase
-- assertion
646 replace
-prev
-with
-direct true
650 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
655 ;; with this optimisation
, vars are as fast as direct memory access
658 : optimise
-vars
( -- done?
)
660 ['] @ of ['] forth
:(direct
:@
) endof
661 ['] ! of ['] forth
:(direct
:!) endof
662 ['] +! of ['] forth
:(direct
:+!) endof
663 ['] -! of ['] forth
:(direct
:-!) endof
664 otherwise drop false exit endcase
665 $
IF $DEBUG
-SINOPT AND $DEBUG
-SINOPT
-VARS
667 ." var:`" prev
-instr
-addr @ cfa
->nfa id
-count xtype
668 ." `; op:" last
-instr
-cfa cfa
->nfa id
-count xtype
669 \
." addr: " v
/c
-value
0 u
.r
672 replace
-v
/c
-with
-direct true
676 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
682 : optimise
-stack
-ops
( -- done?
)
683 buffer
-tail@ dup last
-cw
= ifnot drop false exit
endif
684 buffer
-prev@ dup prev
-cw
= ifnot
2drop false exit
endif
685 @ swap @ case
;; prev tail
687 ['] swap
= ifnot false exit
endif
691 ['] rot = ifnot false exit endif
695 ['] swap
= ifnot false exit
endif
698 otherwise 2drop false exit endcase
699 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-STACK-OPS
701 dup cfa->nfa id-count xtype
704 buffer-prev@ swap over compile! cell+ dp!
705 buffer-reset true ;; don't bother restoring the buffer
for now
709 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
710 ;; swap
1+ swap
--> (swap
:1+:swap
)
713 : optimise
-swap
-1+-swap
( -- done?
)
715 buffer
-tail@ dup last
-cw
= ifnot drop false exit
endif
716 @
['] swap = ifnot false exit endif
718 buffer-prev@ dup prev-cw = ifnot drop false exit endif
719 @ ['] 1+ = ifnot false exit
endif
721 buffer
-third@ dup here
12 - = ifnot drop false exit
endif
722 @
['] swap = ifnot false exit endif
723 $IF $DEBUG-SINOPT AND $DEBUG-SINOPT-SIMPLE-SWAP-INC-SWAP
724 " swap-1+-swap" .optim cr
726 buffer-third@ ['] forth
:(swap
:1+:swap
) over compile
! cell
+ dp
!
727 buffer
-reset true
;; don
't bother restoring the buffer for now
731 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
735 : instr-compiled ( addr -- )
737 lit-and-instr? if ;; we just compiled a literal
738 optimise-direct-bitwise
739 dup ifnot drop optimise-cells endif
740 dup ifnot drop optimise-cells-inc-dec drop false endif -- keep optimising, inc/dec might do more
741 dup ifnot drop optimise-inc-dec endif
742 dup ifnot drop optimise-mul endif
743 dup ifnot drop optimise-div endif
744 dup ifnot drop optimise-shifts endif
747 prev-var/const-and-instr? if
748 optimise-vars drop \ if exit endif -- direct optimisers below will do more this way
752 optimise-direct-poke if exit endif
753 optimise-direct-poke-inc if exit endif
755 true/false-and-one-arg? if
756 optimise-direct-poke-bool if exit endif
757 optimise-direct-poke-inc-bool if exit endif
759 optimise-swap-1+-swap if exit endif
760 optimise-stack-ops if exit endif
765 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
773 ;; called by "compiler:(<j-mark)"
774 ;; erase literal address, so "lit begin and" will not be optimised to shit
775 ['] buffer
-reset
to compiler
:(jump
-here
-marked
)
776 ['] buffer-reset to compiler:(reset-sinopt)
777 ['] push
-literal
to compiler
:(after
-compile
-lit
)
778 ['] instr-compiled to compiler:(after-compile-word)
786 ;; called by "compiler:(<j-mark)"
787 ;; erase literal address, so "lit begin and" will not be optimised to shit
788 ['] forth
:noop
to compiler
:(jump
-here
-marked
)
789 ['] forth:noop to compiler:(reset-sinopt)
790 ['] forth
:drop
to compiler
:(after
-compile
-lit
)
791 ['] forth:drop to compiler:(after-compile-word)
797 : temp-disable ( -- )
799 ['] forth
:drop
to compiler
:(after
-compile
-lit
)
800 ['] forth:drop to compiler:(after-compile-word)
804 : temp-restore ( -- )
806 ['] push
-literal
to compiler
:(after
-compile
-lit
)
807 ['] instr-compiled to compiler:(after-compile-word)
814 : sinopt-enable ( -- ) forth:(sinopt-peephole):install ;
815 : sinopt-disable ( -- ) forth:(sinopt-peephole):uninstall ;
816 : sinopt-enabled? ( -- bool ) forth:(sinopt-peephole):enabled? ;
817 : sinopt-enabled! ( bool -- ) if forth:(sinopt-peephole):install else forth:(sinopt-peephole):uninstall endif ;
819 ;; optimising compiled UrAsm code slows everything down a lot
820 : sinopt-temp-restore ( -- ) forth:(sinopt-peephole):temp-restore ;
821 : sinopt-temp-disable ( -- ) forth:(sinopt-peephole):temp-disable ;