Slide 1

Slide 1 text

LLVM ͱ C++ ͰίϯύΠϥ ϑϩϯτΤϯυͭͬͨ͘ γεςϜϓϩάϥϛϯάձ 2016/7/1

Slide 2

Slide 2 text

• ࢓ࣄɿαʔϏεͷςετΦʔτϝʔγϣϯΤϯδ χΞʢQAʣ • झຯɿ • Vim • σεΫτοϓΞϓϦͮ͘ΓʢElectronʣ • ίϯύΠϥϑϩϯτΤϯυ ࠓ೔͸͜ΕͰ͢ʂ @Linda_pp @rhysd

Slide 3

Slide 3 text

໨࣍ • ϓϩάϥϛϯάݴޠ Dachs • C++ ͱ LLVM ʹΑΔ࣮૷ • Dachs ࠓޙ

Slide 4

Slide 4 text

ϓϩάϥϛϯάݴޠ Dachs

Slide 5

Slide 5 text

Dachs ͱ͸ https://github.com/rhysd/Dachs 2014 ೥͙Β͍͔Βগͣͭ͠࡞͍ͬͯΔ൚༻໨ తͷݴޠɽLLVM ϑϩϯτΤϯυͱ࣮ͯ͠૷ɽ

Slide 6

Slide 6 text

Dachs ͱ͸

Slide 7

Slide 7 text

Dachs ͱ͸ • Ruby ͷΑ͏ʹ؇͘ॻ͖͍ͨʢॻ͖΍͍͢ߏ จɼGCʣ • ੩తͳνΣοΫ͸΍ͬͯ΄͍͠ʢڧ͍ܕ෇ ͚ɼimmutabilityʣ • ੩తϦϯΫͰόΠφϦੜ੒ʢ࠷దԽɼऔΓճ ͠΍͢͞ͳͲʣ

Slide 8

Slide 8 text

؇͘ॻ͖͍ͨɿؔ਺ func fib(n) case n when 0, 1 ret 1 else ret fib(n-1) + fib(n-2) end end func main() println(fib(10)) # UFCS ʹΑΔߏจ౶ҥ 10.fib.println end

Slide 9

Slide 9 text

؇͘ॻ͖͍ͨɿҾ਺ func fib(n) case n when 0, 1 ret 1 else ret fib(n-1) + fib(n-2) end end template auto fib(T const n) { if (n <= 1) { return 1; } else { return fib(n-1) + fib(n-1); } } Ҿ਺ͷܕΛॻ͔ͳ͍ͱؔ਺ςϯϓϨʔτʹɽ fib(n: int): int ͷΑ͏ʹܕΛॻ͘͜ͱ΋Ͱ͖Δ %BDIT $

Slide 10

Slide 10 text

؇͘ॻ͖͍ͨɿdo-end ߏจ func each(array, block) var i := 0u for i < array.size block(array[i]) i += 1u end end func main [1, 2, 3].each do |i| println(i) end # ϥϜμࣜΛ൐͏ݺͼग़͠ͷߏจ౶ҥ each([1, 2, 3], -> i in println(i)) end

Slide 11

Slide 11 text

؇͘ॻ͖͍ͨɿdo-end ߏจ func each(array, block) var i := 0u for i < array.size block(array[i]) i += 1u end end func main [1, 2, 3].each do |i| println(i) end end • do-end ϒϩοΫ͸Ϋ ϩʔδϟʢม਺ΛΩϟ ϓνϟ͢Δಗ໊ؔ਺ʣ ʹม׵͞ΕΔɽ • ؔ਺ͷ࠷ޙͷҾ਺ͱ͠ ͯؔ਺ΦϒδΣΫτ͕ ౉ͬͯ͘Δ

Slide 12

Slide 12 text

