SlideShare a Scribd company logo
.
    GHC へのプログラム変換パスの
.
            追加

          日比野 啓


          2012-09-29



                       .   .   .   .   .   .
今日の話




       .   .   .   .   .   .
今日の話




       .   .   .   .   .   .
Haskell から Core へ


  module Foo ( f ) where

  f :: Int -> Int -> Int
  f x y = x * (x + y)


  Haskell を Core 形式へ変換し、出力するコマンド
  % ghc -c -ddump-simpl Foo.hs



                           .   .   .   .   .   .
Haskell から Core へ
  Foo . f :: GHC . Types . Int -> GHC . Types . Int ->
               GHC . Types . Int
  [ GblId , Arity =2]
  Foo . f =
      ( x_a9H :: GHC . Types . Int )
        ( y_a9I :: GHC . Types . Int ) ->
        GHC . Num .*
           @ GHC . Types . Int
           GHC . Num . $fNumInt
           x_a9H
           ( GHC . Num .+
               @ GHC . Types . Int GHC . Num . $fNumInt
               x_a9H y_a9I )


 Core は GHC が内部で利用している Lambda 式     .   .   .   .   .     .
Core から Core へ




                 .   .   .   .   .   .
Core から Core へ


 Lambda 式を変換すれば、 GHC でプログラム変換
 が書ける。主に最適化のパスを実装する目的で利
 用されているらしい
    compiler/simplCore 以下に変換パスの定義
    compiler/coreSyn 以下に Core の定義や変換用
    ライブラリ




                         .   .   .   .   .   .
simpl の変換パスの追加




 例えば foo というパスを追加する




                      .   .   .   .   .   .
simpl の変換パスの追加

 変換パス foo の追加

 compiler/simplCore/Foo.lhs:
 module Foo ( fooProgram ) where

 import CoreSyn ( CoreProgram )

 fooProgram :: CoreProgram -> CoreProgram
 ...




                               .   .   .   .   .   .
simpl の変換パスの追加

 変換パス foo の追加

 compiler/simplCore/Foo.hs:
 module Foo ( fooProgram ) where

 import CoreSyn ( CoreProgram )

 fooProgram :: CoreProgram -> CoreProgram
 fooProgram = id




                              .    .   .   .   .   .
simpl の変換パスの追加

 変換パス foo の追加

 compiler/simplCore/CoreMonad.lhs

 data CoreToDo ...

   ...
   | CoreFoo
   ...




                                .   .   .   .   .   .
simpl の変換パスの追加
 変換パス foo の追加

 compiler/man/DynFlags.hs
 data DynFlag
    ...
    -- optimisation opts
    ...
    | Opt_Foo
    ...
 fFlags = [
   ...
   ( " foo " , Opt_Foo , nop ) ,
   ... ]

                                   .   .   .   .   .   .
simpl の変換パスの追加

 変換パス foo の追加

 compiler/coreSyn/SimpleCore.lhs
 ...
 getCoreToDo
   ...
   where
     ...
     strictness = dopt Opt_Strictness              dflags
     ...
     foo        = dopt Opt_foo                     dflags
     ...

                                   .   .   .   .    .   .
simpl の変換パスの追加

 変換パス foo の追加

 compiler/coreSyn/SimpleCore.lhs
 ...
 getCoreToDo
   ...
   [ ...
     runWhen strictness ... ,
     ...
     runWhen foo CoreFoo ,
     ...
   ]

                                   .   .   .   .   .   .
simpl の変換パスの追加

 変換パス foo の追加

 compiler/coreSyn/SimpleCore.lhs
 import Foo ( fooProgram )
 ...
 doCorePass :: CoreToDo -> ...
 ...
 doCorePass CoreFoo = doPass fooProgram
 ...




                                   .   .   .   .   .   .
simpl の変換パスの追加


 変換パス foo の追加

   ここまでの変更で、コンパイラに       -O1 -ffoo
   スイッチを与えれば、 Foo (fooProgram) でプ
   ログラムが変換されるようになっている
   はず。
   あとは Foo.hs を実装すればよい



                      .   .   .   .   .   .
利用できるライブラリ

 外部ライブラリと同じものでは
   ex. -package Cabal-1.14.0 -package
   array-0.4.0.0 -package base-4.5.0.0 -package
   bin-package-db-0.0.0.0 -package
   bytestring-0.9.2.1 -package containers-0.4.2.1
   -package directory-1.1.0.2 -package
   filepath-1.3.0.0 -package hoopl-3.8.7.3
   -package hpc-0.5.1.1 -package old-time-1.1.0.0
   -package process-1.1.0.1 -package unix-2.5.1.0


                                .   .   .   .   .   .
