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
410
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
580
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.4k
LLVM Tutorial - わいわいswiftc
sonsongithub
0
320
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
630
Getting started with 3D Touch
sonsongithub
0
720
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
550
Other Decks in Programming
See All in Programming
git worktree × Claude Code × MCP ~生成AI時代の並列開発フロー~
hisuzuya
0
280
Using AI Tools Around Software Development
inouehi
0
1.2k
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
250
都市をデータで見るってこういうこと PLATEAU属性情報入門
nokonoko1203
1
560
生成AIで日々のエラー調査を進めたい
yuyaabo
0
630
既存デザインを変更せずにタップ領域を広げる方法
tahia910
1
240
Java on Azure で LangGraph!
kohei3110
0
170
AWS CDKの推しポイント 〜CloudFormationと比較してみた〜
akihisaikeda
3
300
「Cursor/Devin全社導入の理想と現実」のその後
saitoryc
0
120
DroidKnights 2025 - 다양한 스크롤 뷰에서의 영상 재생
gaeun5744
3
300
第9回 情シス転職ミートアップ 株式会社IVRy(アイブリー)の紹介
ivry_presentationmaterials
1
210
社内での開発コミュニティ活動とモジュラーモノリス標準化事例のご紹介/xPalette and Introduction of Modular monolith standardization
m4maruyama
1
130
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
134
9.3k
Become a Pro
speakerdeck
PRO
28
5.4k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.8k
The Pragmatic Product Professional
lauravandoore
35
6.7k
Embracing the Ebb and Flow
colly
86
4.7k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
GraphQLとの向き合い方2022年版
quramy
46
14k
What's in a price? How to price your products and services
michaelherold
246
12k
4 Signs Your Business is Dying
shpigford
184
22k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.3k
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มͷಋೖ
ଓ͘