؇͘ॻ͖͍ͨɿclass • init ͕ίϯετϥ Ϋλ • ϝϯόม਺ͷܕ Λਪଌ • ίϯετϥΫλͷؔ਺ς ϯϓϨʔτΛղܾ → Ϋϥ εςϯϓϨʔτΛղܾ class Random init(@seed) end func gen x := @seed high := x / 127773 low := x % 127773 var t := 16807 * low - 2836 * high t += 0x7fffffff if t <= 0 @seed = t ret t end end

Slide 13

Slide 13 text

؇͘ॻ͖͍ͨɿclass class Random init(@seed) end func gen x := @seed high := x / 127773 low := x % 127773 var t := 16807 * low - 2836 * high t += 0x7fffffff if t <= 0 @seed = t ret t end end template class Random { T seed; public: Random(T s) : seed(s) {} auto gen() { const auto x = this->seed, high = x / 127773, low = x % 127773; auto t = 16807 * low - 2836 * high; if (t <= 0) { this->seed = t; } return t; } }; %BDIT $

Slide 14

Slide 14 text

؇͘ॻ͖͍ͨɿGC • array ܕ͸഑ྻʹऔͬ ͯ GC Ͱ؅ཧ͠ɼ৳ॖ Մೳɽ • ϥϯλΠϜ͕ libgc (Boehm GC) Λ࢖ͬͯ ͍Δ func five_elems # ഑ྻ͸ώʔϓʹऔΓɼGC Ͱ؅ཧ ret [1, 2, 3, 4, 5] end func main five_elems()[2].println end

Slide 15

Slide 15 text

੩తνΣοΫɿܕ • ม਺ఆٛͰ͸ӈล͔Β஋Λਪଌɼؔ਺΍ ΫϥεͰ ͸ςϯϓϨʔτʹͯ͠࢖༻࣌ʹΠϯελϯεԽ func fib(n) ret if n <= 1 then 1 else fib(n-1) + fib(n-2) end end func main() result := if special then 42 else fib(n) end end

Slide 16

Slide 16 text

੩తνΣοΫɿimmutability # Ҿ਺ʹ var Λ෇͚Δ͔Ͳ͏͔Ͱ੍ޚ func foo(var a, b) # a ͸ clone ͞ΕɼมߋՄೳ # OK! a.modify_something() # b ͸ࢀরʹͳΓɼมߋෆՄೳ # NOT OK! b.modify_something() end func main() kls := new SomeClass foo(kls, kls) end

Slide 17

Slide 17 text

ͦͷଞͷαϯϓϧ https://github.com/rhysd/Dachs/tree/ master/samples ཚ਺ੜ੒ثɼBrainFxxkॲཧܥɼෆಈ఺ίϯ ϏωʔλɼϚϯσϧϒϩू߹ͳͲ

Slide 18

Slide 18 text

C++ ͱ LLVM ʹΑΔ࣮૷

Slide 19

Slide 19 text

ύʔε ҙຯղੳ ʢ໊લɾલํࢀরղܾɼ ςϯϓϨʔτղੳʣ ҙຯղੳ ܕνΣοΫɼΫϩʔδϟ ͷΩϟϓνϟղܾɼ֤ छνΣοΫ --7.*3 ΁ม׵ όΠφϦ ੜ੒ ύʔαδΣωϨʔλ Ͱύʔε͠"45ੜ੒ είʔϓ໦ੜ੒ɼ γϯϘϧςʔϒϧ "45ʹܕ৘ใ෇Ճɼ Ϋϩʔδϟ͝ͱͷΩϟ ϓνϟςʔϒϧੜ੒ MMWN*3#VJMEFS Ͱ*3ੜ੒ --7.͕ΦϒδΣ ΫτϑΝΠϧੜ੒ɼ MEͰϦϯΫ ࠷దԽ --7.1BTTFT

Slide 20

Slide 20 text

