Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
LLVM Tutorial 02 - わいわいswiftc
Search
sonson
March 01, 2019
Programming
1
370
LLVM Tutorial 02 - わいわいswiftc
LLVMチュートリアルをやってみよう.
今回は第3章くらいまでです.
sonson
March 01, 2019
Tweet
Share
More Decks by sonson
See All by sonson
計算グラフのJITコンパイラをLLVM on C++で作ろう
sonsongithub
2
550
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.3k
LLVM Tutorial - わいわいswiftc
sonsongithub
0
290
How to make and publish a Swift playground book for iPad
sonsongithub
5
19k
Swiftで実装するHTML特殊文字の高速処理
sonsongithub
3
7.6k
First step of 3D touch
sonsongithub
0
590
Getting started with 3D Touch
sonsongithub
0
680
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
520
Other Decks in Programming
See All in Programming
命名をリントする
chiroruxx
1
390
ブラウザ単体でmp4書き出すまで - muddy-web - 2024-12
yue4u
2
460
Mermaid x AST x 生成AI = コードとドキュメントの完全同期への道
shibuyamizuho
0
160
今からはじめるAndroidアプリ開発 2024 / DevFest 2024
star_zero
0
1k
複雑な仕様に立ち向かうアーキテクチャ
myohei
0
170
ゆるやかにgolangci-lintのルールを強くする / Kyoto.go #56
utgwkk
1
360
LLM Supervised Fine-tuningの理論と実践
datanalyticslabo
3
1k
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
700
HTTP compression in PHP and Symfony apps
dunglas
2
1.7k
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
250
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
コンテナをたくさん詰め込んだシステムとランタイムの変化
makihiro
1
120
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1030
460k
Automating Front-end Workflow
addyosmani
1366
200k
Agile that works and the tools we love
rasmusluckow
328
21k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
How STYLIGHT went responsive
nonsquared
95
5.2k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.4k
It's Worth the Effort
3n
183
28k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
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มͷಋೖ
ଓ͘