Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Protoベースの実行時コンパイル

 Protoベースの実行時コンパイル

Boost.Protoを使って構築した構文木をLLVMで実行時にコンパイルするライブラリについて解説します

Fadis

May 09, 2015
Tweet

More Decks by Fadis

Other Decks in Programming

Transcript

  1. Protoϕʔεͷ
    ࣮ߦ࣌ίϯύΠϧ
    Naomasa Matsubayashi

    View Slide

  2. @fadis_
    Naomasa Matsubayashi
    $FS
    ࠓ೔ͷωλ΋$

    View Slide

  3. if( x >= 5 ) x *= 2;!
    else x += 5;
    ! cmpl! $4, -4(%rbp)!
    ! jle!
    .L2!
    ! sall! -4(%rbp)!
    ! jmp!
    .L3!
    .L2:!
    ! addl! $5, -4(%rbp)!
    .L3:

    View Slide

  4. if( true ) x *= 2;!
    else x += 5;
    ! sall! -4(%rbp)
    ίϯύΠϧ࣌ʹ৚݅ࣜͷ஋͕ఆ·͍ͬͯͨΒ
    ෼ذΛແ͔ͬͨ͜ͱʹग़དྷΔ

    View Slide

  5. ίϯύΠϧ࣌ʹ৚݅ࣜͷ஋͕ఆ·͍ͬͯͨΒ
    ෼ذΛແ͔ͬͨ͜ͱʹग़དྷΔ
    ͨͱ͑࣌ؒʹճ͔͠มΘΒͳ͍஋ͩͬͨͱͯ͠΋
    ىಈ࣌ʹઃఆϑΝΠϧ͔ΒಡΈࠐΜͰ
    ҎޙมԽ͠ͳ͍஋ͩͬͨͱͯ͠΋
    ίϯύΠϧ࣌ʹ஋͕ఆ·͍ͬͯͳ͚Ε͹
    ͦΕ͸ม਺

    View Slide

  6. ճ͔࣮͠ߦ͞Εͳ͍෼ذͳΒɺ
    ͦΕΛճආ͢ΔͨΊʹখࡉ޻͢Δํ͕ߴίετ
    Ͱ΋ͦΕ͕ඵʹԿઍճ΋
    ࣮ߦ͞ΕΔ෦෼ͱ͔ͩͱ࿩͕มΘͬͯ͘Δ

    View Slide

  7. ࣮ྫύέοτϑΟϧλ
    ৚݅ʹ߹கͨ͠ύέοτΛऽΔ
    ৚݅
    if( ௨৴ݩͷΞυϨε͕΄͛΄͛ )...!
    if( ௨৴ઌͷϙʔτ͕΄͛΄͛ )...!
    if( ύέοτͷ௕͕͞΄͛΄͛ )...
    ࣮ࡍʹ͸ϙʔτ੍ݶ͚ͩ
    ৚݅͸࣮ߦ࣌ʹ
    มߋ͞ΕΔ͔΋
    ৚݅ࣜͷத਎͕͔ΘΔස౓ʹରͯ͠
    ॲཧ͢Δσʔλͷྔ͕ۃ୺ʹଟ͍ͱ
    ແବͳ෼ذ͕ແࢹग़དྷͳ͍

    View Slide

  8. Y ίϯύΠϧ࣌ʹఆ·ͬͯมԽ͠ͳ͍஋
    U
    ͜Ε͸ఆ਺ѻ͍ग़དྷΔ
    Y มԽ͠ଓ͚Δ஋
    U
    ͜Ε͸ม਺ѻ͍͢Δ͔͠ͳ͍
    Y ௿͍ස౓ͰมԽ͢Δ஋
    U
    ΄΅ఆ਺͚ͩͲม਺ѻ͍

    View Slide

  9. Y ௿͍ස౓ͰมԽ͢Δ஋
    U
    ΄΅ఆ਺͚ͩͲม਺ѻ͍
    ఆ਺ѻ͍͢ΔͨΊʹ͸
    ίϯύΠϧ࣌ʹ஋͕ఆ·͍ͬͯͳ͍ͱ͍͚ͳ͍
    ͜͜Ͱ࠶ίϯύΠϧ͢Ε͹ྑ͍ͷͰ͸ʂ
    ͜ͷؒ͸ఆ਺
    ͜ͷؒ΋ఆ਺

    View Slide

  10. ͦ͏ͩɺ
    LLVMͩʂ

    View Slide

  11. LLVM
    --7.ΞηϯϒϦ
    ࠷దԽ
    λʔήοτΞʔΩςΫνϟͷ
    ΞηϯϒϦ
    ΦϨΦϨݴޠΛ࡞ͬͨΒ
    --7.ΞηϯϒϦͰग़ྗग़དྷΔΑ͏ʹ͓͚ͯ͠͹
    ޾ͤʹͳΕΔ
    ίϯύΠϥΠϯϑϥετϥΫνϟ

    View Slide

  12. ޙ͔ΒίϯύΠϧ͍ͨ͠ίʔυͷ
    --7.ΞηϯϒϦΛੜ੒͢ΔίʔυΛ
    ίϯύΠϧ࣌ʹίϯύΠϧ͢Δ
    ࣮ߦ࣌ʹੜ੒͞Εͨ--7.ΞηϯϒϦ͔Β
    ωΠςΟϒόΠφϦΛੜ੒࣮ͯ͠ߦ͢Δ

    View Slide

  13. ίʔυʹBCͱॻ͘୅ΘΓʹ
    JS@CVJMEFS$SFBUF"EE B C

    ͱ͔ॻ͔ͳ͍ͱ͍͚ͳ͍
    ޙ͔ΒίϯύΠϧ͍ͨ͠ίʔυͷ
    --7.ΞηϯϒϦΛੜ੒͢ΔίʔυΛ
    ίϯύΠϧ࣌ʹίϯύΠϧ͢Δ

    View Slide

  14. llvm::Value *x = ir_builder.CreateLoad( arg1 );!
    llvm::Value *y = ir_builder.CreateLoad( arg2 );!
    llvm::Value *a = llvm::ConstantFP::get(!
    llvm::Type::getFloatTy( context ), 0.8f!
    );!
    llvm::Value *b = llvm::ConstantFP::get(!
    llvm::Type::getFloatTy( context ), 0.2f!
    );!
    llvm::Value *t0 = ir_builder.CreateMul( x, a );!
    llvm::Value *t1 = ir_builder.CreateMul( y, b );!
    llvm::Value *result = ir_builder.CreateAdd( t0, t1 );
    arg1 * 0.8f + arg2 * 0.2f;
    Λॻ͘୅ΘΓʹ
    ઈରݏͩʂ

    View Slide

  15. llvm::Value *x = ir_builder.CreateLoad( arg1 );!
    llvm::Value *y = ir_builder.CreateLoad( arg2 );!
    llvm::Value *a = llvm::ConstantFP::get(!
    llvm::Type::getFloatTy( context ), 0.8f!
    );!
    llvm::Value *b = llvm::ConstantFP::get(!
    llvm::Type::getFloatTy( context ), 0.2f!
    );!
    llvm::Value *t0 = ir_builder.CreateMul( x, a );!
    llvm::Value *t1 = ir_builder.CreateMul( y, b );!
    llvm::Value *result = ir_builder.CreateAdd( t0, t1 );
    ͬͯॻ͍ͨͷͱ౳ՁʹͳΔ
    ຐ๏ͷϥΠϒϥϦ࡞Εͳ͍͔ͳʔ
    arg1 * 0.8f + arg2 * 0.2f;
    ͬͯॻ͍ͨΒ

    View Slide

  16. softdsp(Ծ)
    IUUQTHJUIVCDPN'BEJTTPGUETQ

    View Slide

  17. struct woo {!
    typedef int function_type(!
    softdsp::data_layout::array< int, 2 >,!
    softdsp::data_layout::tupleint, double, int, int!
    >,!
    softdsp::data_layout::arraysoftdsp::data_layout::array< int, 2 >, 2!
    >!
    );!
    };!
    sd_module.create_function< woo >()[!
    softdsp::_1[ 0 ] <<= 20,!
    softdsp::_1[ 1 ] = (!
    softdsp::static_cast_< int32_t >(!
    softdsp::static_cast_< float >(!
    softdsp::_1[ 0 ]!
    ) * 3 + ++--softdsp::at_c< 2 >( softdsp::_2 ) / 3!
    ) + (!
    ~softdsp::_3[ 1 ][ 1 ] << 1 )!
    ) % 6!
    ];

    View Slide

  18. TEXPP
    HFUFMFNFOUQUSJOCPVOET<Y<YJ>> J J
    HFUFMFNFOUQUSJOCPVOET<YJ> J J
    MPBEJ
    YPSJ
    TIMJ
    HFUFMFNFOUQUSJOCPVOET J J
    MPBEJ
    TVCJ
    TUPSFJ J
    MPBEJ
    BEEJ
    TUPSFJ J
    MPBEJ
    TEJWJ
    HFUFMFNFOUQUSJOCPVOET<YJ> J J
    MPBEJ
    TJUPGQJUPqPBU
    GNVMqPBU F
    TJUPGQJUPqPBU
    GBEEqPBU
    GQUPTJqPBUUPJ
    BEEJ
    TSFNJ
    HFUFMFNFOUQUSJOCPVOET<YJ> J J
    TUPSFJ J
    HFUFMFNFOUQUSJOCPVOET<YJ> J J
    MPBEJ
    TIMJ
    TUPSFJ J
    MPBEJ
    SFUJ

    View Slide

  19. ༻ҙ͢Δຐ๏
    Boost.Proto
    &YQSFTTJPO5FNQMBUFT
    ߏஙࢧԉϥΠϒϥϦ

    View Slide

  20. &YQSFTTJPO5FNQMBUFT


    JOU JOU
    JOUܕͷ
    JOUܕͷ
    JOUܕͷ
    JOU JOU
    ͜ͷࣜͷ݁Ռͷܕ͸
    JOU

    View Slide

  21. &YQSFTTJPO5FNQMBUFT
    QSPUPMJU


    JOU JOU
    JOUͷఆ਺ܕ
    JOUͷఆ਺ʹJOUͷఆ਺Λ଍͢ܕ
    JOUͷఆ਺ʹJOUͷఆ਺Λ଍ͨ͠΍ͭʹJOUͷఆ਺Λֻ͚Δܕ
    JOU
    ͜ͷࣜͷ݁Ռͷܕ͸
    JOUͷఆ਺ʹJOUͷఆ਺Λ଍ͨ͠΍ͭʹJOUͷఆ਺Λֻ͚ͨ΍ͭʹ ུ
    JOU
    JOUͷఆ਺ʹJOUͷఆ਺Λ଍ͨ͠΍ͭʹJOUͷఆ਺Λֻ͚ͨ΍ͭʹ ུ
    ςϯϓϨʔτΛ࢖ͬͯܕͰߏจ໦Λදݱ͢Δ

    View Slide

  22. &YQSFTTJPO5FNQMBUFT
    ͖ͬ͞ͷTPGUETQͷࣜͷ৔߹
    boost::proto::exprns_::exprboost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::term > >, 0l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&,
    boost::proto::exprns_::exprboost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::term > >, 0l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&,
    boost::proto::exprns_::exprboost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::term >, 0l>&, boost::proto::exprns_::exprboost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::term >, 0l>&, boost::proto::exprns_::exprboost::proto::argsns_::list2boost::proto::argsns_::term > >, 0l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&>, 2l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&,
    boost::proto::exprns_::exprboost::proto::argsns_::list2boost::proto::argsns_::list1boost::proto::argsns_::list1boost::proto::argsns_::list2boost::proto::argsns_::term > >, 0l>&,
    boost::proto::exprns_::expr > >, 0l>
    const&>, 2l> const&>, 1l> const&>, 1l> const&, boost::proto::exprns_::exprboost::proto::argsns_::term, 0l> >, 2l> const&>, 2l> const&>, 2l> const&,
    boost::proto::exprns_::exprboost::proto::argsns_::list2boost::proto::argsns_::list1boost::proto::argsns_::list2boost::proto::argsns_::list2boost::proto::argsns_::term > >, 0l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&>, 1l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&>, 2l> const&,
    boost::proto::exprns_::expr, 0l> >, 2l> const&>, 2l> const&>,
    2l>

    View Slide

  23. #PPTU1SPUP
    ग़དྷ্໊͕ͬͨঢ়͕͍ͨ͠ܕͷ஋Λ
    CPPTUQSPUPFWBM ໊ঢ় ུ
    ஋ DPOUFYU

    struct context {!
    template< typename Expr, typename Enable = void > struct eval{};!
    template< typename Expr > struct eval< Expr,!
    typename boost::enable_if< proto::matches< Expr,!
    proto::plus< proto::_, proto::_ >!
    > >::type > {!
    typedef int result_type;!
    result_type operator()( Expr &expr, context_type &context ){!
    (ҎԼུ)
    Ͱॲཧ͢Δ
    ߏจ໦Λ୧Δ࣌ʹߦ͏ॲཧΛఆٛͨ͠΋ͷ

    View Slide

  24. #PPTU1SPUP
    ίϯςΩετͰॲཧ͢Δ࣌ʹ
    ໊ঢ়͕͍ͨ͠ܕͷ಺༰Λ࣮ߦ͢Δͱ
    ஗ԆධՁ΍ϥϜμ͕࣮ݱग़དྷΔ
    ࣮ࡍͷ࣮૷ྫBoost.Phoenix
    ίϯςΩετͰॲཧ͢Δ࣌ʹ
    ߏจ໦Λ$ͷ௨ৗͷղऍͱҟͳΔղऍͰѻ͏ͱ
    $ͷίʔυதʹ%4-ΛຒΊࠐΊΔ
    ࣮ࡍͷ࣮૷ྫBoost.Spirit

    View Slide

  25. ͡Ό͋ɺίϯςΩετͷதͰ
    --7.ΞηϯϒϦΛ૊ΈཱͯͨΒ
    ਓؒʹ༏͍͠ܗͷࣜΛ$ͷதʹ௚઀ॻ͍ͯ
    --7.ΞηϯϒϦΛߏங͢ΔίʔυʹͳΔ
    ͕࣮ݱͰ͖ΔͷͰ͸

    View Slide

  26. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::plus< proto::_, proto::_ >!
    >!
    >::type!
    > {!
    typedef llvm::Value* result_type;!
    result_type operator()(!
    Expr &expr,!
    context_type &context!
    ) {!
    return ir_builder.CreateAdd(!
    proto::eval( boost::proto::left( expr ), context ),!
    proto::eval( boost::proto::right( expr ), context )!
    );!
    }!
    };
    Ճࢉ

    View Slide

  27. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::terminal< proto::_ >!
    >!
    >::type!
    > {!
    typedef llvm::Value* result_type;!
    result_type operator()(!
    Expr &expr,!
    context_type &context,!
    typename boost::enable_if< boost::is_same< int32_t,!
    decltype( boost::proto::value( expr ) )!
    > >::type* = 0!
    ) {!
    return llvm::ConstantInt::get(!
    llvm::Type::getInt32Ty( context ),!
    boost::proto::value( expr )!
    );!
    }!
    };
    ߏจ໦ͷऴ୺

    View Slide

  28. ࢒೦ͳ͕Β͜ͷํ๏͸
    ্ख͍͔͘ͳ͍

    View Slide

  29. --7.ͷ੔਺ܕ
    J J JJJJ
    $ͷ੔਺ܕ
    CPPM
    DIBS
    TIPSU
    JOU
    MPOH
    MPOHMPOH
    TJHOFE
    ූ߸෇͖
    VOTJHOFE
    ූ߸ແ͠
    ූ߸Ͳ͍ͬͨ͜ʂ

    View Slide

  30. add i8 %0, %1
    div i8 %0, %1
    ූ߸ແͩͬͨ͠৔߹Y&YY#
    ූ߸෇͖ͩͬͨ৔߹Y&YY#
    ූ߸ແͩͬͨ͠৔߹Y&YY
    ූ߸෇͖ͩͬͨ৔߹Y&YY'$
    udiv i8 %0, %1
    sdiv i8 %0, %1
    ผͷ໋ྩ
    ූ߸ͷ༗ແͷ৘ใ͕ඞཁ

    View Slide

  31. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::plus< proto::_, proto::_ >!
    >!
    >::type!
    > {!
    typedef llvm::Value* result_type;!
    result_type operator()(!
    Expr &expr,!
    context_type &context!
    ) {!
    return ir_builder.CreateAdd(!
    proto::eval( boost::proto::left( expr ), context ),!
    proto::eval( boost::proto::right( expr ), context )!
    );!
    }!
    };
    $Ͱͷܕͷ৘ใ͕
    ্Ґͷϊʔυʹ
    ఻ΘΒͳ͍

    View Slide

  32. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::divides< proto::_, proto::_ >!
    >!
    >::type!
    > {!
    typedef llvm::Value* result_type;!
    result_type operator()(!
    Expr &expr,!
    context_type &context!
    ) {!
    return ir_builder.Create???(!
    proto::eval( boost::proto::left( expr ), context ),!
    proto::eval( boost::proto::right( expr ), context )!
    );!
    }!
    };
    llvm::Value*
    ූ߸ͷ༗ແͷ৘ใ͕ࣦΘΕ͍ͯͯ
    ໋ྩΛܾఆͰ͖ͳ͍

    View Slide

  33. ݴ͍׵͑Ε͹
    $Ͱͷܕ͕Կͩͬͨͷ͔͕
    Θ͔Ε͹Α͍

    View Slide

  34. struct return_value_ {};!
    template< typename T >!
    struct return_value : public return_value_ {!
    return_value( llvm::Value *value_ )!
    : value( value_ ) {}!
    llvm::Value * const value;!
    };
    return_value< signed int >(!
    llvm::ConstantInt::get(!
    llvm::Type::getInt32Ty( context ),!
    boost::proto::value( expr )!
    )!
    );
    $ͰԿܕͩͬͨͷ͔Λ෇Ճͯ͠ฦ͢

    View Slide

  35. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::plus< proto::_, proto::_ >!
    >!
    >::type!
    > {!
    typedef (ུ) raw_result_type; // left + rightͷ݁Ռͷܕ!
    typedef return_value< raw_result_type > result_type;!
    result_type operator()(!
    Expr &expr,!
    context_type &context!
    ) {!
    return return_value< raw_result_type >(!
    ir_builder.CreateAdd(!
    proto::eval( boost::proto::left( expr ), context ),!
    proto::eval( boost::proto::right( expr ), context )!
    )!
    );!
    }!
    };
    ฦΓ஋ʹ$Ͱͷܕ͕
    ؚ·ΕΔ

    View Slide

  36. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::divides< proto::_, proto::_ >!
    >!
    >::type!
    > {!
    typedef (ུ) raw_result_type; // left / rightͷ݁Ռͷܕ!
    typedef return_value< raw_result_type > result_type;!
    result_type operator()(!
    Expr &expr, context_type &context,!
    typename boost::enable_ifboost::is_signed< raw_result_type >!
    >::type* = 0!
    ) {!
    return return_value< raw_result_type >(!
    ir_builder.CreateSDiv(!
    proto::eval( boost::proto::left( expr ),!
    context ).value,!
    proto::eval( boost::proto::right( expr ),!
    context ).value!
    ));!
    }!
    };
    ූ߸෇͖Ͱ͋Δ͜ͱΛ
    ֬ೝ
    ූ߸෇͖༻ͷ໋ྩʹ֬ఆͰ͖Δ

    View Slide

  37. B C

    D E


    BΛϩʔυ
    a / b + c * d
    Ϩδελʹϩʔυ
    ͞ΕͨBͱCͰআࢉ
    আࢉͷ݁ՌΛʹฦ͢
    CΛϩʔυ

    View Slide

  38. B C

    D E


    e = a / b + c * d

    F
    FΛϩʔυ
    ͕ೖͬͯͨ
    3 = a / b + c * d
    ͑

    View Slide

  39. ୅ೖ͸
    ࢦఆͨ͠஋Λࢦఆͨ͠ΞυϨεʹॻ͖ࠐΉૢ࡞
    Ҿ਺͸ॻ͖ࠐΈઌͷ஋Ͱ͸ͳ͘ɺ
    ॻ͖ࠐΈઌ΁ͷϙΠϯλͰͳ͍ͱ͓͔͍͠
    store i32 3, i32* %ptr
    --7.ΞηϯϒϦͰ͸Ҿ਺͸ϙΠϯλ
    Ͱ΋$͸ͦ͏ͳͬͯͳ͍ΑͶ
    a = b

    View Slide

  40. int a;!
    int b = 1;!
    int c = 2;
    a = b + c;
    ࢀর
    ࢀর
    ࢀর
    ࣜͷதʹ໊લΛ෇͚ͨม਺Λஔ͍ͨஈ֊Ͱ͸ɺ
    ͦΕ͸ม਺΁ͷࢀরͱͯ͠ѻΘΕΔ
    ՃࢉΛ͢Δ࣌ʹॳΊͯ
    ϩʔυ͢Δ

    View Slide

  41. a = b + c;
    ม਺BͷΞυϨε
    ໌ࣔతʹ໊લΛ༩͑ΒΕͨྖҬΛࢦ͍ͯ͠Δ
    ࠨล஋ࢀর
    ʹɺCDͷ݁ՌΛ୅ೖ
    ୅ೖޙʹഁغ͞ΕΔҰ࣌ྖҬΛࢦ͍ͯ͠Δ
    ӈล஋ࢀর
    ࠨล஋ࢀরʹ͸୅ೖͰ͖Δ
    ӈล஋ࢀরʹ͸୅ೖͰ͖ͳ͍

    View Slide

  42. ߏจ໦ͷऴ୺Ͱଈ࠲ʹϩʔυ͢Δͱ͍͏͜ͱ͸
    ऴ୺͕͍͖ͳΓӈล஋ࢀরʹ
    ͳͬͯ͠·͏ͱ͍͏͜ͱ
    $Β͍͠୅ೖΛ͚ͨ͠Ε͹ɺ
    $ͱಉ͡Α͏ʹࠨล஋ࢀরΛ
    ѻΘͳ͚Ε͹ͳΒͳ͍

    View Slide

  43. return_value< int >
    த਎͸MMWN*OUFHFS5ZQFͷ஋
    return_value< int& >
    த਎͸MMWN1PJOUFS5ZQFͷ஋
    ͜ͷͭΛ۠ผͯ͠ѻ͏͜ͱ͕Ͱ͖Ε͹ྑ͍

    View Slide

  44. template< typename Index >!
    return_value< typename boost::mpl::atboost::function_types::parameter_typesfunction_type!
    >,!
    Index!
    >::type& > as_value( const placeholder< Index > & ) {!
    llvm::Value *value = &*std::next(!
    llvm_function->getArgumentList().begin(),!
    Index::value!
    );!
    return return_value< typename boost::mpl::atboost::function_types::parameter_typesfunction_type!
    >,!
    Index!
    >::type& >( value );!
    }
    ϩʔυ͠ͳ͍ͰΞυϨεΛฦ͢

    View Slide

  45. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::plus< proto::_, proto::_ >!
    >!
    >::type!
    > {!
    typedef (ུ) raw_result_type; // left + rightͷ݁Ռͷܕ!
    typedef return_value< raw_result_type > result_type;!
    result_type operator()(!
    Expr &expr,!
    context_type &context!
    ) {!
    const auto left =!
    tools->load( proto::eval( boost::proto::left( expr ) );!
    const auto right =!
    tools->load( proto::eval( boost::proto::right( expr ) );!
    return return_value< raw_result_type >(!
    ir_builder.CreateAdd( left.value, right.value )!
    );!
    }!
    };
    ܭࢉͷ௚લͰϩʔυ

    View Slide

  46. template< typename value_type >!
    return_value< typename boost::remove_referencetypename get_return_type< value_type >::type!
    >::type >!
    load( value_type value,!
    typename boost::enable_ifboost::mpl::and_boost::is_convertible< value_type, return_value_ >,!
    boost::is_reference< typename get_return_type< value_type >::type >!
    >!
    >::type* = 0!
    ) {!
    return return_value< typename boost::remove_referencetypename get_return_type< value_type >::type!
    >::type >( ir_builder.CreateLoad( value.value ) );!
    }!
    template< typename value_type >!
    value_type!
    load( value_type value,!
    typename boost::enable_if< boost::mpl::not_< boost::mpl::and_boost::is_convertible< value_type, return_value_ >,!
    boost::mpl::not_boost::is_reference< typename get_return_type< value_type >::type > !
    >!
    > > >::type* = 0 ) { return value; }
    ࠨล஋ࢀরͩͬͨΒ
    ϩʔυͯ͠ࢀরΛ֎͢
    ͦΕҎ֎ͩͬͨΒ
    ͦͷ··ฦ͢

    View Slide

  47. σϦϑΝϨϯε
    *a
    ఴࣈԋࢉࢠ
    a[ i ]
    ͍ͭ͜Β͸Մೳͳ৔߹ࠨล஋ࢀরΛฦ͢
    ࠨล஋ࢀরͷ࣮૷͕ݦஶʹݱΕΔ෦෼
    ୅ೖԋࢉࢠ
    a = b
    ୅ೖͱಉ࣌ʹ৭ʑ͢ΔϠπ
    a += b

    View Slide

  48. template< typename LeftType, typename RightType >!
    return_value<(ུ)> operator()( LeftType left_, RightType right_,!
    typename boost::enable_if<(ུ)>::type* = 0!
    ) {!
    const auto left = tools->as_llvm_value( tools->load( left_ ) );!
    std::vector< int > args =!
    { static_cast< int >( right_ ) };!
    llvm::ArrayRef< int > args_ref( args );!
    return return_valuetypename hermit::range_valuetypename boost::remove_referencetypename get_return_type< LeftType >::type!
    >::type!
    >::type!
    >( !
    tools->ir_builder.CreateExtractValue( left.value, args_ref )!
    );!
    }
    Ϩδελ্ʹ͋Δ഑ྻͷཁૉΛऔΓग़ͯ͠ฦ͢
    ఴࣈԋࢉࢠ ӈล஋ࢀর൛

    View Slide

  49. template< typename LeftType, typename RightType >!
    return_value<(ུ)> operator()( LeftType left_, RightType right_,!
    typename boost::enable_if<(ུ)>::type* = 0!
    ) {!
    typename static_cast_< int >::template eval< Context >
    cast( tools );!
    llvm::Value *indices[] = {!
    cast( tools->as_llvm_value( 0u ) ).value,!
    cast( tools->as_llvm_value( tools->load( right_ ) ) ).value!
    };!
    return return_valuetypename hermit::range_valuetypename boost::remove_referencetypename get_return_type< LeftType >::type!
    >::type!
    >::type&!
    >(!
    tools->ir_builder.CreateInBoundsGEP( left_.value, indices )!
    );!
    }
    ഑ྻͷઌ಄ΞυϨε͔ΒཁૉͷΞυϨεΛٻΊͯฦ͢
    ఴࣈԋࢉࢠ ࠨล஋ࢀর൛

    View Slide

  50. a[ i ] = b;
    ͕Ͱ͖Δʂ

    View Slide

  51. c = a + b;
    ࣮͸qPBU ࣮͸JOU
    ͜͜·Ͱͷ࣮૷Ͱ͸͜ͷܭࢉ͸ࣦഊ͢Δ
    --7.ʹ͸҉໧ͷΩϟετ͕ͳ͍
    ΩϟετΛ࡞Ζ͏

    View Slide

  52. template< typename From, typename To_ >!
    llvm::Value *cast( llvm::Value *src,!
    typename boost::enable_ifboost::mpl::and_boost::is_integral< From >,!
    boost::is_signed< From >,!
    boost::is_float< To_ >!
    >!
    >::type* = 0!
    ) {!
    return tools->ir_builder.CreateSIToFP(!
    src,!
    tools->type_generator_( tag< To_ >() )!
    );!
    }
    ූ߸෇͖੔਺͔Βුಈখ਺΁ͷΩϟετ

    View Slide

  53. template< typename Expr > struct eval< Expr,!
    typename boost::enable_ifproto::matches< Expr,!
    proto::plus< proto::_, proto::_ >!
    >!
    >::type!
    > {!
    typedef (ུ) raw_result_type; // left + rightͷ݁Ռͷܕ!
    typedef return_value< raw_result_type > result_type;!
    result_type operator()(!
    Expr &expr,!
    context_type &context!
    ) {!
    typename static_cast_< result_type >::template eval< Context >!
    cast( tools );!
    const auto left =!
    cast( tools->load( proto::eval( boost::proto::left( expr ) ) );!
    const auto right =!
    cast( tools->load( proto::eval( boost::proto::right( expr ) ) );!
    return return_value< raw_result_type >(!
    ir_builder.CreateAdd( left.value, right.value )!
    );!
    }!
    };
    ྆ลͷ஋Λ݁ՌͷܕʹΩϟετ

    View Slide

  54. "#*ͷนΛӽ͑Δ
    ίϯύΠϧ࣌ʹίϯύΠϧ͞Εͨଆͷίʔυ͸
    --7.͕ੜ੒͢Δίʔυͱ
    "#*ޓ׵͕͋Δͱ͸ݶΒͳ͍
    --7.͕ੜ੒ͨؔ͠਺ʹҾ਺Λ౉࣌͢ʹ
    Ҿ਺͕ਖ਼͘͠ಡΊͳͯ͘ࠔΔ

    View Slide

  55. "#*ͷนΛӽ͑Δ
    --7.͕ཁٻ͢Δσʔλͷ഑ஔΛ
    γϦΞϥΠθʔγϣϯϑΥʔϚοτͱݟͳͯ͠
    σʔλߏ଄ΛγϦΞϥΠζ͢Δ
    data_layout::tuple< int32_t, float > foo;
    ࢦఆ͞ΕͨσʔλϨΠΞ΢τͰ
    --7.ͷߏ଄ମͱͯ͠ཁૉΛ֨ೲ͢Δλϓϧ
    3BOEPN"DDFTT4FRVFODF
    \J qPBU^
    foo.get()

    View Slide

  56. "#*ͷนΛӽ͑Δ
    data_layout::array< int32_t, 3 > foo;
    ಉ༷ʹ഑ྻ΋
    3BOEPN"DDFTT5SBWFSTBM3BOHF

    foo.get()
    --7.͕ཁٻ͢Δσʔλͷ഑ஔΛ
    γϦΞϥΠθʔγϣϯϑΥʔϚοτͱݟͳͯ͠
    σʔλߏ଄ΛγϦΞϥΠζ͢Δ

    View Slide

  57. "#*ͷนΛӽ͑Δ
    value_generator vg(!
    context, data_layout!
    );!
    auto value = vg(!
    tag< softdsp::data_layout::tupleint, double, int, int!
    > >()!
    );!
    boost::fusion::at_c< 0 >( value ) = 4;!
    boost::fusion::at_c< 1 >( value ) = 5.0;!
    boost::fusion::at_c< 2 >( value ) = 8;!
    boost::fusion::at_c< 3 >( value ) = 20;

    View Slide

  58. ࠓޙͷల๬
    طʹग़དྷ͍ͯΔ͜ͱ
    εΧϥ୯߲ɺ߲ԋࢉͷࣜΛ
    ࣮ߦ࣌ʹίϯύΠϧ࣮ͯ͠ߦ͢Δ
    ࠓऔΓ૊ΜͰ͍Δ͜ͱ
    ςετ͕ɺςετ͕ͳ͍ͱࢮΜͰ͠·͏ʂ
    কདྷతʹऔΓ૊Έ͍ͨ͜ͱ
    4*.%ରԠɺܭࢉͷPIVSPEP

    View Slide

  59. ·ͱΊ
    --7.ͱ#PPTU1SPUPΛ૊Έ߹Θͤͯ
    ·ΔͰී௨ͷ$ͷࣜͷΑ͏ʹݟ͑ΔͦͷίʔυΛ
    ࣮ߦ࣌ʹίϯύΠϧ͠·͠ΐ͏

    View Slide

  60. Thank you for listening

    View Slide