ASTʢ࣮૷Πϝʔδʣ struct ͱ boost::variant ʢ҆શͳڞ༻ମΫϥεʣ ͷΠϯελϯεΛϊʔ υʹ࢖ͬͯදݱ struct string_literal { /*...*/ }; struct binary_expr { /*.. */ }; struct if_expr { /*.. */ }; using expr = boost::variant< string_literal, if_expr, binary_expr >; struct return_statement { /*...*/ }; struct for_statement { /*...*/ }; using statement = boost::variant< return_statement, for_statement, expr >;

Slide 21

Slide 21 text

ύʔα Boost.Spirit ͱ͍͏ύʔαδΣωϨʔλϥΠ ϒϥϦΛ࢖༻͠ɼจࣈྻͷιʔείʔυΛ AST ʹม׵͢Δɽ EDSL ͰએݴతʹύʔεϧʔϧΛ௚઀ C++ ͷ ίʔυͱͯ͠ఆٛ͢Δɽ

Slide 22

Slide 22 text

Boost.Spirit • Boost.Spirit ͱ͍͏ύʔαδΣωϨʔλϥΠϒϥϦΛ࢖༻ • ԋࢉࢠΦʔόʔϩʔυͰ EDSL ͬΆ͘ύʔε͢ΔϧʔϧΛॻ͚Δ • C++ ςϯϓϨʔτΛѱ༻ར༻ͯ͠ίϯύΠϧ࣌ʹϧʔϧͷ੔߹ੑ ΛνΣοΫ • ίϯύΠϧ࣌ؒ΋ Boost ͢Δʢੜ੒͞ΕΔύʔαͷੑೳ͸ྑ͍ʣ • kinaba ͞Μͷ Let’s Boost ͕ࢀߟʹͳΓ·͢ɿhttp:// www.kmonos.net/alang/boost/classes/spirit.html

Slide 23

Slide 23 text

ύʔαͷงғؾ // variable_decl ::= ['var'] variable_name [':' type] // Λύʔε͢ΔϧʔϧΛఆٛ variable_decl = ( -qi::matches[qi::lit("var")] // ୯߲ - ͸ 0 or 1ճϚον >> variable_name // ม਺໊Λύʔε͢Δϧʔϧ >> -( ':' >> type // ': type' Λ෇͚ͯܕΛ໌ࣔͯ͠΋ྑ͍ ) ) [ // ηϚϯςΟοΫΞΫγϣϯ // ରԠ͢Δύʔε͕੒ޭͨ࣌͠ʹݺ͹ΕΔ _val = make_node_ptr( _1, // "var" ͕͔͋ͬͨͲ͏͔ͷ bool ஋ _2, // ม਺໊ _3, // boost::optional<ܕϊʔυ> ͳ஋ ) ];

Slide 24

Slide 24 text

ҙຯղੳɼLLVM IR ੜ੒ • visitor ύλʔϯͰͻͨ͢Β AST ΛᢞΊ·͘Δ • AST ΛҰ८ͯ͠είʔϓ໦΍γϯϘϧςʔϒϧੜ੒ • AST ΛҰ८ͯ͠ܕ৘ใΛऩूɾνΣοΫ • AST ΛҰ८֤ͯ͠ϊʔυʹରԠ͢Δ LLVM IR Λ llvm::IRBuilder Ͱੜ੒ • llvm::IRBuilder ͸ϏϧμʔύλʔϯͰ IR ίʔυΛੜ੒͢ΔͨΊͷϔϧύʔɽLLVM ެ ࣜͷνϡʔτϦΞϧ͕෼͔Γ΍͍͢ http://llvm.org/docs/tutorial/LangImpl3.html

Slide 25

Slide 25 text

