$30 off During Our Annual Pro Sale. View Details »

LLVM Tutorial - わいわいswiftc

sonson
December 17, 2018

LLVM Tutorial - わいわいswiftc

LLVM Tutorialについて発表しました.
公開しようと思っている翻訳メモはこちら.
https://github.com/sonsongithub/llvm-tutorial

sonson

December 17, 2018
Tweet

More Decks by sonson

Other Decks in Programming

Transcript

  1. 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

    View Slide

  2. https://peaks.cc/books/iOS12

    View Slide

  3. https://peaks.cc/books/iOS12

    View Slide

  4. ͳͥɼLLVMʁ
    • ੈͷதͷྲྀΕ
    • ϜʔΞͷ๏ଇͷݶք
    • CPUͷྔతਐԽ͸ɼݶքʹ͍͍ۙͮͯΔʢ෺ཧతʣ
    • ճආ͢Δʹ͸ʁ
    • ฒྻԽ
    • CPU͸ສೳ͗͢ΔˠGPU, FPGA, ASIC
    • ͲΕ΋։ൃ͕ࠓ·Ͱͷͱҧ͍͗ͯ͢ࠔ೉ۃ·Δ
    ιϑτ΢ΣΞͷ։ൃํ๏͕৭ʑࢼ͞Ε͍ͯΔ

    View Slide

  5. ͜͜਺೥ͷ࿩
    • 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͕ग़ͯ͘Δ

    View Slide

  6. ͜ͷลͷ࿩͸ੲͬͪ͜Ͱൃද
    https://tech.d-itlab.co.jp/programming/567/

    View Slide

  7. LLVM Tutorialͱ͸ʁ
    • Tutorials about using LLVM. Includes a tutorial about
    making a custom language with LLVM.

    View Slide

  8. LLVM Tutorial
    • LLVMΛ࢖ͬͯΦϨΦϨݴޠͷίϯύΠϥΛ࡞Δ
    • C++ͰllvmΛϥΠϒϥϦͱͯ͠ɼίϯύΠϥΛ։ൃ
    • ಡΉͷʹඞཁͳεΩϧ
    • C++
    • ӳޠ
    • ͳΜ͔brokenͩͬͨΓɼ͚ͩͨ͘ײ͡

    View Slide

  9. ϝϞॻ͖ͳͲ
    • https://github.com/sonsongithub/llvm-tutorial
    • LLVM Release Licenseʹج͖ͮɼ຋༁ϝϞ౳Λެ։ͯ͠
    ͍·͢

    View Slide

  10. ࣮૷
    • llvmͷΫϥεΛ࢖͍ίϯύΠϥΛ࡞Δ
    • C++ͰllvmͷΫϥεΛੜ੒͠ɼͦ͜ͰͳΜͧ΍Δ
    • ࠷ऴతʹ׬੒ͨ͠όΠφϦʹιʔείʔυΛ৯ΘͤΔ
    • ݁Ռɼղੳ݁Ռɼதؒίʔυɼߏจ໦Β͕ಘΒΕΔ

    View Slide

  11. ίϯύΠϧ؀ڥ
    • ίϚϯυͷྫ
    • llvm-configͳͲXcodeʹؚ·Εͳ͍πʔϧ͕͋Δ
    • macOSͷ৔߹
    • brew install llvmͰΠϯετʔϧ͓ͯ͘͠
    • Mojave͸/usr/include͕ͳ͍ͷͰखಈͰɾɾɾɾ
    • ࢲ͸ϋϚͬͨɾɾɾɾɾ
    • ”Xcode 10 Release Notes”
    • ؀ڥม਺ͷ੾Γସ͑Λ๨Εͣʹ
    clang++ --std=c++14 ./toy.cpp `llvm-config --cxxflags --ldflags --libs --libfiles —system-libs`

    View Slide

  12. ։ൃ͢ΔݴޠKaleidoscope
    • ໨ඪͱ࢓༷
    • doubleܕͷΈ
    • ؔ਺͕࢖͑Δ
    • Standard libraryͷؔ਺Λ࢖͑Δ
    • if/elseจ
    • forจ
    • Ϣʔβఆٛԋࢉࢠ
    • REPL/JIT

    View Slide

  13. αϯϓϧ
    # Compute the x'th fibonacci number.
    def fib(x)
    if x < 3 then
    1
    else
    fib(x-1)+fib(x-2)
    # This expression will compute the 40th number.
    fib(40)
    # load standard library
    extern sin(arg);
    extern cos(arg);
    extern atan2(arg1, arg2);
    # call atan2
    atan2(sin(.4), cos(42))

    View Slide

  14. ྲྀΕ
    • ιʔείʔυΛτʔΫϯʹ෼ׂ͢Δ
    • τʔΫϯ͔Βߏจ໦Λ࡞Δ
    • ߏจ໦ͷϊʔυΛLLVM IRʹม׵͢Δ
    • LLVM IRΛόΠφϦʹ͢Δ

    View Slide

  15. େલఏ

    View Slide

  16. νϡʔτϦΞϧͷιʔείʔυ͕͍͚ͯͳ͍

    View Slide

  17. άϩʔόϧม਺ͩΒ͚ɾɾɾ
    ͍͋ͬͪͬͨΓɼ͍ͬͪͬͨ͜Γɾɾɾɾɾɾ

    View Slide

  18. The error recovery in our parser will not be the best
    and is not particular user-friendly, but it will be
    enough for our tutorial.
    Note that instead of adding virtual methods to the
    ExprAST class hierarchy, it could also make sense to
    use a visitor pattern or some other way to model
    this. Again, this tutorial won’t dwell on good
    software engineering practices: for our purposes,
    adding a virtual method is simplest.

    View Slide

  19. ࠷ॳͷҰาʙޠኮղੳ(Lexer)
    • ·ͣιʔείʔυΛݻ·Γʹ෼ׂ͍ͯ͘͠
    extern cos(0.1);
    ֎෦એݴ
    tok_extern
    Կ͔ͷࣝผࢠ
    tok_identifier
    ਺஋τʔΫϯ
    tok_number
    Χοίͱηϛίϩϯ͸ޠኮʹ౰ͨΒͳ͍ͷͰɼ
    ͱΓ͋͑ͣඈ͹͢

    View Slide

  20. Lexer
    • ந৅ߏจ໦ͱݺ͹ΕΔ໦ߏ଄Λ࡞Δ

    View Slide

  21. ͋ͱ͸ɾɾɾɾ
    • ΧοίΛਂ͞༏ઌͰॲཧ
    • ೋ߲ԋࢉࢠΛ༏ઌॱҐΛ͚ͭͯɼਂ͞༏ઌͰॲཧ
    • ɾɾɾ͏Μ͵Μ΍Δͱɼந৅ߏจ໦͕׬੒

    View Slide

  22. ߏจ໦ͷϊʔυΫϥε
    /// ExprAST - Base class for all expression nodes.
    class ExprAST {
    public:
    virtual ~ExprAST() {}
    };
    /// NumberExprAST - Expression class for numeric literals like
    "1.0".
    class NumberExprAST : public ExprAST {
    double Val;
    public:
    NumberExprAST(double Val) : Val(Val) {}
    };
    ਺஋Λอଘ͢Δϊʔυ

    View Slide

  23. ม਺ͱೋ߲ԋࢉࢠ
    /// VariableExprAST - ม਺Λอଘ͢ΔͨΊͷཁૉ
    class VariableExprAST : public ExprAST {
    std::string Name;
    public:
    VariableExprAST(const std::string &Name) : Name(Name) {}
    };
    /// BinaryExprAST - +ͱ͔ͷԋࢉࢠΛอଘ͢ΔͨΊͷཁૉʁ
    class BinaryExprAST : public ExprAST {
    char Op;
    std::unique_ptr LHS, RHS;
    public:
    BinaryExprAST(char op, std::unique_ptr LHS,
    std::unique_ptr RHS)
    : Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
    };
    +ͱ͔-Έ͍ͨͳԋࢉࢠͱ͔

    View Slide

  24. ؔ਺ݺͼग़͠ͷͨΊͷϊʔυ
    /// CallExprAST - ؔ਺ݺͼग़͠ͱҾ਺Λอଘ͢ΔͨΊͷ໦
    class CallExprAST : public ExprAST {
    std::string Callee;
    std::vector> Args;
    public:
    CallExprAST(const std::string &Callee,
    std::vector> Args)
    : Callee(Callee), Args(std::move(Args)) {}
    };
    ؔ਺ݺͼग़͠ͷϊʔυɽ͔͜͜Βؔ਺ϙΠϯλΛݺͿʁ

    View Slide

  25. ؔ਺ͷϓϩτλΠϓએݴ
    /// PrototypeAST - This class represents the "prototype" for a
    function,
    /// which captures its name, and its argument names (thus
    implicitly the number
    /// of arguments the function takes).
    class PrototypeAST {
    std::string Name;
    std::vector Args;
    public:
    PrototypeAST(const std::string &name, std::vector
    Args)
    : Name(name), Args(std::move(Args)) {}
    const std::string &getName() const { return Name; }
    };
    ؔ਺ͷ໊લɼҾ਺ͷ໊લͷϦετ͕ϓϩύςΟɽ
    ʢී௨͸ܕͷϦετͷ΋ඞཁʣ

    View Slide

  26. ؔ਺ͷϓϩτλΠϓએݴ
    /// FunctionAST - This class represents a function definition
    itself.
    class FunctionAST {
    std::unique_ptr Proto;
    std::unique_ptr Body;
    public:
    FunctionAST(std::unique_ptr Proto,
    std::unique_ptr Body)
    : Proto(std::move(Proto)), Body(std::move(Body)) {}
    };
    ؔ਺ͷ࣮૷ɽ
    ϓϩτλΠϓ΁ͷϙΠϯλͱؔ਺ͷ࣮૷ຊମ΁ͷϙΠϯλ

    View Slide

  27. ந৅ߏจ໦ͷϊʔυ͕ἧ͏
    • ExprAST
    • NumberExprAST
    • VariableExprAST
    • BinaryExprAST
    • CallExprAST
    • PrototypeAST
    • FunctionAST

    View Slide

  28. ιʔε͔Βؤுͬͯ໦Λ࡞͍ͬͯ͘
    /// numberexpr ::= number
    static std::unique_ptr ParseNumberExpr() {
    auto Result = llvm::make_unique(NumVal);
    getNextToken(); // consume the number
    return std::move(Result);
    }
    NumVal͕άϩʔόϧม਺ͰɼgetNextToken()Ͱ
    άϩʔόϧม਺ʹ࣍ͷτʔΫϯΛಡΈࠐΉ
    ͭ·ΓɼԚ͍

    View Slide

  29. ιʔε͔Βؤுͬͯ໦Λ࡞͍ͬͯ͘
    auto LHS = llvm::make_unique("x");
    auto RHS = llvm::make_unique("y");
    auto Result = std::make_unique('+', std::move(LHS),
    std::move(RHS));

    View Slide

  30. codegenͷͨΊͷΦϒδΣΫτ
    • static LLVMContext TheContext;
    • γϯάϧτϯʁσʔλ΍ܕ͕͢΂ͯอଘ͢ΔΦϒδΣ
    Ϋτɽ
    • static IRBuilder<> Builder(TheContext);
    • llvmͷIRΛੜ੒͢ΔͨΊͷΦϒδΣΫτɽ
    • static std::unique_ptr TheModule;
    • ͍ΘΏΔϞδϡʔϧɽ͜͜ʹάϩʔόϧม਺͕อଘ
    ͞ΕΔɽ͜ͷΦϒΤδΣΫτʹ͢΂ͯͷσʔλ͕อ
    ଘ͞Εɼ͋ΒΏΔ΋ͷ͸͜͜΁ͷϙΠϯλ
    • static std::map NamedValues;
    • ม਺໊ʁͷ௥੻ʹ࢖͏ϚοϓͬΆ͍ɽ

    View Slide

  31. LLVM IRΛੜ੒͢Δ
    • ͖͞΄ͲͷϊʔυʹcodegenΛੜ΍͢
    /// ExprAST - Base class for all expression nodes.
    class ExprAST {
    public:
    virtual ~ExprAST() {}
    virtual Value *codegen() = 0;
    };
    /// NumberExprAST - Expression class for numeric literals like
    "1.0".
    class NumberExprAST : public ExprAST {
    double Val;
    public:
    NumberExprAST(double Val) : Val(Val) {}
    virtual Value *codegen();
    };
    ValueɾɾɾStatic Single Assignment RegisterΛࣔ͢ม਺

    View Slide

  32. ೋ߲ԋࢉࢠͷ৔߹
    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");
    // Convert bool 0/1 to double 0.0 or 1.0
    return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext),
    "booltmp");
    default:
    return LogErrorV("invalid binary operator");
    }
    }

    View Slide

  33. ଓ͘

    View Slide