利用できるライブラリ



 コンパイラ内部だと
   TrieMap(CoreMap)
        CoreExpr を key とした Map
    CoreSubst(Subst)
        Core Syntax を置換するためのデータ構造




                                 .   .   .   .   .   .
実装されている最適化パスの例



 CSE (Common SubExpression Elimination)
     -O1 -fcse
     PRE (Partial redundancy elimination) とも
     式の字面で判断して共通式を除去




                                .   .   .   .   .   .
CSE


      x = p   + q
      y = p   + q
      -- ↓
      x = p   + q   -- Map p + q = > x
      y = p   + q   -- 置き換え対象
      -- ↓
      x = p   + q   -- Map   p + q => x
      y = x




                                  .   .   .   .   .   .
CSE

      r = p
      s = q
      x = p   + q
      y = r   + s
      -- ↓
      r = p
      s = q
      x = p   + q   -- Map p + q = > x
      y = r   + s   -- Map r + s = > y
                    -- 置き換え対象が無い



                                 .   .   .   .   .   .
自分でも最適化パスを追加してみまし
た



 GVN (Global value numbering)
     式が生成する値ごとに異なる番号を付けてい
     き、同じ番号の付いた式を除去する




                                .   .   .   .   .   .
GVN



  -- p ,   q は自由変数
  r = p
  s = q
  x = p    + q
  y = r    + s
  z = x    * y




                     .   .   .   .   .   .
GVN

  z = x * y -- 略
  -- hash [r + s] = hplus [ hash [r],
  --                        hash [+] ,
  --                        hash [s ]]
  --              -- p = > 1, (+) = > 2, q = > 3,
  --              -- r = > 1, s = > 3
  --              = hplus [ 1, 2, 3]
  --              = 123
  -- この例では例えば         123 になったとしておく
  y = r + s -- y = > 123
  x = p + q -- x = > 123
  s = q      -- s = > 2, q = > 2
  r = p      -- r = > 1, r = > 1

                             .   .   .   .   .   .
GVN


  y   =   r + s -- y   =>   123
  x   =   p + q -- x   =>   123
  s   =   q     -- s   =>   2, q = > 2
  r   =   p     -- r   =>   1, r = > 1

  -- 1:   r == > p
  -- 2:   s == > q
  -- 123: y == > x




                                    .    .   .   .   .   .
GVN


  -- 1:   r == > p
  -- 2:   s == > q
  -- 123: y == > x

  r   =   p     --   変化なし          -- 除去可能
  s   =   q     --   変化なし          -- 除去可能
  x   =   p + q --   変化なし
  y   =   p + q --   <-- y = r +   s -- 除去可能
  z   =   x * x --   <-- z = x *   y




                                   .   .   .   .   .   .
デモ




 デモ


      .   .   .   .   .   .
まとめ


  Lambda 式 Core の変換でプログラム変換を実
  装できる
  ライブラリも結構使えるので書きやすい
  GVN を実装してみた。が不完全なのでもう
  ちょっとがんばりたい
  Compiler plugin 化もしてみたい




                   .   .   .   .   .   .

More Related Content

PDF
Goをカンストさせる話
PPT
C++でHello worldを書いてみた
PDF
mlr-grep - レコード指向grep
PPT
diff template library
PDF
Introduction to NumPy & SciPy
PPT
python-geohex
PDF
Boost Tour 1.48.0 diff
PDF
Siv3Dで楽しむゲームとメディアアート開発
Goをカンストさせる話
C++でHello worldを書いてみた
mlr-grep - レコード指向grep
diff template library
Introduction to NumPy & SciPy
python-geohex
Boost Tour 1.48.0 diff
Siv3Dで楽しむゲームとメディアアート開発

What's hot (20)

PDF
diffの真髄
PDF
NumPyが物足りない人へのCython入門
KEY
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PDF
V6でJIT・部分適用・継続
PDF
マーク&スイープ勉強会
PDF
マスターオブゴールーチンアンドチャネル スタートGo #1
PDF
プログラミング言語 Julia の紹介
PPT
CLR/H No.35-2
PDF
スクリプトで文字コード変換
PDF
コルーチンの使い方
ODP
(define)なしで再帰関数を定義する
PPTX
Brief introduction of Boost.ICL
PDF
条件分岐とcmovとmaxps
ODP
Real World OCamlを読んでLispと協調してみた
PDF
Boost.Coroutine
PDF
LLVM最適化のこつ
PDF
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
ODP
F#とC#で見る関数志向プログラミング
PDF
Delimited Dynamic Binding
PDF
diffの真髄
NumPyが物足りない人へのCython入門
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
V6でJIT・部分適用・継続
マーク&スイープ勉強会
マスターオブゴールーチンアンドチャネル スタートGo #1
プログラミング言語 Julia の紹介
CLR/H No.35-2
スクリプトで文字コード変換
コルーチンの使い方
(define)なしで再帰関数を定義する
Brief introduction of Boost.ICL
条件分岐とcmovとmaxps
Real World OCamlを読んでLispと協調してみた
Boost.Coroutine
LLVM最適化のこつ
2011.7.3 札幌C++勉強会#2「C++のマクロはどこまで関数をいじれるのか」
F#とC#で見る関数志向プログラミング
Delimited Dynamic Binding
Ad