ࢀߟɿ visitor // return จ͔Β໭Γ஋ܕΛूΊΔ visitor // Ͳ͏ visit ͢Δ͔Λఆٛͨ͠ߏ଄ମ struct return_types_gatherer { std::vector result_types; // return จͷ node ͷ࣌ template void visit(ast::node::return_stmt const& ret, Walker const& w) { // Ҿ਺Ͱ౉ͬͯ͘Δؔ਺ΦϒδΣΫτΛݺͼग़͢ͱࢠϊʔυ // Λ࠶ؼతʹ visit ͯ͘͠ΕΔ w(); result_types.push_back(ret->ret_type); } // ͦΕҎ֎ͷϊʔυͷͱ͖ template void visit(T const&, W const& w) { w(); } }; // ࢖͍ํ return_types_gatherer gatherer; ast::make_walker(gatherer).walk(some_ast_node);

Slide 26

Slide 26 text

࠷దԽͱΦϒδΣΫτੜ੒ ΄΅ LLVM ʹ͓ΜͿʹͩͬ͜ঢ়ଶɽ LLVM ͸͍͍ͧɽ

Slide 27

Slide 27 text

UBSHFUUSJQMF Λऔಘ EBUBMBZPVU Λऔಘ όοΫΤϯυ ͷॳظԽ UBSHFU NBDIJOFΛ औಘ *3#VJMEFSͰ *3ੜ੒ ؔ਺͝ͱͷ*3 ࠷దԽ Ϟδϡʔϧ͝ͱ ͷ*3࠷దԽɾ *3ݕূ ΦϒδΣΫτϑΝ Πϧͷੜ੒ MEͰϥϯλΠϜΛ ϦϯΫ FH Y@BQQMFEBSXJO $16৘ใ FH""SDI *3ͷ֤ܕ͕ԿCJU͔ FHුಈখ਺఺਺GCJU MMWN'VODUJPO1BTT.BOBHFS MMWN.PEVMF1BTT.BOBHFS ΦϒδΣΫτϑΝΠϧΛੜ੒͢Δ NPEVMFQBTTΛ࢖ͬͯੜ੒ ੨͍෦෼͸΄΅ --7.ͷ"1*Λ ࢖͏͚ͩͰ͍͚Δ ҙຯղੳ ׬ྃ

Slide 28

Slide 28 text

Dachs ࠓޙ

Slide 29

Slide 29 text

ࠓޙ • ύʔα͕ͭΒ͍ͷΛͲ͏ʹ͔͍ͨ͠ • ίϯύΠϧ͕஗͗͢ΔʢMacBook Air ͩͱ4෼͙Β͍ʣ • γϯϘϧ͕େ͖͗ͯ͢ OS X Ͱ gdb ͕Ϋϥογϡ͢Δ • ಠࣗͷ LLVM Pass Λ௥Ճͯ͠ stack promotion ͳͲࣗલͷ࠷దԽΛ࣮૷͍ͨ͠ • ௿Ϩϕϧͳ APIʢstack ʹऔΔ഑ྻɼϙΠϯλʣͷ࠶ઃܭ • ඪ४ϥΠϒϥϦΛࣗ਎ͷݴޠͰ࣮૷͢Δʹ͸ඞཁ • LLVM ͷ C++ όΠϯσΟϯά͸มߋ͕ܹ͍͠ͷͰ llvm-c Λ࢖͏ʁˠ ͍ͬͦผݴ ޠʹ͢Δʁ • ਖ਼֬ͳ GC Λࡌ͍ͤͨ

Slide 30

Slide 30 text

ݴ͍͔ͨͬͨ͜ͱ • ͍͖͞ΐ͏ͷߏจ΍ݴޠػೳΛߟ͑Δͷ͸ָ ͍͠ • ߟ͑ͯΈͨߏจ΍ηϚϯςΟΫε͕࣮ࡍʹಈ ͘ͱ͞Βʹָ͍͠ • LLVM ͸͍͍ͧ

Slide 31

Slide 31 text

LLVM ͱ C++ ͰίϯύΠϥ ϑϩϯτΤϯυͭͬͨͯ͘Δ SPձ 2016/7/1 @Linda_pp @rhysd