gsoc: Conditional constant propogation

Charles Zhang <[email protected]> Sat, 16 Jun 2018 00:26:36 -0400
Newsgroups gmane.lisp.clisp.devel
Message-ID <CAB=SSS=rowxGdD3Rv9Mt8=qKg8TTppoLfMN7_uXem7cA0cKefw@mail.gmail.com>
Hello,

I wrote a conditional constant propagation flow analysis pass. Now
cleavir can generate code for situations like:

CLEAVIR-CLISP> (cleavir-compile '(lambda ()
                   (let ((x nil))
                     (values
                      (case 2
                        (1 (setq x 'a) 'w)
                        (2 (setq x 'b) 'y)
                        (t (setq x 'c) 'z))
                      x))))
#<COMPILED-FUNCTION NIL>
CLEAVIR-CLISP> (disassemble *)

Disassembly of function NIL
(CONST 0) = Y
(CONST 1) = B
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0     (CONST&PUSH 0)                      ; Y
1     (CONST&PUSH 1)                      ; B
2     (CALLSR 2 29)                       ; VALUES
5     (SKIP&RET 1)
NIL

vs

CLEAVIR-CLISP> (compile nil '(lambda () (declare (optimize speed))
                   (let ((x nil))
                     (values
                      (case 2
                        (1 (setq x 'a) 'w)
                        (2 (setq x 'b) 'y)
                        (t (setq x 'c) 'z))
                      x))))
#<COMPILED-FUNCTION NIL>
NIL
NIL
CLEAVIR-CLISP> (disassemble *)

Disassembly of function NIL
(CONST 0) = 2
(CONST 1) = 1
(CONST 2) = A
(CONST 3) = W
(CONST 4) = B
(CONST 5) = Y
(CONST 6) = C
(CONST 7) = Z
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
23 byte-code instructions:
0     (NIL&PUSH)
1     (CONST&PUSH 0)                      ; 2
2     (JMPIFEQTO 1 L18)                   ; 1
5     (CONST&PUSH 0)                      ; 2
6     (JMPIFEQTO 0 L23)                   ; 2
9     (CONST 6)                           ; C
10    (STORE 0)
11    (CONST 7)                           ; Z
12    L12
12    (PUSH)
13    (LOAD&PUSH 1)
14    (STACK-TO-MV 2)
16    (SKIP&RET 2)
18    L18
18    (CONST 2)                           ; A
19    (STORE 0)
20    (CONST 3)                           ; W
21    (JMP L12)
23    L23
23    (CONST 4)                           ; B
24    (STORE 0)
25    (CONST 5)                           ; Y
26    (JMP L12)

and

CLEAVIR-CLISP> (cleavir-compile '(lambda () (let ((i 0) a b c d)
                          (values
                           (and (setq a (setq i (1+ i)))
                                (setq b (setq i (1+ i)))
                                (setq c (setq i (1+ i)))
                                (setq d (setq i (1+ i))))
                           i a b c d))))
#<COMPILED-FUNCTION NIL>
CLEAVIR-CLISP> (disassemble *)

Disassembly of function NIL
(CONST 0) = 4
(CONST 1) = 4
(CONST 2) = 1
(CONST 3) = 2
(CONST 4) = 3
(CONST 5) = 4
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
8 byte-code instructions:
0     (CONST&PUSH 0)                      ; 4
1     (CONST&PUSH 1)                      ; 4
2     (CONST&PUSH 2)                      ; 1
3     (CONST&PUSH 3)                      ; 2
4     (CONST&PUSH 4)                      ; 3
5     (CONST&PUSH 5)                      ; 4
6     (CALLSR 6 29)                       ; VALUES
9     (SKIP&RET 1)

vs
CLEAVIR-CLISP> (compile nil '(lambda () (declare (optimize speed))
(let ((i 0) a b c d)
                          (values
                           (and (setq a (setq i (1+ i)))
                                (setq b (setq i (1+ i)))
                                (setq c (setq i (1+ i)))
                                (setq d (setq i (1+ i))))
                           i a b c d))))
#<COMPILED-FUNCTION NIL>
NIL
NIL
CLEAVIR-CLISP> (disassemble *)

Disassembly of function NIL
(CONST 0) = 0
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
25 byte-code instructions:
0     (CONST&PUSH 0)                      ; 0
1     (PUSH-NIL 4)
3     (LOAD&INC&STORE 4)
5     (STORE 3)
6     (JMPIFNOT L27)
8     (PUSH)
9     (CALLS2&STORE 177 4)                ; 1+
12    (STORE 2)
13    (JMPIFNOT L27)
15    (PUSH)
16    (CALLS2&STORE 177 4)                ; 1+
19    (STORE 1)
20    (JMPIFNOT L27)
22    (PUSH)
23    (CALLS2&STORE 177 4)                ; 1+
26    (STORE 0)
27    L27
27    (PUSH)
28    (LOAD&PUSH 5)
29    (LOAD&PUSH 5)
30    (LOAD&PUSH 5)
31    (LOAD&PUSH 5)
32    (LOAD&PUSH 5)
33    (STACK-TO-MV 6)
35    (SKIP&RET 6)

This type of optimization is particularly helpful for macro heavy
functions, which might have lots of easily compile time computed
information.

Charles

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
clisp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-devel