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
430
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
590
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.5k
LLVM Tutorial - わいわいswiftc
sonsongithub
0
330
How to make and publish a Swift playground book for iPad
sonsongithub
5
19k
Swiftで実装するHTML特殊文字の高速処理
sonsongithub
3
7.8k
First step of 3D touch
sonsongithub
0
650
Getting started with 3D Touch
sonsongithub
0
740
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
570
Other Decks in Programming
See All in Programming
Чего вы не знали о строках в Python – Василий Рябов, PythoNN
sobolevn
0
150
実践AIチャットボットUI実装入門
syumai
7
2.4k
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
150
AI Coding Meetup #3 - 導入セッション / ai-coding-meetup-3
izumin5210
0
290
複雑化したリポジトリをなんとかした話 pipenvからuvによるモノレポ構成への移行
satoshi256kbyte
1
720
iOS 17で追加されたSubscriptionStoreView を利用して5分でサブスク実装チャレンジ
natmark
0
480
ててべんす独演会〜Flowの全てを語ります〜
tbsten
1
220
Advance Your Career with Open Source
ivargrimstad
0
260
NetworkXとGNNで学ぶグラフデータ分析入門〜複雑な関係性を解き明かすPythonの力〜
mhrtech
3
950
defer f()とdefer fの挙動を 誤解していた話
kogamochiduki
2
160
CSS Linter の現在地 2025年のベストプラクティスを探る
ryo_manba
10
3.2k
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
160
Featured
See All Featured
Testing 201, or: Great Expectations
jmmastey
45
7.7k
The Straight Up "How To Draw Better" Workshop
denniskardys
237
140k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
20k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.1k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
4 Signs Your Business is Dying
shpigford
185
22k
Code Reviewing Like a Champion
maltzj
525
40k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
840
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
2.6k
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มͷಋೖ
ଓ͘