20周遅れのコンパイラ開発
そのうち HLS 対応
りょうす
2016/4/9
Agenda
• 今取り組んでいること
– CPSを使ったコンパイラ
• 今後勉強すること
– A正規形とK正規形
– OCaml と型推論
今取り組んでいること
• CPS を使ったコンパイラ
– 開発言語: Common Lisp
– ターゲットの言語: Mini Scheme
– 生成されるもの: VM のコード(HLS ではない!!)
CPS(Continuation Passing Style)
- 1992 年の本
- ML を使用している
参考資料
- 199X 年(半ば?)の東大
で行われていた実習
- Scheme
mini-scheme(例)
• 再帰を使った階乗の例
(:fix ((fact (n)
(:if (:= n 0)
1
(:* n (fact (:- n 1))))))
(fact 10))
mini-scheme → CPS
• 再帰を使った階乗の例
(:fix ((fact (n)
(:if (:= n 0)
1
(:* n (fact (:- n 1))))))
(fact 10))
(:FIXH
((FACT (|sym1| N)
(:FIXS ((|sym2| (|sym3|) (:APP |sym1| (|sym3|))))
(:= (N 0) NIL
((:APP |sym2| (1))
(:- (N 1) (|sym7|)
((:FIXS
((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym2|
(|sym4|))))))
(:APP FACT (|sym5| |sym7|))))))))))
(:FIXS ((|sym8| (|sym9|) (:APP EXIT (|sym9|)))) (:APP FACT
(|sym8| 10))))
CPS → CPS(η-Reduction)
• 再帰を使った階乗の例
(:FIXH
((FACT (|sym1| N)
(:FIXS ((|sym2| (|sym3|) (:APP |sym1| (|sym3|))))
(:= (N 0) NIL
((:APP |sym2| (1))
(:- (N 1) (|sym7|)
((:FIXS
((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym2|
(|sym4|))))))
(:APP FACT (|sym5| |sym7|))))))))))
(:FIXS ((|sym8| (|sym9|) (:APP EXIT (|sym9|)))) (:APP FACT
(|sym8| 10))))
(:FIXH
((FACT (|sym1| N)
(:= (N 0) NIL
((:APP |sym1| (1))
(:- (N 1) (|sym7|)
((:FIXS
((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym1|
(|sym4|))))))
(:APP FACT (|sym5| |sym7|)))))))))
(:APP FACT (EXIT 10)))
CPS→ VM
• 再帰を使った階乗の例
(:FIXH
((FACT (|sym1| N)
(:= (N 0) NIL
((:APP |sym1| (1))
(:- (N 1) (|sym7|)
((:FIXS
((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym1|
(|sym4|))))))
(:APP FACT (|sym5| |sym7|)))))))))
(:APP FACT (EXIT 10)))
((:JUMP (:LABEL |:MAIN|)) MAIN (:CONST (:LABEL |:MAIN|)) EXIT
(:CONST (:LABEL |:EXIT|)) |:EXIT| (:HALT :R1) |:MAIN|
(:JUMP (:LABEL |:label0|)) (:LIVE-REG 0 (1 1 1 0 0 0 0 0 0 0)) |:FACT|
(:= :R2 0) (:CONDITIONAL-JUMP (:LABEL |:label1|)) (:- :R2 1 :R9)
(:JUMP (:LABEL |:label2|)) (:LIVE-REG 0 (1 1 0 0 0 0 0 0 0 0)) |:sym5|
(:RECORD-REF :R0 2 :R9) (:RECORD-REF :R0 1 :R8) (:POP 3) (:* :R8 :R1 :R1)
(:RECORD-REF :R9 0 :R8) (:MOVE :R9 :R0) (:JUMP :R8) |:label2|
(:STACK (:HEAP-LIST (:LABEL |:sym5|) :R2 :R1) :R1) (:RECORD-REF :R0 0 :R8)
(:MOVE :R9 :R2) (:JUMP :R8) |:label1| (:RECORD-REF :R1 0 :R9)
(:MOVE :R1 :R0)
(:MOVEI 1 :R1) (:JUMP :R9) |:label0|
(:HEAP (:HEAP-LIST (:LABEL |:FACT|)) :R9) (:RECORD-REF :R9 0 :R8)
(:MOVE :R9 :R0) (:MOVEI (:ADDRESS EXIT) :R1) (:MOVEI 10 :R2) (:JUMP :R8))
VM も作った
• vmgen(gforth) でつくった VM (抜粋)
 stack definitions:
E stack data-stack sp Cell
E s" Operand" single inst-stream type-prefix operand
E s" Imm" single inst-stream type-prefix imm
E s" Cell" single data-stack type-prefix s
 ----------------------------------------------------------------
add ( operand -- )
regs[operand.r2] = regs[operand.r0] + regs[operand.r1];
addi8 ( operand -- )
regs[operand.r2] = regs[operand.r0] + operand.r1;
addi32 ( operand imm32 -- )
regs[operand.r2] = regs[operand.r0] + imm32;
 ----------------------------------------------------------------
sub ( operand -- )
regs[operand.r2] = regs[operand.r0] - regs[operand.r1];
subi8 ( operand -- )
regs[operand.r2] = regs[operand.r0] - operand.r1;
Zynq 上で動く
T-Kernel VM の結果
(この例はフィボナッチ) VM
OpenAMP か
TrustZone(SafeG) を
使用
今と後
Scheme CPS VM
今
Scheme CPS VM
後
IROHA
今後勉強すること
• A正規形とK正規形
• OCaml と型推論
おしまい