Viewers also liked (8)

PPTX
Html5 101
ODP
Html5 101
PDF
Museo de antequera
PDF
Lazy Pairing Heap
PDF
HaskellDB
PDF
Profunctor and Arrow
PDF
Html5 101
PDF
Learn BEM: CSS Naming Convention
Html5 101
Html5 101
Museo de antequera
Lazy Pairing Heap
HaskellDB
Profunctor and Arrow
Html5 101
Learn BEM: CSS Naming Convention
Ad

Similar to Adding simpl GVN path into GHC (20)

KEY
Algebraic DP: 動的計画法を書きやすく
PDF
F#入門 ~関数プログラミングとは何か~
KEY
Sml#探検隊
PDF
PFI Christmas seminar 2009
PDF
Ekmett勉強会発表資料
PPTX
Ocaml lecture slides 01 at axsh
PDF
Misrac20150523
PDF
超絶技巧プログラミングの世界(FTD2015)
PDF
あまぁいRcpp生活
PDF
Ssaw08 0916
PPTX
T77 episteme
PPTX
ゼロから始めるScala文法 (再)
PDF
すごいHaskell読書会 第六章 発表資料
PDF
PCD2019 TOKYO ワークショップ「2時間で!Processingでプログラミング入門」
ODP
Ekmett勉強会発表資料
PDF
PFDS 10.2.1 lists with efficient catenation
PDF
たのしい関数型
PDF
プログラミングコンテストでのデータ構造 2 ~動的木編~
PPTX
純粋関数型アルゴリズム入門
PDF
プログラミング作法
Algebraic DP: 動的計画法を書きやすく
F#入門 ~関数プログラミングとは何か~
Sml#探検隊
PFI Christmas seminar 2009
Ekmett勉強会発表資料
Ocaml lecture slides 01 at axsh
Misrac20150523
超絶技巧プログラミングの世界(FTD2015)
あまぁいRcpp生活
Ssaw08 0916
T77 episteme
ゼロから始めるScala文法 (再)
すごいHaskell読書会 第六章 発表資料
PCD2019 TOKYO ワークショップ「2時間で!Processingでプログラミング入門」
Ekmett勉強会発表資料
PFDS 10.2.1 lists with efficient catenation
たのしい関数型
プログラミングコンテストでのデータ構造 2 ~動的木編~
純粋関数型アルゴリズム入門
プログラミング作法

