Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
LLVM Tutorial 02 - わいわいswiftc
Search
sonson
March 01, 2019
Programming
470
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
LLVM Tutorial 02 - わいわいswiftc
LLVMチュートリアルをやってみよう.
今回は第3章くらいまでです.
sonson
March 01, 2019
More Decks by sonson
See All by sonson
計算グラフのJITコンパイラをLLVM on C++で作ろう
sonsongithub
2
640
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.6k
LLVM Tutorial - わいわいswiftc
sonsongithub
0
360
How to make and publish a Swift playground book for iPad
sonsongithub
5
19k
Swiftで実装するHTML特殊文字の高速処理
sonsongithub
3
8.1k
First step of 3D touch
sonsongithub
0
730
Getting started with 3D Touch
sonsongithub
0
820
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
610
Other Decks in Programming
See All in Programming
Androidだけじゃない、DroidKaigiで広がった私の技術スタック
akkeylab
0
120
速習iPhone Duo対応
yuukiw00w
2
970
Verilogで学ぶCPU自作入門
uyuki234
8
4k
phperだってパンチカードでコーディングしたい
o0h
PRO
0
230
カツオ、ご期待ください
suneo3476
0
160
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
310
パーソナライズPodcastを作った話
repunit11
0
130
気持ちぃ〜角丸 Squircle
ryu1013
0
120
CodeRabbitの効果検証と過ごしてみた3ヶ月
armondando
0
190
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
140
Workers Cache を知る
syumai
0
340
mrbgem 三角測量 開発
ogom
0
210
Featured
See All Featured
Designing for Timeless Needs
cassininazir
1
520
Rails Girls Zürich Keynote
gr2m
96
14k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
So, you think you're a good person
axbom
PRO
2
2.2k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
Practical Orchestrator
shlominoach
192
12k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
390
What's in a price? How to price your products and services
michaelherold
247
13k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
840
Facilitating Awesome Meetings
lara
57
7.2k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
570
Transcript
Getting start with llvm Θ͍Θ͍swiftc Yuichi Yoshida Senior researcher, DENSO
IT Laboratory, Inc. #conference @sonson_twit © 2018 DENSO IT Laboratory, Inc., All rights reserved. Redistribution or public display not permitted without written permission from DENSO IT Laboratory, Inc. LLVM Tutorial
https://peaks.cc/books/iOS12
LLVM IRಡΊ·͔͢ʁ @G = weak global i32 0 ; type
of @G is i32* @H = weak global i32 0 ; type of @H is i32* define i32 @test(i1 %Condition) { entry: br i1 %Condition, label %cond_true, label %cond_false cond_true: %X.0 = load i32* @G br label %cond_next cond_false: %X.1 = load i32* @H br label %cond_next cond_next: %X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ] ret i32 %X.2 }
LLVMͱʁ • ίϯύΠϥ։ൃج൫ • ίϯύΠϥΛ࡞ΔͨΊͷϥΠϒϥϦ • C++Ͱॻ͔Ε͍ͯΔ • ෭࢈ •
LLDB • clang • GNU GCC͕ංେԽ͗ͨ͢͠ର߅അ • dragoneggͱݺΕΔgccͷόοΫΤϯυ͋Δ • libc++
$ݴޠ --7.*3 1BTT όΠφϦ ίϯύΠϥ 1BTT LLVMΛͬͯ࡞Δ ͜ͷPass͕ॏཁ ৭ʑ༻ҙ͞Ε͍ͯΔ͠ ࣗͰ࡞ΕΔ
x86, ARM, ia64, i386ɾɾɾͳͲ όΠφϦͷมLLVMͷϞδϡʔϧ
ΦϨΦϨ ݴޠ --7.*3 1BTT όΠφϦ ίϯύΠϥ 1BTT ͑͜͜͞࡞Ε ͋ͱLLVMʹͤΒΕΔ
Swiftͷ߹ 4XJGU 4*- 4*- ܕ੍ 4*- 3"8 4*- ࠷దԽ --7.*3
4XJGU*OUFSNFEJBUF-BOHVBHF
Ԡ༻ BSN " " 4
Ԡ༻ BSN " " 4 BSN " " 4 BSN
" " 4 BSN " " 4 BSN " " 4
Ԡ༻ CJUDPEF " " 4 BSN --7.Λ͍ ֤σόΠε͚ ʹ࠷దԽ
ͳͥɼLLVMʁ • ੈͷதͷྲྀΕ • ϜʔΞͷ๏ଇͷݶք • CPUͷྔతਐԽɼݶքʹ͍͍ۙͮͯΔʢཧతʣ • ճආ͢Δʹʁ •
ฒྻԽ • CPUສೳ͗͢ΔˠGPU, FPGA, ASIC • ͲΕ։ൃ͕ࠓ·Ͱͷͱҧ͍͗ͯ͢ࠔۃ·Δ ιϑτΣΞͷ։ൃํ๏͕৭ʑࢼ͞Ε͍ͯΔ
͜͜ͷ • Halide • LLVMΛ͍ɼC/C++ʹฒྻίʔυΛ͔͚Δ • fixstars͕͜ΕͰHalide FPGAͳͲΛϦϦʔε • temp.split(y,
y, yi, 8).parallel(y).vectorize(x, 4); • Tensorflow for Swift • SwiftͰػցֶशͷߦྻܭࢉฒྻܭࢉΛΓ͍ͨ • Julia • ֶతͳܭࢉΛඳ͖ͨ͘͢͠ݴޠ • LLVMΛ༻ ཁॴɼཁॴͰLLVM͕ग़ͯ͘Δ
[11]
Halide [10] • εϨου • SIMD • GPU • ͳͲͳͲɾɾɾ
Halide HalideͳΒɼ͜ͷίʔυͰશͯͷڥʹϙʔτͰ͖Δ [10] • εϨου • SIMD • GPU •
ͳͲͳͲɾɾɾ
·ͱΊΔͱ • ࠷ۙͷίϯύΠϥLLVM • HalideͳͲΛར༻͢ΔʹLLVM • ΓɼLLVMΛΒͳ͍ͱલʹਐΊͳ͍
LLVM Tutorial • LLVMΛͬͯΦϨΦϨݴޠͷίϯύΠϥΛ࡞Δ • C++ͰllvmΛϥΠϒϥϦͱͯ͠ɼίϯύΠϥΛ։ൃ • ಡΉͷʹඞཁͳεΩϧ • C++
• ӳޠ • ͳΜ͔brokenͩͬͨΓɼ͚ͩͨ͘ײ͡ • ਖ਼ɼจ͕͗ͯ͢ಡΊͳ͔ͬͨΓɼ͋Μ·ϝϯς φϯε͞Εͯͳ͍ͱ͜Ζ͋Δ
LLVM Tutorialͱʁ • Tutorials about using LLVM. Includes a tutorial
about making a custom language with LLVM.
ϝϞॻ͖ͳͲ • https://github.com/sonsongithub/llvm-tutorial • LLVM Release Licenseʹج͖ͮɼ༁ϝϞΛެ։ ͍ͯ͠·͢
TutorialͷϏϧυʹ͍ͭͯ • 7.0Chapter4Ҏ߱ɼStandard libraryͷؔΛϦ ϯΫͯ͠Δαϯϓϧ͑ͳ͍ • ֎෦ͷAPIݺͼग़͠ʹࣦഊͯ͠Ϋϥογϡ͢Δ • 6.0OK •
github͔ΒνΣοΫΞτ͠ɼϏϧυ͢Δͷ͕ྑ͍ • ֬ೝͨ͠ڥ • macOS, brewͱιʔε͔ΒϏϧυ • Linux, aptͷύοέʔδͱιʔε͔ΒϏϧυ
ίϯύΠϥͷதʹ /// ίϯύΠϥͷதͰɼKaleidoscope͔ΒݺΔؔΛఆٛ͢Δ /// putchard - putchar that takes a
double and returns 0. extern "C" DLLEXPORT double putchard(double X) { fputc((char)X, stderr); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. extern "C" DLLEXPORT double printd(double X) { fprintf(stderr, "%f\n", X); return 0; }
TutorialϏϧυํ๏ • macOS • clang++ɾɾɾdeveloper tool • llvm-configɾɾɾιʔε͔ΒࣗલͰϏϧυͨ͠ͷ • linux
• g++ɾɾɾbuild essentials • llvm-configɾɾɾaptͰπʔϧΛΠϯετʔϧ • -rdynamic,-Wl,–export-dynamic͕ඞཁͳ͜ͱ͋Δ clang++ ./toy.cpp `../../../build/bin/llvm-config --cxxflags --ldflags --libs --libfiles --system-libs`
༁ • ͡Ίʹ • ύʔαͱநߏจ • LLVM IRίʔυੜ • JITͱ࠷దԽ
• ੍ޚϑϩʔ • ԋࢉࢠͷఆٛ • mutableͷಋೖ • ίϯύΠϧ • σόοάใ • ·ͱΊ
LLVM IRͷಛ • Ϩδελɼมແݶʹ͋Δ • ̏൪ίʔυΈ͍ͨͳײ͡ • SSA(Static Single Assignment
form) • ੩త୯ҰೖɾɾɾมมԽ͠ͳ͍ • ܕݫີ a = (b + c) ∗ d ʢʴɼ̱ɼ̲ɼtmpaddʣ ʢˎɼtmpaddɼ̳ɼaʣ
LLVM IRͷαϯϓϧ define double @baz(double %x) { entry: %ifcond =
fcmp one double %x, 0.000000e+00 br i1 %ifcond, label %then, label %else then: ; preds = %entry %calltmp = call double @foo() br label %ifcont else: ; preds = %entry %calltmp1 = call double @bar() br label %ifcont ifcont: ; preds = %else, %then %iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ] ret double %iftmp }
։ൃ͢ΔݴޠKaleidoscope • ඪͱ༷ • doubleܕͷΈ • ͕ؔ͑Δ • Standard libraryͷؔΛ͑Δ
• if/elseจ • forจ • Ϣʔβఆٛԋࢉࢠ • REPL/JIT
࠷ॳ • ̍ߦΛίϯύΠϧ͢Δ • มͳ͍ • ؔ͋Δ • math.hͱ͔͑Δ •
if/else/forจͳ͠ɾɾɾޙ͔ΒՃ • ͭ·ΓνϡʔϦϯάશͰͳ͍
͜Ε͔ΒC++Ͱ࡞Δͷ ,BMFJEPTDPQFͷιʔείʔυ ΦϨΦϨݴޠͷιʔείʔυ ίϯύΠϥ --7.*3όΠφϦ ,BMFJEPTDPQFΛղऍ͠ --7.Λͬͯɼ--7.*3Λੜ͠ɼ όΠφϦΛు͘ ͭ·ΓɼC++Ͱݴޠͷ༷Λॻ͍͍ͯ͘ײ͡
࠷ॳͷҰาʙޠኮղੳ(Lexer) • ·ͣιʔείʔυΛݻ·Γʹׂ͍ͯ͘͠ extern cos(0.1); ֎෦એݴ tok_extern Կ͔ͷࣝผࢠ tok_identifier τʔΫϯ
tok_number ΧοίͱηϛίϩϯޠኮʹͨΒͳ͍ͷͰɼ ͱΓ͋͑ͣඈ͢
ୈೋาʙநߏจ def hoge(a b c) a+(b+c); FunctionAST Proto PrototypeAST Body
BinaryExprAST - + LHS VariableExprAST - a RHS BinaryExprAST - + LHS VariableExprAST - b RHS VariableExprAST - c ԋࢉࢠͷ༏ઌʹج͖ͮɼਂ͞༏ઌͰߏจΛ࡞͍ͬͯ͘
நߏจͷΫϥε class ExprAST { public: virtual ~ExprAST() = default; virtual
Value *codegen() = 0; };
มΛอ࣋͢Δϊʔυ class VariableExprAST : public ExprAST { std::string Name; public:
VariableExprAST(const std::string &Name) : Name(Name) {} Value *codegen() override; };
ೋ߲ԋࢉࢠ class BinaryExprAST : public ExprAST { char Op; std::unique_ptr<ExprAST>
LHS, RHS; public: BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS, std::unique_ptr<ExprAST> RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} Value *codegen() override; };
ؔએݴ class PrototypeAST { std::string Name; std::vector<std::string> Args; public: PrototypeAST(const
std::string &Name, std::vector<std::string> Args) : Name(Name), Args(std::move(Args)) {} Function *codegen(); const std::string &getName() const { return Name; } };
࣮ؔ class FunctionAST { std::unique_ptr<PrototypeAST> Proto; std::unique_ptr<ExprAST> Body; public: FunctionAST(std::unique_ptr<PrototypeAST>
Proto, std::unique_ptr<ExprAST> Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} Function *codegen(); };
நߏจ def hoge(a b c) a+(b+c); FunctionAST Proto PrototypeAST Body
BinaryExprAST - + LHS VariableExprAST - a RHS BinaryExprAST - + LHS VariableExprAST - b RHS VariableExprAST - c ԋࢉࢠͷ༏ઌʹج͖ͮɼਂ͞༏ઌͰߏจΛ࡞͍ͬͯ͘
நߏจ def hoge(a b c) a+b+c; FunctionAST Proto PrototypeAST Body
BinaryExprAST - + LHS VariableExprAST - c RHS BinaryExprAST - + LHS VariableExprAST - a RHS VariableExprAST - b ԋࢉࢠͷ༏ઌʹج͖ͮɼਂ͞༏ઌͰߏจΛ࡞͍ͬͯ͘
LLVM IRΛੜ͢Δ class ExprAST { public: virtual ~ExprAST() = default;
virtual Value *codegen() = 0; }; ֤ϊʔυ͔ΒLLVM IRΛੜ͢Δ ߏจͷϊʔυ͝ͱʹੜͷͨΊͷίʔυΛ࣮͍ͯ͘͠
codegenͷࣄ • llvm::ValueΫϥεΛฦ͢ • ͜ͷΫϥε͕LLVM IRΛు͍ͯ͘ΕΔ • llvm::Value • ੩త୯ҰೖϨδελΛࣔ͢
if (auto *FnIR = ProtoAST->codegen()) { fprintf(stderr, "Read extern: "); FnIR->print(errs()); fprintf(stderr, "\n"); }
ೋ߲ԋࢉࢠͷ߹ Value *BinaryExprAST::codegen() { Value *L = LHS->codegen(); Value *R
= RHS->codegen(); if (!L || !R) return nullptr; switch (Op) { case '+': return Builder.CreateFAdd(L, R, "addtmp"); case '-': return Builder.CreateFSub(L, R, "subtmp"); case '*': return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); return Builder.CreateUIToFP( L, Type::getDoubleTy(TheContext), "booltmp"); default: return LogErrorV("invalid binary operator"); } } ܭࢉ݁ՌΛอଘ͢ΔϨδελ໊
ؔએݴ Function *PrototypeAST::codegen() { std::vector<Type *> Doubles( Args.size(), Type::getDoubleTy(TheContext) );
FunctionType *FT = FunctionType::get( Type::getDoubleTy(TheContext), Doubles, false ); Function *F = Function::Create( FT, Function::ExternalLinkage, Name, TheModule.get() ); // Set names for all arguments. unsigned Idx = 0; for (auto &Arg : F->args()) Arg.setName(Args[Idx++]); return F; }
࣮ؔ Function *FunctionAST::codegen() { Function *TheFunction = TheModule->getFunction( Proto->getName()); if
(!TheFunction) TheFunction = Proto->codegen(); if (!TheFunction) return nullptr; // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create( TheContext, "entry", TheFunction); Builder.SetInsertPoint(BB);
࣮ؔ // Record the function arguments in the NamedValues map.
NamedValues.clear(); for (auto &Arg : TheFunction->args()) NamedValues[Arg.getName()] = &Arg; if (Value *RetVal = Body->codegen()) { // Finish off the function. Builder.CreateRet(RetVal); // Validate the generated code, checking for consistency. verifyFunction(*TheFunction); return TheFunction; } // Error reading body, remove function. TheFunction->eraseFromParent(); return nullptr; }
நߏจ͔ΒLLVM IRΛ࡞Δ def hoge(a b c) a+b+c; FunctionAST Proto PrototypeAST
Body BinaryExprAST - + LHS VariableExprAST - c RHS BinaryExprAST - + LHS VariableExprAST - a RHS VariableExprAST - b
codegen def hoge(a b c) a+b+c; FunctionAST Proto PrototypeAST Body
BinaryExprAST - + LHS VariableExprAST - c RHS BinaryExprAST - + LHS VariableExprAST - a RHS VariableExprAST - b BEEUNQGBEEEPVCMFB C
codegen def hoge(a b c) a+b+c; FunctionAST Proto PrototypeAST Body
BinaryExprAST - + LHS VariableExprAST - c RHS BinaryExprAST - + LHS VariableExprAST - a RHS VariableExprAST - b BEEUNQGBEEEPVCMFB C BEEUNQGBEEEPVCMFBEEUNQ D
codegen def hoge(a b c) a+b+c; FunctionAST Proto PrototypeAST Body
BinaryExprAST - + LHS VariableExprAST - c RHS BinaryExprAST - + LHS VariableExprAST - a RHS VariableExprAST - b EFpOFEPVCMF!IPHF EPVCMFB EPVCMFC EPVCMFD \ FOUSZ BEEUNQGBEEEPVCMFB C BEEUNQGBEEEPVCMFBEEUNQ D SFUEPVCMFBEEUNQ ^
·ͱΊ • LLVMʹ͍ͭͯ • എܠɼྺ࢙ɼԠ༻ • LLVM Tutorial • நߏจ
• LLVM IRͷੜ • ͔͜͜Β͕͓͠Ζ͍ • PassʹΑΔ࠷దԽ • ੍ޚϑϩʔͷ࣮ • mutableมͷಋೖ
ଓ͘