# HG changeset patch # User Nobuyasu Oshiro # Date 1325664772 -32400 # Node ID 6465e96ba272423e6ab0d918f175413410d13d9b # Parent 2697e09f6ce9db1a12f8cdfb72fc173645c8f47d modify explanation of continuation with environment diff -r 2697e09f6ce9 -r 6465e96ba272 presen/index.html --- a/presen/index.html Tue Jan 03 22:11:32 2012 +0900 +++ b/presen/index.html Wed Jan 04 17:12:52 2012 +0900 @@ -504,45 +504,23 @@
-

CbCの実装:TCE(末尾除去)の動作

-
  • スタック:呼び出し元関数と同じ範囲を使うことになる。
  • - - - -
    -

    - -

    -
    -
      -
    • func_bの引数はfunc_aのスタックに上書する
    • -
    • func_bの為にスタックポインタは伸ばされない
    • -
    -
    -
  • CbCにおけるコードセグメントへの継続はこのTCEを用いて実装されている。
  • -
  • TCEにかかるには条件が幾つかある。
  • -
    - -

    CbCの実装:TCE(末尾除去)

    +
    - -
    -

    CbCの実装:TCE(末尾除去)

    -
  • 条件を回避する為以下の実装にする。
  • -
      + +
    1. 条件を回避する為以下の実装にする。
    2. +
      • 型はvoid型で統一する。
      • gotoの直後にreturnを置く。
      • スタックサイズは固定にする。
      • 引数は一旦、一時変数にコピーする。
      • -
    + +
    @@ -564,37 +542,6 @@
    - - -
    -

    CbCの実装:TCE(末尾除去)

    -
  • try_tail_callフラグが落とされる部分
  • - - - - -
    -
    -  if (currently_expanding_call++ != 0
    -      || ((!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl))) 
    -         && !flag_optimize_sibling_calls)
    -      || args_size.var
    -      || dbg_cnt (tail_call) == false)
    -    try_tail_call = 0;
    -	
    -
    -
  • !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)により条件を回避
  • -
    -

    CbCの実装:TCE(末尾除去)

  • try_tail_callフラグが落とされる部分
  • @@ -602,6 +549,16 @@
    +
    +  if (currently_expanding_call++ != 0
    +      || ((!fndecl || !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl))) 
    +         && !flag_optimize_sibling_calls)
    +      || args_size.var
    +      || dbg_cnt (tail_call) == false)
    +    try_tail_call = 0;
    +
    +     :
    +
       if (
     #ifdef HAVE_sibcall_epilogue
           !HAVE_sibcall_epilogue
    @@ -627,20 +584,9 @@
                                                  crtl->args.size))
           || !lang_hooks.decls.ok_for_sibcall (fndecl))
         try_tail_call = 0;
    -	
    - - - -
  • 引数のスタックサイズ、関数の型のチェックが行われる。
  • -
    - -
    -

    CbCの実装:TCE(末尾除去)

    -
  • try_tail_callフラグが落とされる部分
  • - - - +
    -
    +
    +      :
    +
       /* Check if caller and callee disagree in promotion of function                                                                                                                      
          return value.  */
     #ifndef noCbC
    @@ -676,10 +622,10 @@
             try_tail_call = 0;
         }
     	
    -
    -
  • 関数の型のチェックが行われる。
  • +
  • !CbC_IS_CODE_SEGMENT (TREE_TYPE (fndecl)により条件を回避
  • @@ -786,10 +732,10 @@

    CbCの実装:引数渡し

    +
    - + @@ -959,64 +905,59 @@

    環境付き継続:実装の問題

    +
  • 重要な部分
    • -
    • リターンするretval変数が重要になってくる。
    • -
    • retval変数のデータをどうやって確保するか。
    • +
    • リターンするretval変数のメモリ確保
  • 次の方法が考えられる。
    • クロージャでの確保
    • staticでの確保
    • +
    • setjmpを用いての実装
    • static thread local storage(tls)を用いての確保
    • +
    • 戻り値を入れるレジスタを明示的に指定

    環境付き継続:実装の問題

      -
    • クロージャでの実装の問題点:
    • - -
        -
      • CbCでは継続によりスタックの値は破棄されていく。
      • -
      • クロージャにしたコードが破棄される可能性がある。
      • -
      -
      -
    • staticでの実装の問題点:
    • - -
        -
      • マルチスレッドのプログラムに対応できない。
      • -
      • 値を返し切る前に別スレッドによって値が書き換えられる可能性がある。
      • -
      +
    • クロージャでの実装の問題点:
    • + +
        +
      • CbCでは継続によりスタックの値は破棄されていく。
      • +
      • クロージャにしたコードが破棄される可能性がある。
      • +
      + +
    • staticでの実装の問題点:
    • + +
        +
      • マルチスレッドのプログラムに対応できない。
      • +
      • 値を返し切る前に別スレッドによって値が書き換えられる可能性がある。
      • +
      + +
    • setjmpでの実装
    • +
        +
      • setjmpを行うTreeを生成するのが少し手間になる。
      • +
      • int型の戻値しか得られない。
      • +

    環境付き継続:実装の問題

    -
  • static tlsでの実装
    • -
    • スレッド毎に静的に値を確保する。
    • -
    +
  • static tlsでの実装
  • + +
    • 現在はこの方法で実装を行なっている。
    • しかし、最適化にかけると正しい値が返ってこない。
      (最適化によりコードが削除されている...?)
    • -
    - -
    -

    環境付き継続:その他の実装方法

    + +
  • 戻値を入れるレジスタを明示的に指定する。
    • -
    • setjmpでの実装
    • -
        -
      • setjmpを行うTreeを生成するのが少し手間になる。
      • -
      • int型の戻値しか得られない。
      • -
      -
    • 戻値を入れるレジスタを明示的に指定する。
    • -
        -
      • まだ実装を試していない。
      • -
      +
    • まだ実装を試していない。
    • +
    @@ -1056,40 +997,47 @@
  • llvmへのCbCの実装
  • -
  • ご清聴ありがとうございました。
  • +
    +

    ご清聴ありがとうございました。

    +

    CbCの実装:TCE(末尾除去)の動作

    +
  • スタック:呼び出し元関数と同じ範囲を使うことになる。
  • +
    引数渡しに使われるレジスタの数(gcc)引数渡しに使われるレジスタの数(gcc)
    arch int(整数型)
    + + +
    +

    + +

    +
    +
      +
    • func_bの引数はfunc_aのスタックに上書する
    • +
    • func_bの為にスタックポインタは伸ばされない
    • +
    +
    +
  • CbCにおけるコードセグメントへの継続はこのTCEを用いて実装されている。
  • +
    + +

    CbCの機能の拡張:__rectype の実装

    +
    - -
    -

    CbCの機能の拡張:__rectype の実装

  • そこで、__rectype という予約後を作り、以下の宣言を行えるようにした。
  • -
    +	
     __code factorial(int n, int result, __rectype *print) {
        :
        goto (*print)(n,result,print,exit1, envp);
     }
     	
    +