Adding simpl GVN path into GHC

  • 1. . GHC へのプログラム変換パスの . 追加 日比野 啓 2012-09-29 . . . . . .
  • 2. 今日の話 . . . . . .
  • 3. 今日の話 . . . . . .
  • 4. Haskell から Core へ module Foo ( f ) where f :: Int -> Int -> Int f x y = x * (x + y) Haskell を Core 形式へ変換し、出力するコマンド % ghc -c -ddump-simpl Foo.hs . . . . . .
  • 5. Haskell から Core へ Foo . f :: GHC . Types . Int -> GHC . Types . Int -> GHC . Types . Int [ GblId , Arity =2] Foo . f = ( x_a9H :: GHC . Types . Int ) ( y_a9I :: GHC . Types . Int ) -> GHC . Num .* @ GHC . Types . Int GHC . Num . $fNumInt x_a9H ( GHC . Num .+ @ GHC . Types . Int GHC . Num . $fNumInt x_a9H y_a9I ) Core は GHC が内部で利用している Lambda 式 . . . . . .
  • 6. Core から Core へ . . . . . .
  • 7. Core から Core へ Lambda 式を変換すれば、 GHC でプログラム変換 が書ける。主に最適化のパスを実装する目的で利 用されているらしい compiler/simplCore 以下に変換パスの定義 compiler/coreSyn 以下に Core の定義や変換用 ライブラリ . . . . . .
  • 8. simpl の変換パスの追加 例えば foo というパスを追加する . . . . . .
  • 9. simpl の変換パスの追加 変換パス foo の追加 compiler/simplCore/Foo.lhs: module Foo ( fooProgram ) where import CoreSyn ( CoreProgram ) fooProgram :: CoreProgram -> CoreProgram ... . . . . . .
  • 10. simpl の変換パスの追加 変換パス foo の追加 compiler/simplCore/Foo.hs: module Foo ( fooProgram ) where import CoreSyn ( CoreProgram ) fooProgram :: CoreProgram -> CoreProgram fooProgram = id . . . . . .
  • 11. simpl の変換パスの追加 変換パス foo の追加 compiler/simplCore/CoreMonad.lhs data CoreToDo ... ... | CoreFoo ... . . . . . .
  • 12. simpl の変換パスの追加 変換パス foo の追加 compiler/man/DynFlags.hs data DynFlag ... -- optimisation opts ... | Opt_Foo ... fFlags = [ ... ( " foo " , Opt_Foo , nop ) , ... ] . . . . . .
  • 13. simpl の変換パスの追加 変換パス foo の追加 compiler/coreSyn/SimpleCore.lhs ... getCoreToDo ... where ... strictness = dopt Opt_Strictness dflags ... foo = dopt Opt_foo dflags ... . . . . . .
  • 14. simpl の変換パスの追加 変換パス foo の追加 compiler/coreSyn/SimpleCore.lhs ... getCoreToDo ... [ ... runWhen strictness ... , ... runWhen foo CoreFoo , ... ] . . . . . .
  • 15. simpl の変換パスの追加 変換パス foo の追加 compiler/coreSyn/SimpleCore.lhs import Foo ( fooProgram ) ... doCorePass :: CoreToDo -> ... ... doCorePass CoreFoo = doPass fooProgram ... . . . . . .
  • 16. simpl の変換パスの追加 変換パス foo の追加 ここまでの変更で、コンパイラに -O1 -ffoo スイッチを与えれば、 Foo (fooProgram) でプ ログラムが変換されるようになっている はず。 あとは Foo.hs を実装すればよい . . . . . .
  • 17. 利用できるライブラリ 外部ライブラリと同じものでは ex. -package Cabal-1.14.0 -package array-0.4.0.0 -package base-4.5.0.0 -package bin-package-db-0.0.0.0 -package bytestring-0.9.2.1 -package containers-0.4.2.1 -package directory-1.1.0.2 -package filepath-1.3.0.0 -package hoopl-3.8.7.3 -package hpc-0.5.1.1 -package old-time-1.1.0.0 -package process-1.1.0.1 -package unix-2.5.1.0 . . . . . .
  • 18. 利用できるライブラリ コンパイラ内部だと TrieMap(CoreMap) CoreExpr を key とした Map CoreSubst(Subst) Core Syntax を置換するためのデータ構造 . . . . . .
  • 19. 実装されている最適化パスの例 CSE (Common SubExpression Elimination) -O1 -fcse PRE (Partial redundancy elimination) とも 式の字面で判断して共通式を除去 . . . . . .
  • 20. CSE x = p + q y = p + q -- ↓ x = p + q -- Map p + q = > x y = p + q -- 置き換え対象 -- ↓ x = p + q -- Map p + q => x y = x . . . . . .
  • 21. CSE r = p s = q x = p + q y = r + s -- ↓ r = p s = q x = p + q -- Map p + q = > x y = r + s -- Map r + s = > y -- 置き換え対象が無い . . . . . .
  • 22. 自分でも最適化パスを追加してみまし た GVN (Global value numbering) 式が生成する値ごとに異なる番号を付けてい き、同じ番号の付いた式を除去する . . . . . .
  • 23. GVN -- p , q は自由変数 r = p s = q x = p + q y = r + s z = x * y . . . . . .
  • 24. GVN z = x * y -- 略 -- hash [r + s] = hplus [ hash [r], -- hash [+] , -- hash [s ]] -- -- p = > 1, (+) = > 2, q = > 3, -- -- r = > 1, s = > 3 -- = hplus [ 1, 2, 3] -- = 123 -- この例では例えば 123 になったとしておく y = r + s -- y = > 123 x = p + q -- x = > 123 s = q -- s = > 2, q = > 2 r = p -- r = > 1, r = > 1 . . . . . .
  • 25. GVN y = r + s -- y => 123 x = p + q -- x => 123 s = q -- s => 2, q = > 2 r = p -- r => 1, r = > 1 -- 1: r == > p -- 2: s == > q -- 123: y == > x . . . . . .
  • 26. GVN -- 1: r == > p -- 2: s == > q -- 123: y == > x r = p -- 変化なし -- 除去可能 s = q -- 変化なし -- 除去可能 x = p + q -- 変化なし y = p + q -- <-- y = r + s -- 除去可能 z = x * x -- <-- z = x * y . . . . . .
  • 27. デモ デモ . . . . . .
  • 28. まとめ Lambda 式 Core の変換でプログラム変換を実 装できる ライブラリも結構使えるので書きやすい GVN を実装してみた。が不完全なのでもう ちょっとがんばりたい Compiler plugin 化もしてみたい . . . . . .