20周遅れ

  • 1.
  • 2.
    Agenda • 今取り組んでいること – CPSを使ったコンパイラ •今後勉強すること – A正規形とK正規形 – OCaml と型推論
  • 3.
    今取り組んでいること • CPS を使ったコンパイラ –開発言語: Common Lisp – ターゲットの言語: Mini Scheme – 生成されるもの: VM のコード(HLS ではない!!)
  • 4.
    CPS(Continuation Passing Style) -1992 年の本 - ML を使用している
  • 5.
  • 6.
    mini-scheme(例) • 再帰を使った階乗の例 (:fix ((fact(n) (:if (:= n 0) 1 (:* n (fact (:- n 1)))))) (fact 10))
  • 7.
    mini-scheme → CPS •再帰を使った階乗の例 (:fix ((fact (n) (:if (:= n 0) 1 (:* n (fact (:- n 1)))))) (fact 10)) (:FIXH ((FACT (|sym1| N) (:FIXS ((|sym2| (|sym3|) (:APP |sym1| (|sym3|)))) (:= (N 0) NIL ((:APP |sym2| (1)) (:- (N 1) (|sym7|) ((:FIXS ((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym2| (|sym4|)))))) (:APP FACT (|sym5| |sym7|)))))))))) (:FIXS ((|sym8| (|sym9|) (:APP EXIT (|sym9|)))) (:APP FACT (|sym8| 10))))
  • 8.
    CPS → CPS(η-Reduction) •再帰を使った階乗の例 (:FIXH ((FACT (|sym1| N) (:FIXS ((|sym2| (|sym3|) (:APP |sym1| (|sym3|)))) (:= (N 0) NIL ((:APP |sym2| (1)) (:- (N 1) (|sym7|) ((:FIXS ((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym2| (|sym4|)))))) (:APP FACT (|sym5| |sym7|)))))))))) (:FIXS ((|sym8| (|sym9|) (:APP EXIT (|sym9|)))) (:APP FACT (|sym8| 10)))) (:FIXH ((FACT (|sym1| N) (:= (N 0) NIL ((:APP |sym1| (1)) (:- (N 1) (|sym7|) ((:FIXS ((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym1| (|sym4|)))))) (:APP FACT (|sym5| |sym7|))))))))) (:APP FACT (EXIT 10)))
  • 9.
    CPS→ VM • 再帰を使った階乗の例 (:FIXH ((FACT(|sym1| N) (:= (N 0) NIL ((:APP |sym1| (1)) (:- (N 1) (|sym7|) ((:FIXS ((|sym5| (|sym6|) (:* (N |sym6|) (|sym4|) ((:APP |sym1| (|sym4|)))))) (:APP FACT (|sym5| |sym7|))))))))) (:APP FACT (EXIT 10))) ((:JUMP (:LABEL |:MAIN|)) MAIN (:CONST (:LABEL |:MAIN|)) EXIT (:CONST (:LABEL |:EXIT|)) |:EXIT| (:HALT :R1) |:MAIN| (:JUMP (:LABEL |:label0|)) (:LIVE-REG 0 (1 1 1 0 0 0 0 0 0 0)) |:FACT| (:= :R2 0) (:CONDITIONAL-JUMP (:LABEL |:label1|)) (:- :R2 1 :R9) (:JUMP (:LABEL |:label2|)) (:LIVE-REG 0 (1 1 0 0 0 0 0 0 0 0)) |:sym5| (:RECORD-REF :R0 2 :R9) (:RECORD-REF :R0 1 :R8) (:POP 3) (:* :R8 :R1 :R1) (:RECORD-REF :R9 0 :R8) (:MOVE :R9 :R0) (:JUMP :R8) |:label2| (:STACK (:HEAP-LIST (:LABEL |:sym5|) :R2 :R1) :R1) (:RECORD-REF :R0 0 :R8) (:MOVE :R9 :R2) (:JUMP :R8) |:label1| (:RECORD-REF :R1 0 :R9) (:MOVE :R1 :R0) (:MOVEI 1 :R1) (:JUMP :R9) |:label0| (:HEAP (:HEAP-LIST (:LABEL |:FACT|)) :R9) (:RECORD-REF :R9 0 :R8) (:MOVE :R9 :R0) (:MOVEI (:ADDRESS EXIT) :R1) (:MOVEI 10 :R2) (:JUMP :R8))
  • 10.
    VM も作った • vmgen(gforth)でつくった VM (抜粋) stack definitions: E stack data-stack sp Cell E s" Operand" single inst-stream type-prefix operand E s" Imm" single inst-stream type-prefix imm E s" Cell" single data-stack type-prefix s ---------------------------------------------------------------- add ( operand -- ) regs[operand.r2] = regs[operand.r0] + regs[operand.r1]; addi8 ( operand -- ) regs[operand.r2] = regs[operand.r0] + operand.r1; addi32 ( operand imm32 -- ) regs[operand.r2] = regs[operand.r0] + imm32; ---------------------------------------------------------------- sub ( operand -- ) regs[operand.r2] = regs[operand.r0] - regs[operand.r1]; subi8 ( operand -- ) regs[operand.r2] = regs[operand.r0] - operand.r1;
  • 11.
    Zynq 上で動く T-Kernel VMの結果 (この例はフィボナッチ) VM OpenAMP か TrustZone(SafeG) を 使用
  • 12.
  • 13.
  • 14.