diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /examples | |
parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) | |
download | src-test2-dd58ef019b700900793a1eb48b52123db01b654e.tar.gz src-test2-dd58ef019b700900793a1eb48b52123db01b654e.zip |
Notes
Diffstat (limited to 'examples')
27 files changed, 2558 insertions, 2613 deletions
diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp index 8026adc8d075..d8c54b50b854 100644 --- a/examples/BrainF/BrainF.cpp +++ b/examples/BrainF/BrainF.cpp @@ -29,6 +29,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include <iostream> + using namespace llvm; //Set the constants for naming @@ -44,7 +45,7 @@ Module *BrainF::parse(std::istream *in1, int mem, CompileFlags cf, comflag = cf; header(Context); - readloop(0, 0, 0, Context); + readloop(nullptr, nullptr, nullptr, Context); delete builder; return module; } @@ -68,7 +69,6 @@ void BrainF::header(LLVMContext& C) { getOrInsertFunction("putchar", IntegerType::getInt32Ty(C), IntegerType::getInt32Ty(C), NULL)); - //Function header //define void @brainf() @@ -85,7 +85,7 @@ void BrainF::header(LLVMContext& C) { Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty); allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy); ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem, - NULL, "arr"); + nullptr, "arr"); BB->getInstList().push_back(cast<Instruction>(ptr_arr)); //call void @llvm.memset.p0i8.i32(i8 *%arr, i8 0, i32 %d, i32 1, i1 0) @@ -114,8 +114,6 @@ void BrainF::header(LLVMContext& C) { ConstantInt::get(C, APInt(32, memtotal/2)), headreg); - - //Function footer //brainf.end: @@ -127,8 +125,6 @@ void BrainF::header(LLVMContext& C) { //ret void ReturnInst::Create(C, endbb); - - //Error block for array out of bounds if (comflag & flag_arraybounds) { diff --git a/examples/BrainF/BrainFDriver.cpp b/examples/BrainF/BrainFDriver.cpp index 99c8ff36dc61..1a38c67b0d4a 100644 --- a/examples/BrainF/BrainFDriver.cpp +++ b/examples/BrainF/BrainFDriver.cpp @@ -64,9 +64,9 @@ void addMainFunction(Module *mod) { IntegerType::getInt8Ty(mod->getContext()))), NULL)); { Function::arg_iterator args = main_func->arg_begin(); - Value *arg_0 = args++; + Value *arg_0 = &*args++; arg_0->setName("argc"); - Value *arg_1 = args++; + Value *arg_1 = &*args++; arg_1->setName("argv"); } diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f98c403deb0b..5727066d6227 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -4,7 +4,7 @@ add_subdirectory(HowToUseJIT) add_subdirectory(Kaleidoscope) add_subdirectory(ModuleMaker) -if( ( NOT WIN32 ) AND ( NOT "${LLVM_NATIVE_ARCH}" STREQUAL "ARM" ) ) +if(LLVM_ENABLE_EH AND (NOT WIN32) AND (NOT "${LLVM_NATIVE_ARCH}" STREQUAL "ARM")) add_subdirectory(ExceptionDemo) endif() diff --git a/examples/ExceptionDemo/CMakeLists.txt b/examples/ExceptionDemo/CMakeLists.txt index b4354f66f0d6..793cf291ca6f 100644 --- a/examples/ExceptionDemo/CMakeLists.txt +++ b/examples/ExceptionDemo/CMakeLists.txt @@ -5,14 +5,14 @@ set(LLVM_LINK_COMPONENTS MCJIT RuntimeDyld Support + Target nativecodegen ) # Enable EH and RTTI for this demo -set(LLVM_REQUIRES_EH 1) -set(LLVM_REQUIRES_RTTI 1) - -set(LLVM_BUILD_EXAMPLES OFF) +if(NOT LLVM_ENABLE_EH) + message(FATAL_ERROR "ExceptionDemo must require EH.") +endif() add_llvm_example(ExceptionDemo ExceptionDemo.cpp diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index 81337c4823b0..444ee2649fa7 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -77,6 +77,7 @@ #include <sstream> #include <stdexcept> +#include <inttypes.h> #ifndef USE_GLOBAL_STR_CONSTS #define USE_GLOBAL_STR_CONSTS true @@ -319,7 +320,7 @@ void printStr(char *toPrint) { } -/// Deletes the true previosly allocated exception whose address +/// Deletes the true previously allocated exception whose address /// is calculated from the supplied OurBaseException_t::unwindException /// member address. Handles (ignores), NULL pointers. /// @param expToDelete exception to delete @@ -569,8 +570,8 @@ static bool handleActionValue(int64_t *resultAction, fprintf(stderr, "handleActionValue(...): exceptionObject = <%p>, " "excp = <%p>.\n", - exceptionObject, - excp); + (void*)exceptionObject, + (void*)excp); #endif const uint8_t *actionPos = (uint8_t*) actionEntry, @@ -588,8 +589,8 @@ static bool handleActionValue(int64_t *resultAction, #ifdef DEBUG fprintf(stderr, - "handleActionValue(...):typeOffset: <%lld>, " - "actionOffset: <%lld>.\n", + "handleActionValue(...):typeOffset: <%" PRIi64 ">, " + "actionOffset: <%" PRIi64 ">.\n", typeOffset, actionOffset); #endif @@ -848,7 +849,7 @@ _Unwind_Reason_Code ourPersonality(int version, #ifdef DEBUG fprintf(stderr, "ourPersonality(...):lsda = <%p>.\n", - lsda); + (void*)lsda); #endif // The real work of the personality function is captured here @@ -971,7 +972,7 @@ void generateIntegerPrint(llvm::LLVMContext &context, llvm::Value *cast = builder.CreateBitCast(stringVar, builder.getInt8PtrTy()); - builder.CreateCall2(&printFunct, &toPrint, cast); + builder.CreateCall(&printFunct, {&toPrint, cast}); } @@ -1264,10 +1265,10 @@ static llvm::Function *createCatchWrappedInvokeFunction( builder.SetInsertPoint(exceptionBlock); llvm::Function *personality = module.getFunction("ourPersonality"); + ret->setPersonalityFn(personality); llvm::LandingPadInst *caughtResult = builder.CreateLandingPad(ourCaughtResultType, - personality, numExceptionsToCatch, "landingPad"); @@ -1694,7 +1695,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, #ifdef DEBUG fprintf(stderr, "createStandardUtilityFunctions(...):ourBaseFromUnwindOffset " - "= %lld, sizeof(struct OurBaseException_t) - " + "= %" PRIi64 ", sizeof(struct OurBaseException_t) - " "sizeof(struct _Unwind_Exception) = %lu.\n", ourBaseFromUnwindOffset, sizeof(struct OurBaseException_t) - @@ -1973,7 +1974,7 @@ int main(int argc, char *argv[]) { // Set up the optimizer pipeline. // Start with registering info about how the // target lays out data structures. - module->setDataLayout(*executionEngine->getDataLayout()); + module->setDataLayout(executionEngine->getDataLayout()); // Optimizations turned on #ifdef ADD_OPT_PASSES diff --git a/examples/Fibonacci/fibonacci.cpp b/examples/Fibonacci/fibonacci.cpp index 8092e19380dd..ecb49eb92e1a 100644 --- a/examples/Fibonacci/fibonacci.cpp +++ b/examples/Fibonacci/fibonacci.cpp @@ -33,6 +33,7 @@ #include "llvm/IR/Module.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; static Function *CreateFibFunction(Module *M, LLVMContext &Context) { @@ -41,7 +42,7 @@ static Function *CreateFibFunction(Module *M, LLVMContext &Context) { Function *FibF = cast<Function>(M->getOrInsertFunction("fib", Type::getInt32Ty(Context), Type::getInt32Ty(Context), - (Type *)0)); + nullptr)); // Add a basic block to the function. BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FibF); @@ -51,7 +52,7 @@ static Function *CreateFibFunction(Module *M, LLVMContext &Context) { Value *Two = ConstantInt::get(Type::getInt32Ty(Context), 2); // Get pointer to the integer argument of the add1 function... - Argument *ArgX = FibF->arg_begin(); // Get the arg. + Argument *ArgX = &*FibF->arg_begin(); // Get the arg. ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. // Create the true_block. @@ -87,7 +88,6 @@ static Function *CreateFibFunction(Module *M, LLVMContext &Context) { return FibF; } - int main(int argc, char **argv) { int n = argc > 1 ? atol(argv[1]) : 24; @@ -106,7 +106,6 @@ int main(int argc, char **argv) { ExecutionEngine *EE = EngineBuilder(std::move(Owner)) .setErrorStr(&errStr) - .setEngineKind(EngineKind::JIT) .create(); if (!EE) { diff --git a/examples/HowToUseJIT/HowToUseJIT.cpp b/examples/HowToUseJIT/HowToUseJIT.cpp index 91ea17dd22bf..e0bf6a00bf01 100644 --- a/examples/HowToUseJIT/HowToUseJIT.cpp +++ b/examples/HowToUseJIT/HowToUseJIT.cpp @@ -65,7 +65,7 @@ int main() { Function *Add1F = cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context), Type::getInt32Ty(Context), - (Type *)0)); + nullptr)); // Add a basic block to the function. As before, it automatically inserts // because of the last argument. @@ -80,7 +80,7 @@ int main() { // Get pointers to the integer argument of the add1 function... assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg - Argument *ArgX = Add1F->arg_begin(); // Get the arg + Argument *ArgX = &*Add1F->arg_begin(); // Get the arg ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. // Create the add instruction, inserting it into the end of BB. @@ -91,12 +91,11 @@ int main() { // Now, function add1 is ready. - // Now we're going to create function `foo', which returns an int and takes no // arguments. Function *FooF = cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context), - (Type *)0)); + nullptr)); // Add a basic block to the FooF function. BB = BasicBlock::Create(Context, "EntryBlock", FooF); diff --git a/examples/Kaleidoscope/Chapter2/CMakeLists.txt b/examples/Kaleidoscope/Chapter2/CMakeLists.txt index fed3f4b78c77..6224d9ac8640 100644 --- a/examples/Kaleidoscope/Chapter2/CMakeLists.txt +++ b/examples/Kaleidoscope/Chapter2/CMakeLists.txt @@ -1,3 +1,9 @@ add_kaleidoscope_chapter(Kaleidoscope-Ch2 toy.cpp ) + +if(LLVM_COMPILER_IS_GCC_COMPATIBLE) + target_compile_options(Kaleidoscope-Ch2 PRIVATE + -Wno-unused-private-field + ) +endif() diff --git a/examples/Kaleidoscope/Chapter2/Makefile b/examples/Kaleidoscope/Chapter2/Makefile index 1a9b94ce541e..fa27e6e06687 100644 --- a/examples/Kaleidoscope/Chapter2/Makefile +++ b/examples/Kaleidoscope/Chapter2/Makefile @@ -10,4 +10,6 @@ LEVEL = ../../.. TOOLNAME = Kaleidoscope-Ch2 EXAMPLE_TOOL = 1 +LLVM_CXXFLAGS := -Wno-unused-private-field + include $(LEVEL)/Makefile.common diff --git a/examples/Kaleidoscope/Chapter2/toy.cpp b/examples/Kaleidoscope/Chapter2/toy.cpp index cd901394a524..69f359961293 100644 --- a/examples/Kaleidoscope/Chapter2/toy.cpp +++ b/examples/Kaleidoscope/Chapter2/toy.cpp @@ -1,10 +1,22 @@ #include <cctype> #include <cstdio> -#include <cstdlib> #include <map> +#include <memory> #include <string> #include <vector> +namespace helper { +// Cloning make_unique here until it's standard in C++14. +// Using a namespace to avoid conflicting with MSVC's std::make_unique (which +// ADL can sometimes find in unqualified calls). +template <class T, class... Args> +static + typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type + make_unique(Args &&... args) { + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +} +} + //===----------------------------------------------------------------------===// // Lexer //===----------------------------------------------------------------------===// @@ -15,14 +27,16 @@ enum Token { tok_eof = -1, // commands - tok_def = -2, tok_extern = -3, + tok_def = -2, + tok_extern = -3, // primary - tok_identifier = -4, tok_number = -5 + tok_identifier = -4, + tok_number = -5 }; -static std::string IdentifierStr; // Filled in if tok_identifier -static double NumVal; // Filled in if tok_number +static std::string IdentifierStr; // Filled in if tok_identifier +static double NumVal; // Filled in if tok_number /// gettok - Return the next token from standard input. static int gettok() { @@ -37,31 +51,34 @@ static int gettok() { while (isalnum((LastChar = getchar()))) IdentifierStr += LastChar; - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; + if (IdentifierStr == "def") + return tok_def; + if (IdentifierStr == "extern") + return tok_extern; return tok_identifier; } - if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ + if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ std::string NumStr; do { NumStr += LastChar; LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } if (LastChar == '#') { // Comment until end of line. - do LastChar = getchar(); + do + LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -84,30 +101,40 @@ public: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { + double Val; + public: - NumberExprAST(double val) {} + NumberExprAST(double Val) : Val(Val) {} }; /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: - VariableExprAST(const std::string &name) : Name(name) {} + VariableExprAST(const std::string &Name) : Name(Name) {} }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { + char Op; + std::unique_ptr<ExprAST> LHS, RHS; + public: - BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) {} + BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS, + std::unique_ptr<ExprAST> RHS) + : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; - std::vector<ExprAST*> Args; + std::vector<std::unique_ptr<ExprAST>> Args; + public: - CallExprAST(const std::string &callee, std::vector<ExprAST*> &args) - : Callee(callee), Args(args) {} + CallExprAST(const std::string &Callee, + std::vector<std::unique_ptr<ExprAST>> Args) + : Callee(Callee), Args(std::move(Args)) {} }; /// PrototypeAST - This class represents the "prototype" for a function, @@ -116,16 +143,21 @@ public: class PrototypeAST { std::string Name; std::vector<std::string> Args; + public: - PrototypeAST(const std::string &name, const std::vector<std::string> &args) - : Name(name), Args(args) {} - + PrototypeAST(const std::string &Name, std::vector<std::string> Args) + : Name(Name), Args(std::move(Args)) {} }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { + std::unique_ptr<PrototypeAST> Proto; + std::unique_ptr<ExprAST> Body; + public: - FunctionAST(PrototypeAST *proto, ExprAST *body) {} + FunctionAST(std::unique_ptr<PrototypeAST> Proto, + std::unique_ptr<ExprAST> Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} }; } // end anonymous namespace @@ -137,9 +169,7 @@ public: /// token the parser is looking at. getNextToken reads another token from the /// lexer and updates CurTok with its results. static int CurTok; -static int getNextToken() { - return CurTok = gettok(); -} +static int getNextToken() { return CurTok = gettok(); } /// BinopPrecedence - This holds the precedence for each binary operator that is /// defined. @@ -149,40 +179,69 @@ static std::map<char, int> BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; - if (TokPrec <= 0) return -1; + if (TokPrec <= 0) + return -1; return TokPrec; } /// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} -PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } +std::unique_ptr<ExprAST> Error(const char *Str) { + fprintf(stderr, "Error: %s\n", Str); + return nullptr; +} +std::unique_ptr<PrototypeAST> ErrorP(const char *Str) { + Error(Str); + return nullptr; +} + +static std::unique_ptr<ExprAST> ParseExpression(); -static ExprAST *ParseExpression(); +/// numberexpr ::= number +static std::unique_ptr<ExprAST> ParseNumberExpr() { + auto Result = helper::make_unique<NumberExprAST>(NumVal); + getNextToken(); // consume the number + return std::move(Result); +} + +/// parenexpr ::= '(' expression ')' +static std::unique_ptr<ExprAST> ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { +static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; - - getNextToken(); // eat identifier. - + + getNextToken(); // eat identifier. + if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); - + return helper::make_unique<VariableExprAST>(IdName); + // Call. - getNextToken(); // eat ( - std::vector<ExprAST*> Args; + getNextToken(); // eat ( + std::vector<std::unique_ptr<ExprAST>> Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) return 0; - Args.push_back(Arg); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; - if (CurTok == ')') break; + if (CurTok == ')') + break; if (CurTok != ',') return Error("Expected ')' or ',' in argument list"); @@ -192,133 +251,125 @@ static ExprAST *ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - - return new CallExprAST(IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; + return helper::make_unique<CallExprAST>(IdName, std::move(Args)); } /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr -static ExprAST *ParsePrimary() { +static std::unique_ptr<ExprAST> ParsePrimary() { switch (CurTok) { - default: return Error("unknown token when expecting an expression"); - case tok_identifier: return ParseIdentifierExpr(); - case tok_number: return ParseNumberExpr(); - case '(': return ParseParenExpr(); + default: + return Error("unknown token when expecting an expression"); + case tok_identifier: + return ParseIdentifierExpr(); + case tok_number: + return ParseNumberExpr(); + case '(': + return ParseParenExpr(); } } /// binoprhs /// ::= ('+' primary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { +static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, + std::unique_ptr<ExprAST> LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; - getNextToken(); // eat binop - + getNextToken(); // eat binop + // Parse the primary expression after the binary operator. - ExprAST *RHS = ParsePrimary(); - if (!RHS) return 0; - + auto RHS = ParsePrimary(); + if (!RHS) + return nullptr; + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec+1, RHS); - if (RHS == 0) return 0; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } - + // Merge LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS); + LHS = helper::make_unique<BinaryExprAST>(BinOp, std::move(LHS), + std::move(RHS)); } } /// expression /// ::= primary binoprhs /// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParsePrimary(); - if (!LHS) return 0; - - return ParseBinOpRHS(0, LHS); +static std::unique_ptr<ExprAST> ParseExpression() { + auto LHS = ParsePrimary(); + if (!LHS) + return nullptr; + + return ParseBinOpRHS(0, std::move(LHS)); } /// prototype /// ::= id '(' id* ')' -static PrototypeAST *ParsePrototype() { +static std::unique_ptr<PrototypeAST> ParsePrototype() { if (CurTok != tok_identifier) return ErrorP("Expected function name in prototype"); std::string FnName = IdentifierStr; getNextToken(); - + if (CurTok != '(') return ErrorP("Expected '(' in prototype"); - + std::vector<std::string> ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorP("Expected ')' in prototype"); - + // success. - getNextToken(); // eat ')'. - - return new PrototypeAST(FnName, ArgNames); + getNextToken(); // eat ')'. + + return helper::make_unique<PrototypeAST>(FnName, std::move(ArgNames)); } /// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { - getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) return 0; - - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; +static std::unique_ptr<FunctionAST> ParseDefinition() { + getNextToken(); // eat def. + auto Proto = ParsePrototype(); + if (!Proto) + return nullptr; + + if (auto E = ParseExpression()) + return helper::make_unique<FunctionAST>(std::move(Proto), std::move(E)); + return nullptr; } /// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { - if (ExprAST *E = ParseExpression()) { +static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { + if (auto E = ParseExpression()) { // Make an anonymous proto. - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); - return new FunctionAST(Proto, E); + auto Proto = helper::make_unique<PrototypeAST>("__anon_expr", + std::vector<std::string>()); + return helper::make_unique<FunctionAST>(std::move(Proto), std::move(E)); } - return 0; + return nullptr; } /// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { - getNextToken(); // eat extern. +static std::unique_ptr<PrototypeAST> ParseExtern() { + getNextToken(); // eat extern. return ParsePrototype(); } @@ -359,11 +410,20 @@ static void MainLoop() { while (1) { fprintf(stderr, "ready> "); switch (CurTok) { - case tok_eof: return; - case ';': getNextToken(); break; // ignore top-level semicolons. - case tok_def: HandleDefinition(); break; - case tok_extern: HandleExtern(); break; - default: HandleTopLevelExpression(); break; + case tok_eof: + return; + case ';': // ignore top-level semicolons. + getNextToken(); + break; + case tok_def: + HandleDefinition(); + break; + case tok_extern: + HandleExtern(); + break; + default: + HandleTopLevelExpression(); + break; } } } @@ -378,7 +438,7 @@ int main() { BinopPrecedence['<'] = 10; BinopPrecedence['+'] = 20; BinopPrecedence['-'] = 20; - BinopPrecedence['*'] = 40; // highest. + BinopPrecedence['*'] = 40; // highest. // Prime the first token. fprintf(stderr, "ready> "); diff --git a/examples/Kaleidoscope/Chapter3/toy.cpp b/examples/Kaleidoscope/Chapter3/toy.cpp index c60f76725fdb..05697ea70a49 100644 --- a/examples/Kaleidoscope/Chapter3/toy.cpp +++ b/examples/Kaleidoscope/Chapter3/toy.cpp @@ -1,13 +1,14 @@ -#include "llvm/IR/Verifier.h" -#include "llvm/IR/DerivedTypes.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" #include <cctype> #include <cstdio> #include <map> #include <string> #include <vector> + using namespace llvm; //===----------------------------------------------------------------------===// @@ -20,14 +21,16 @@ enum Token { tok_eof = -1, // commands - tok_def = -2, tok_extern = -3, + tok_def = -2, + tok_extern = -3, // primary - tok_identifier = -4, tok_number = -5 + tok_identifier = -4, + tok_number = -5 }; -static std::string IdentifierStr; // Filled in if tok_identifier -static double NumVal; // Filled in if tok_number +static std::string IdentifierStr; // Filled in if tok_identifier +static double NumVal; // Filled in if tok_number /// gettok - Return the next token from standard input. static int gettok() { @@ -42,31 +45,34 @@ static int gettok() { while (isalnum((LastChar = getchar()))) IdentifierStr += LastChar; - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; + if (IdentifierStr == "def") + return tok_def; + if (IdentifierStr == "extern") + return tok_extern; return tok_identifier; } - if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ + if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ std::string NumStr; do { NumStr += LastChar; LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } if (LastChar == '#') { // Comment until end of line. - do LastChar = getchar(); + do + LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -85,43 +91,49 @@ namespace { class ExprAST { public: virtual ~ExprAST() {} - virtual Value *Codegen() = 0; + 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) {} - Value *Codegen() override; + NumberExprAST(double Val) : Val(Val) {} + Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: - VariableExprAST(const std::string &name) : Name(name) {} - Value *Codegen() override; + VariableExprAST(const std::string &Name) : Name(Name) {} + Value *codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { char Op; - ExprAST *LHS, *RHS; + std::unique_ptr<ExprAST> LHS, RHS; + public: - BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) - : Op(op), LHS(lhs), RHS(rhs) {} - Value *Codegen() override; + 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; }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; - std::vector<ExprAST*> Args; + std::vector<std::unique_ptr<ExprAST>> Args; + public: - CallExprAST(const std::string &callee, std::vector<ExprAST*> &args) - : Callee(callee), Args(args) {} - Value *Codegen() override; + CallExprAST(const std::string &Callee, + std::vector<std::unique_ptr<ExprAST>> Args) + : Callee(Callee), Args(std::move(Args)) {} + Value *codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, @@ -130,22 +142,24 @@ public: class PrototypeAST { std::string Name; std::vector<std::string> Args; + public: - PrototypeAST(const std::string &name, const std::vector<std::string> &args) - : Name(name), Args(args) {} - - Function *Codegen(); + 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; } }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { - PrototypeAST *Proto; - ExprAST *Body; + std::unique_ptr<PrototypeAST> Proto; + std::unique_ptr<ExprAST> Body; + public: - FunctionAST(PrototypeAST *proto, ExprAST *body) - : Proto(proto), Body(body) {} - - Function *Codegen(); + FunctionAST(std::unique_ptr<PrototypeAST> Proto, + std::unique_ptr<ExprAST> Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} + Function *codegen(); }; } // end anonymous namespace @@ -157,9 +171,7 @@ public: /// token the parser is looking at. getNextToken reads another token from the /// lexer and updates CurTok with its results. static int CurTok; -static int getNextToken() { - return CurTok = gettok(); -} +static int getNextToken() { return CurTok = gettok(); } /// BinopPrecedence - This holds the precedence for each binary operator that is /// defined. @@ -169,41 +181,70 @@ static std::map<char, int> BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; - if (TokPrec <= 0) return -1; + if (TokPrec <= 0) + return -1; return TokPrec; } /// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} -PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } -FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; } +std::unique_ptr<ExprAST> Error(const char *Str) { + fprintf(stderr, "Error: %s\n", Str); + return nullptr; +} + +std::unique_ptr<PrototypeAST> ErrorP(const char *Str) { + Error(Str); + return nullptr; +} + +static std::unique_ptr<ExprAST> ParseExpression(); + +/// numberexpr ::= number +static std::unique_ptr<ExprAST> ParseNumberExpr() { + auto Result = llvm::make_unique<NumberExprAST>(NumVal); + getNextToken(); // consume the number + return std::move(Result); +} -static ExprAST *ParseExpression(); +/// parenexpr ::= '(' expression ')' +static std::unique_ptr<ExprAST> ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { +static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; - - getNextToken(); // eat identifier. - + + getNextToken(); // eat identifier. + if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); - + return llvm::make_unique<VariableExprAST>(IdName); + // Call. - getNextToken(); // eat ( - std::vector<ExprAST*> Args; + getNextToken(); // eat ( + std::vector<std::unique_ptr<ExprAST>> Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) return 0; - Args.push_back(Arg); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; - if (CurTok == ')') break; + if (CurTok == ')') + break; if (CurTok != ',') return Error("Expected ')' or ',' in argument list"); @@ -213,133 +254,125 @@ static ExprAST *ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - - return new CallExprAST(IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr -static ExprAST *ParsePrimary() { +static std::unique_ptr<ExprAST> ParsePrimary() { switch (CurTok) { - default: return Error("unknown token when expecting an expression"); - case tok_identifier: return ParseIdentifierExpr(); - case tok_number: return ParseNumberExpr(); - case '(': return ParseParenExpr(); + default: + return Error("unknown token when expecting an expression"); + case tok_identifier: + return ParseIdentifierExpr(); + case tok_number: + return ParseNumberExpr(); + case '(': + return ParseParenExpr(); } } /// binoprhs /// ::= ('+' primary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { +static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, + std::unique_ptr<ExprAST> LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; - getNextToken(); // eat binop - + getNextToken(); // eat binop + // Parse the primary expression after the binary operator. - ExprAST *RHS = ParsePrimary(); - if (!RHS) return 0; - + auto RHS = ParsePrimary(); + if (!RHS) + return nullptr; + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec+1, RHS); - if (RHS == 0) return 0; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } - + // Merge LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS); + LHS = + llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } } /// expression /// ::= primary binoprhs /// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParsePrimary(); - if (!LHS) return 0; - - return ParseBinOpRHS(0, LHS); +static std::unique_ptr<ExprAST> ParseExpression() { + auto LHS = ParsePrimary(); + if (!LHS) + return nullptr; + + return ParseBinOpRHS(0, std::move(LHS)); } /// prototype /// ::= id '(' id* ')' -static PrototypeAST *ParsePrototype() { +static std::unique_ptr<PrototypeAST> ParsePrototype() { if (CurTok != tok_identifier) return ErrorP("Expected function name in prototype"); std::string FnName = IdentifierStr; getNextToken(); - + if (CurTok != '(') return ErrorP("Expected '(' in prototype"); - + std::vector<std::string> ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorP("Expected ')' in prototype"); - + // success. - getNextToken(); // eat ')'. - - return new PrototypeAST(FnName, ArgNames); + getNextToken(); // eat ')'. + + return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames)); } /// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { - getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) return 0; - - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; +static std::unique_ptr<FunctionAST> ParseDefinition() { + getNextToken(); // eat def. + auto Proto = ParsePrototype(); + if (!Proto) + return nullptr; + + if (auto E = ParseExpression()) + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); + return nullptr; } /// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { - if (ExprAST *E = ParseExpression()) { +static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { + if (auto E = ParseExpression()) { // Make an anonymous proto. - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); - return new FunctionAST(Proto, E); + auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr", + std::vector<std::string>()); + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); } - return 0; + return nullptr; } /// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { - getNextToken(); // eat extern. +static std::unique_ptr<PrototypeAST> ParseExtern() { + getNextToken(); // eat extern. return ParsePrototype(); } @@ -347,113 +380,108 @@ static PrototypeAST *ParseExtern() { // Code Generation //===----------------------------------------------------------------------===// -static Module *TheModule; +static std::unique_ptr<Module> TheModule; static IRBuilder<> Builder(getGlobalContext()); -static std::map<std::string, Value*> NamedValues; +static std::map<std::string, Value *> NamedValues; -Value *ErrorV(const char *Str) { Error(Str); return 0; } +Value *ErrorV(const char *Str) { + Error(Str); + return nullptr; +} -Value *NumberExprAST::Codegen() { +Value *NumberExprAST::codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); } -Value *VariableExprAST::Codegen() { +Value *VariableExprAST::codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - return V ? V : ErrorV("Unknown variable name"); + if (!V) + return ErrorV("Unknown variable name"); + return V; } -Value *BinaryExprAST::Codegen() { - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); - if (L == 0 || R == 0) return 0; - +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 '+': + 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(getGlobalContext()), "booltmp"); - default: return ErrorV("invalid binary operator"); + default: + return ErrorV("invalid binary operator"); } } -Value *CallExprAST::Codegen() { +Value *CallExprAST::codegen() { // Look up the name in the global module table. Function *CalleeF = TheModule->getFunction(Callee); - if (CalleeF == 0) + if (!CalleeF) return ErrorV("Unknown function referenced"); - + // If argument mismatch error. if (CalleeF->arg_size() != Args.size()) return ErrorV("Incorrect # arguments passed"); - std::vector<Value*> ArgsV; + std::vector<Value *> ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) return 0; + ArgsV.push_back(Args[i]->codegen()); + if (!ArgsV.back()) + return nullptr; } - + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } -Function *PrototypeAST::Codegen() { +Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. - std::vector<Type*> Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); - FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), - Doubles, false); - - Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); - - // If F conflicted, there was already something named 'Name'. If it has a - // body, don't allow redefinition or reextern. - if (F->getName() != Name) { - // Delete the one we just made and get the existing one. - F->eraseFromParent(); - F = TheModule->getFunction(Name); - - // If F already has a body, reject this. - if (!F->empty()) { - ErrorF("redefinition of function"); - return 0; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return 0; - } - } - + std::vector<Type *> Doubles(Args.size(), + Type::getDoubleTy(getGlobalContext())); + FunctionType *FT = + FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); + + Function *F = + Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get()); + // Set names for all arguments. unsigned Idx = 0; - for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); - ++AI, ++Idx) { - AI->setName(Args[Idx]); - - // Add arguments to variable symbol table. - NamedValues[Args[Idx]] = AI; - } - + for (auto &Arg : F->args()) + Arg.setName(Args[Idx++]); + return F; } -Function *FunctionAST::Codegen() { - NamedValues.clear(); - - Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; - +Function *FunctionAST::codegen() { + // First, check for an existing function from a previous 'extern' declaration. + 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(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); - - if (Value *RetVal = Body->Codegen()) { + + // 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); @@ -462,10 +490,10 @@ Function *FunctionAST::Codegen() { return TheFunction; } - + // Error reading body, remove function. TheFunction->eraseFromParent(); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// @@ -473,10 +501,10 @@ Function *FunctionAST::Codegen() { //===----------------------------------------------------------------------===// static void HandleDefinition() { - if (FunctionAST *F = ParseDefinition()) { - if (Function *LF = F->Codegen()) { + if (auto FnAST = ParseDefinition()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read function definition:"); - LF->dump(); + FnIR->dump(); } } else { // Skip token for error recovery. @@ -485,10 +513,10 @@ static void HandleDefinition() { } static void HandleExtern() { - if (PrototypeAST *P = ParseExtern()) { - if (Function *F = P->Codegen()) { + if (auto ProtoAST = ParseExtern()) { + if (auto *FnIR = ProtoAST->codegen()) { fprintf(stderr, "Read extern: "); - F->dump(); + FnIR->dump(); } } else { // Skip token for error recovery. @@ -498,10 +526,10 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - if (Function *LF = F->Codegen()) { + if (auto FnAST = ParseTopLevelExpr()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read top-level expression:"); - LF->dump(); + FnIR->dump(); } } else { // Skip token for error recovery. @@ -514,46 +542,42 @@ static void MainLoop() { while (1) { fprintf(stderr, "ready> "); switch (CurTok) { - case tok_eof: return; - case ';': getNextToken(); break; // ignore top-level semicolons. - case tok_def: HandleDefinition(); break; - case tok_extern: HandleExtern(); break; - default: HandleTopLevelExpression(); break; + case tok_eof: + return; + case ';': // ignore top-level semicolons. + getNextToken(); + break; + case tok_def: + HandleDefinition(); + break; + case tok_extern: + HandleExtern(); + break; + default: + HandleTopLevelExpression(); + break; } } } //===----------------------------------------------------------------------===// -// "Library" functions that can be "extern'd" from user code. -//===----------------------------------------------------------------------===// - -/// putchard - putchar that takes a double and returns 0. -extern "C" -double putchard(double X) { - putchar((char)X); - return 0; -} - -//===----------------------------------------------------------------------===// // Main driver code. //===----------------------------------------------------------------------===// int main() { - LLVMContext &Context = getGlobalContext(); - // Install standard binary operators. // 1 is lowest precedence. BinopPrecedence['<'] = 10; BinopPrecedence['+'] = 20; BinopPrecedence['-'] = 20; - BinopPrecedence['*'] = 40; // highest. + BinopPrecedence['*'] = 40; // highest. // Prime the first token. fprintf(stderr, "ready> "); getNextToken(); // Make the module, which holds all the code. - TheModule = new Module("my cool jit", Context); + TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext()); // Run the main "interpreter loop" now. MainLoop(); diff --git a/examples/Kaleidoscope/Chapter4/CMakeLists.txt b/examples/Kaleidoscope/Chapter4/CMakeLists.txt index 2c01e120070a..89feed143adc 100644 --- a/examples/Kaleidoscope/Chapter4/CMakeLists.txt +++ b/examples/Kaleidoscope/Chapter4/CMakeLists.txt @@ -3,14 +3,15 @@ set(LLVM_LINK_COMPONENTS Core ExecutionEngine InstCombine - MCJIT + Object RuntimeDyld ScalarOpts Support - TransformUtils native ) add_kaleidoscope_chapter(Kaleidoscope-Ch4 toy.cpp ) + +export_executable_symbols(Kaleidoscope-Ch4) diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp index ad091e4496b7..4f77ec862b1b 100644 --- a/examples/Kaleidoscope/Chapter4/toy.cpp +++ b/examples/Kaleidoscope/Chapter4/toy.cpp @@ -1,9 +1,5 @@ +#include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/Passes.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/MCJIT.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" @@ -16,7 +12,10 @@ #include <map> #include <string> #include <vector> +#include "../include/KaleidoscopeJIT.h" + using namespace llvm; +using namespace llvm::orc; //===----------------------------------------------------------------------===// // Lexer @@ -66,7 +65,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -98,7 +97,7 @@ namespace { class ExprAST { public: virtual ~ExprAST() {} - virtual Value *Codegen() = 0; + virtual Value *codegen() = 0; }; /// NumberExprAST - Expression class for numeric literals like "1.0". @@ -106,8 +105,8 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} - Value *Codegen() override; + NumberExprAST(double Val) : Val(Val) {} + Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". @@ -115,30 +114,32 @@ class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(const std::string &name) : Name(name) {} - Value *Codegen() override; + VariableExprAST(const std::string &Name) : Name(Name) {} + Value *codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { char Op; - ExprAST *LHS, *RHS; + std::unique_ptr<ExprAST> LHS, RHS; public: - BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) - : Op(op), LHS(lhs), RHS(rhs) {} - Value *Codegen() override; + 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; }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; public: - CallExprAST(const std::string &callee, std::vector<ExprAST *> &args) - : Callee(callee), Args(args) {} - Value *Codegen() override; + CallExprAST(const std::string &Callee, + std::vector<std::unique_ptr<ExprAST>> Args) + : Callee(Callee), Args(std::move(Args)) {} + Value *codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, @@ -149,21 +150,22 @@ class PrototypeAST { std::vector<std::string> Args; public: - PrototypeAST(const std::string &name, const std::vector<std::string> &args) - : Name(name), Args(args) {} - - Function *Codegen(); + 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; } }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { - PrototypeAST *Proto; - ExprAST *Body; + std::unique_ptr<PrototypeAST> Proto; + std::unique_ptr<ExprAST> Body; public: - FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} - - Function *Codegen(); + FunctionAST(std::unique_ptr<PrototypeAST> Proto, + std::unique_ptr<ExprAST> Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} + Function *codegen(); }; } // end anonymous namespace @@ -194,41 +196,58 @@ static int GetTokPrecedence() { } /// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { +std::unique_ptr<ExprAST> Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str); - return 0; + return nullptr; } -PrototypeAST *ErrorP(const char *Str) { + +std::unique_ptr<PrototypeAST> ErrorP(const char *Str) { Error(Str); - return 0; + return nullptr; } -FunctionAST *ErrorF(const char *Str) { - Error(Str); - return 0; + +static std::unique_ptr<ExprAST> ParseExpression(); + +/// numberexpr ::= number +static std::unique_ptr<ExprAST> ParseNumberExpr() { + auto Result = llvm::make_unique<NumberExprAST>(NumVal); + getNextToken(); // consume the number + return std::move(Result); } -static ExprAST *ParseExpression(); +/// parenexpr ::= '(' expression ')' +static std::unique_ptr<ExprAST> ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { +static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; getNextToken(); // eat identifier. if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); + return llvm::make_unique<VariableExprAST>(IdName); // Call. getNextToken(); // eat ( - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) - return 0; - Args.push_back(Arg); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; if (CurTok == ')') break; @@ -242,34 +261,14 @@ static ExprAST *ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - return new CallExprAST(IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} - -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) - return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr -static ExprAST *ParsePrimary() { +static std::unique_ptr<ExprAST> ParsePrimary() { switch (CurTok) { default: return Error("unknown token when expecting an expression"); @@ -284,7 +283,8 @@ static ExprAST *ParsePrimary() { /// binoprhs /// ::= ('+' primary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { +static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, + std::unique_ptr<ExprAST> LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -299,38 +299,39 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { getNextToken(); // eat binop // Parse the primary expression after the binary operator. - ExprAST *RHS = ParsePrimary(); + auto RHS = ParsePrimary(); if (!RHS) - return 0; + return nullptr; // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec + 1, RHS); - if (RHS == 0) - return 0; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } // Merge LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS); + LHS = + llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } } /// expression /// ::= primary binoprhs /// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParsePrimary(); +static std::unique_ptr<ExprAST> ParseExpression() { + auto LHS = ParsePrimary(); if (!LHS) - return 0; + return nullptr; - return ParseBinOpRHS(0, LHS); + return ParseBinOpRHS(0, std::move(LHS)); } /// prototype /// ::= id '(' id* ')' -static PrototypeAST *ParsePrototype() { +static std::unique_ptr<PrototypeAST> ParsePrototype() { if (CurTok != tok_identifier) return ErrorP("Expected function name in prototype"); @@ -349,300 +350,86 @@ static PrototypeAST *ParsePrototype() { // success. getNextToken(); // eat ')'. - return new PrototypeAST(FnName, ArgNames); + return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames)); } /// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { +static std::unique_ptr<FunctionAST> ParseDefinition() { getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) - return 0; + auto Proto = ParsePrototype(); + if (!Proto) + return nullptr; - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; + if (auto E = ParseExpression()) + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); + return nullptr; } /// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { - if (ExprAST *E = ParseExpression()) { +static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { + if (auto E = ParseExpression()) { // Make an anonymous proto. - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); - return new FunctionAST(Proto, E); + auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr", + std::vector<std::string>()); + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); } - return 0; + return nullptr; } /// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { +static std::unique_ptr<PrototypeAST> ParseExtern() { getNextToken(); // eat extern. return ParsePrototype(); } //===----------------------------------------------------------------------===// -// Quick and dirty hack -//===----------------------------------------------------------------------===// - -// FIXME: Obviously we can do better than this -std::string GenerateUniqueName(const char *root) { - static int i = 0; - char s[16]; - sprintf(s, "%s%d", root, i++); - std::string S = s; - return S; -} - -std::string MakeLegalFunctionName(std::string Name) { - std::string NewName; - if (!Name.length()) - return GenerateUniqueName("anon_func_"); - - // Start with what we have - NewName = Name; - - // Look for a numberic first character - if (NewName.find_first_of("0123456789") == 0) { - NewName.insert(0, 1, 'n'); - } - - // Replace illegal characters with their ASCII equivalent - std::string legal_elements = - "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - size_t pos; - while ((pos = NewName.find_first_not_of(legal_elements)) != - std::string::npos) { - char old_c = NewName.at(pos); - char new_str[16]; - sprintf(new_str, "%d", (int)old_c); - NewName = NewName.replace(pos, 1, new_str); - } - - return NewName; -} - -//===----------------------------------------------------------------------===// -// MCJIT helper class -//===----------------------------------------------------------------------===// - -class MCJITHelper { -public: - MCJITHelper(LLVMContext &C) : Context(C), OpenModule(NULL) {} - ~MCJITHelper(); - - Function *getFunction(const std::string FnName); - Module *getModuleForNewFunction(); - void *getPointerToFunction(Function *F); - void *getSymbolAddress(const std::string &Name); - void dump(); - -private: - typedef std::vector<Module *> ModuleVector; - typedef std::vector<ExecutionEngine *> EngineVector; - - LLVMContext &Context; - Module *OpenModule; - ModuleVector Modules; - EngineVector Engines; -}; - -class HelpingMemoryManager : public SectionMemoryManager { - HelpingMemoryManager(const HelpingMemoryManager &) = delete; - void operator=(const HelpingMemoryManager &) = delete; - -public: - HelpingMemoryManager(MCJITHelper *Helper) : MasterHelper(Helper) {} - ~HelpingMemoryManager() override {} - - /// This method returns the address of the specified symbol. - /// Our implementation will attempt to find symbols in other - /// modules associated with the MCJITHelper to cross link symbols - /// from one generated module to another. - uint64_t getSymbolAddress(const std::string &Name) override; - -private: - MCJITHelper *MasterHelper; -}; - -uint64_t HelpingMemoryManager::getSymbolAddress(const std::string &Name) { - uint64_t FnAddr = SectionMemoryManager::getSymbolAddress(Name); - if (FnAddr) - return FnAddr; - - uint64_t HelperFun = (uint64_t)MasterHelper->getSymbolAddress(Name); - if (!HelperFun) - report_fatal_error("Program used extern function '" + Name + - "' which could not be resolved!"); - - return HelperFun; -} - -MCJITHelper::~MCJITHelper() { - if (OpenModule) - delete OpenModule; - EngineVector::iterator begin = Engines.begin(); - EngineVector::iterator end = Engines.end(); - EngineVector::iterator it; - for (it = begin; it != end; ++it) - delete *it; -} - -Function *MCJITHelper::getFunction(const std::string FnName) { - ModuleVector::iterator begin = Modules.begin(); - ModuleVector::iterator end = Modules.end(); - ModuleVector::iterator it; - for (it = begin; it != end; ++it) { - Function *F = (*it)->getFunction(FnName); - if (F) { - if (*it == OpenModule) - return F; - - assert(OpenModule != NULL); - - // This function is in a module that has already been JITed. - // We need to generate a new prototype for external linkage. - Function *PF = OpenModule->getFunction(FnName); - if (PF && !PF->empty()) { - ErrorF("redefinition of function across modules"); - return 0; - } - - // If we don't have a prototype yet, create one. - if (!PF) - PF = Function::Create(F->getFunctionType(), Function::ExternalLinkage, - FnName, OpenModule); - return PF; - } - } - return NULL; -} - -Module *MCJITHelper::getModuleForNewFunction() { - // If we have a Module that hasn't been JITed, use that. - if (OpenModule) - return OpenModule; - - // Otherwise create a new Module. - std::string ModName = GenerateUniqueName("mcjit_module_"); - Module *M = new Module(ModName, Context); - Modules.push_back(M); - OpenModule = M; - return M; -} - -void *MCJITHelper::getPointerToFunction(Function *F) { - // See if an existing instance of MCJIT has this function. - EngineVector::iterator begin = Engines.begin(); - EngineVector::iterator end = Engines.end(); - EngineVector::iterator it; - for (it = begin; it != end; ++it) { - void *P = (*it)->getPointerToFunction(F); - if (P) - return P; - } - - // If we didn't find the function, see if we can generate it. - if (OpenModule) { - std::string ErrStr; - ExecutionEngine *NewEngine = - EngineBuilder(std::unique_ptr<Module>(OpenModule)) - .setErrorStr(&ErrStr) - .setMCJITMemoryManager(std::unique_ptr<HelpingMemoryManager>( - new HelpingMemoryManager(this))) - .create(); - if (!NewEngine) { - fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); - exit(1); - } - - // Create a function pass manager for this engine - auto *FPM = new legacy::FunctionPassManager(OpenModule); - - // Set up the optimizer pipeline. Start with registering info about how the - // target lays out data structures. - OpenModule->setDataLayout(*NewEngine->getDataLayout()); - // Provide basic AliasAnalysis support for GVN. - FPM->add(createBasicAliasAnalysisPass()); - // Promote allocas to registers. - FPM->add(createPromoteMemoryToRegisterPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - FPM->add(createInstructionCombiningPass()); - // Reassociate expressions. - FPM->add(createReassociatePass()); - // Eliminate Common SubExpressions. - FPM->add(createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - FPM->add(createCFGSimplificationPass()); - FPM->doInitialization(); - - // For each function in the module - Module::iterator it; - Module::iterator end = OpenModule->end(); - for (it = OpenModule->begin(); it != end; ++it) { - // Run the FPM on this function - FPM->run(*it); - } - - // We don't need this anymore - delete FPM; - - OpenModule = NULL; - Engines.push_back(NewEngine); - NewEngine->finalizeObject(); - return NewEngine->getPointerToFunction(F); - } - return NULL; -} - -void *MCJITHelper::getSymbolAddress(const std::string &Name) { - // Look for the symbol in each of our execution engines. - EngineVector::iterator begin = Engines.begin(); - EngineVector::iterator end = Engines.end(); - EngineVector::iterator it; - for (it = begin; it != end; ++it) { - uint64_t FAddr = (*it)->getFunctionAddress(Name); - if (FAddr) { - return (void *)FAddr; - } - } - return NULL; -} - -void MCJITHelper::dump() { - ModuleVector::iterator begin = Modules.begin(); - ModuleVector::iterator end = Modules.end(); - ModuleVector::iterator it; - for (it = begin; it != end; ++it) - (*it)->dump(); -} -//===----------------------------------------------------------------------===// // Code Generation //===----------------------------------------------------------------------===// -static MCJITHelper *JITHelper; +static std::unique_ptr<Module> TheModule; static IRBuilder<> Builder(getGlobalContext()); static std::map<std::string, Value *> NamedValues; +static std::unique_ptr<legacy::FunctionPassManager> TheFPM; +static std::unique_ptr<KaleidoscopeJIT> TheJIT; +static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos; Value *ErrorV(const char *Str) { Error(Str); - return 0; + return nullptr; +} + +Function *getFunction(std::string Name) { + // First, see if the function has already been added to the current module. + if (auto *F = TheModule->getFunction(Name)) + return F; + + // If not, check whether we can codegen the declaration from some existing + // prototype. + auto FI = FunctionProtos.find(Name); + if (FI != FunctionProtos.end()) + return FI->second->codegen(); + + // If no existing prototype exists, return null. + return nullptr; } -Value *NumberExprAST::Codegen() { +Value *NumberExprAST::codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); } -Value *VariableExprAST::Codegen() { +Value *VariableExprAST::codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - return V ? V : ErrorV("Unknown variable name"); + if (!V) + return ErrorV("Unknown variable name"); + return V; } -Value *BinaryExprAST::Codegen() { - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); - if (L == 0 || R == 0) - return 0; +Value *BinaryExprAST::codegen() { + Value *L = LHS->codegen(); + Value *R = RHS->codegen(); + if (!L || !R) + return nullptr; switch (Op) { case '+': @@ -661,10 +448,10 @@ Value *BinaryExprAST::Codegen() { } } -Value *CallExprAST::Codegen() { +Value *CallExprAST::codegen() { // Look up the name in the global module table. - Function *CalleeF = JITHelper->getFunction(Callee); - if (CalleeF == 0) + Function *CalleeF = getFunction(Callee); + if (!CalleeF) return ErrorV("Unknown function referenced"); // If argument mismatch error. @@ -673,94 +460,99 @@ Value *CallExprAST::Codegen() { std::vector<Value *> ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) - return 0; + ArgsV.push_back(Args[i]->codegen()); + if (!ArgsV.back()) + return nullptr; } return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } -Function *PrototypeAST::Codegen() { +Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); - std::string FnName = MakeLegalFunctionName(Name); - - Module *M = JITHelper->getModuleForNewFunction(); - - Function *F = Function::Create(FT, Function::ExternalLinkage, FnName, M); - - // If F conflicted, there was already something named 'Name'. If it has a - // body, don't allow redefinition or reextern. - if (F->getName() != FnName) { - // Delete the one we just made and get the existing one. - F->eraseFromParent(); - F = JITHelper->getFunction(Name); - // If F already has a body, reject this. - if (!F->empty()) { - ErrorF("redefinition of function"); - return 0; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return 0; - } - } + Function *F = + Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get()); // Set names for all arguments. unsigned Idx = 0; - for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); - ++AI, ++Idx) { - AI->setName(Args[Idx]); - - // Add arguments to variable symbol table. - NamedValues[Args[Idx]] = AI; - } + for (auto &Arg : F->args()) + Arg.setName(Args[Idx++]); return F; } -Function *FunctionAST::Codegen() { - NamedValues.clear(); - - Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; +Function *FunctionAST::codegen() { + // Transfer ownership of the prototype to the FunctionProtos map, but keep a + // reference to it for use below. + auto &P = *Proto; + FunctionProtos[Proto->getName()] = std::move(Proto); + Function *TheFunction = getFunction(P.getName()); + if (!TheFunction) + return nullptr; // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); - if (Value *RetVal = Body->Codegen()) { + // 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); + // Run the optimizer on the function. + TheFPM->run(*TheFunction); + return TheFunction; } // Error reading body, remove function. TheFunction->eraseFromParent(); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// // Top-Level parsing and JIT Driver //===----------------------------------------------------------------------===// +static void InitializeModuleAndPassManager() { + // Open a new module. + TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext()); + TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout()); + + // Create a new pass manager attached to it. + TheFPM = llvm::make_unique<legacy::FunctionPassManager>(TheModule.get()); + + // Do simple "peephole" optimizations and bit-twiddling optzns. + TheFPM->add(createInstructionCombiningPass()); + // Reassociate expressions. + TheFPM->add(createReassociatePass()); + // Eliminate Common SubExpressions. + TheFPM->add(createGVNPass()); + // Simplify the control flow graph (deleting unreachable blocks, etc). + TheFPM->add(createCFGSimplificationPass()); + + TheFPM->doInitialization(); +} + static void HandleDefinition() { - if (FunctionAST *F = ParseDefinition()) { - if (Function *LF = F->Codegen()) { + if (auto FnAST = ParseDefinition()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read function definition:"); - LF->dump(); + FnIR->dump(); + TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); } } else { // Skip token for error recovery. @@ -769,10 +561,11 @@ static void HandleDefinition() { } static void HandleExtern() { - if (PrototypeAST *P = ParseExtern()) { - if (Function *F = P->Codegen()) { + if (auto ProtoAST = ParseExtern()) { + if (auto *FnIR = ProtoAST->codegen()) { fprintf(stderr, "Read extern: "); - F->dump(); + FnIR->dump(); + FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST); } } else { // Skip token for error recovery. @@ -782,15 +575,25 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - if (Function *LF = F->Codegen()) { - // JIT the function, returning a function pointer. - void *FPtr = JITHelper->getPointerToFunction(LF); - - // Cast it to the right type (takes no arguments, returns a double) so we - // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)FPtr; + if (auto FnAST = ParseTopLevelExpr()) { + if (FnAST->codegen()) { + + // JIT the module containing the anonymous expression, keeping a handle so + // we can free it later. + auto H = TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); + + // Search the JIT for the __anon_expr symbol. + auto ExprSymbol = TheJIT->findSymbol("__anon_expr"); + assert(ExprSymbol && "Function not found"); + + // Get the symbol's address and cast it to the right type (takes no + // arguments, returns a double) so we can call it as a native function. + double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); fprintf(stderr, "Evaluated to %f\n", FP()); + + // Delete the anonymous expression module from the JIT. + TheJIT->removeModule(H); } } else { // Skip token for error recovery. @@ -805,9 +608,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -827,7 +630,13 @@ static void MainLoop() { /// putchard - putchar that takes a double and returns 0. extern "C" double putchard(double X) { - putchar((char)X); + fputc((char)X, stderr); + return 0; +} + +/// printd - printf that takes a double prints it as "%f\n", returning 0. +extern "C" double printd(double X) { + fprintf(stderr, "%f\n", X); return 0; } @@ -839,8 +648,6 @@ int main() { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); - LLVMContext &Context = getGlobalContext(); - JITHelper = new MCJITHelper(Context); // Install standard binary operators. // 1 is lowest precedence. @@ -853,11 +660,12 @@ int main() { fprintf(stderr, "ready> "); getNextToken(); + TheJIT = llvm::make_unique<KaleidoscopeJIT>(); + + InitializeModuleAndPassManager(); + // Run the main "interpreter loop" now. MainLoop(); - // Print out all of the generated code. - JITHelper->dump(); - return 0; } diff --git a/examples/Kaleidoscope/Chapter5/CMakeLists.txt b/examples/Kaleidoscope/Chapter5/CMakeLists.txt index a938d9731fe8..c0ae70654c36 100644 --- a/examples/Kaleidoscope/Chapter5/CMakeLists.txt +++ b/examples/Kaleidoscope/Chapter5/CMakeLists.txt @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS Core ExecutionEngine InstCombine - MCJIT + Object RuntimeDyld ScalarOpts Support @@ -13,3 +13,5 @@ set(LLVM_LINK_COMPONENTS add_kaleidoscope_chapter(Kaleidoscope-Ch5 toy.cpp ) + +export_executable_symbols(Kaleidoscope-Ch5) diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp index db9904895739..eeca4775eeb1 100644 --- a/examples/Kaleidoscope/Chapter5/toy.cpp +++ b/examples/Kaleidoscope/Chapter5/toy.cpp @@ -1,10 +1,5 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/Passes.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/MCJIT.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" @@ -17,7 +12,10 @@ #include <map> #include <string> #include <vector> +#include "../include/KaleidoscopeJIT.h" + using namespace llvm; +using namespace llvm::orc; //===----------------------------------------------------------------------===// // Lexer @@ -84,7 +82,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -116,7 +114,7 @@ namespace { class ExprAST { public: virtual ~ExprAST() {} - virtual Value *Codegen() = 0; + virtual Value *codegen() = 0; }; /// NumberExprAST - Expression class for numeric literals like "1.0". @@ -124,8 +122,8 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} - Value *Codegen() override; + NumberExprAST(double Val) : Val(Val) {} + Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". @@ -133,52 +131,57 @@ class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(const std::string &name) : Name(name) {} - Value *Codegen() override; + VariableExprAST(const std::string &Name) : Name(Name) {} + Value *codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { char Op; - ExprAST *LHS, *RHS; + std::unique_ptr<ExprAST> LHS, RHS; public: - BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) - : Op(op), LHS(lhs), RHS(rhs) {} - Value *Codegen() override; + 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; }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; public: - CallExprAST(const std::string &callee, std::vector<ExprAST *> &args) - : Callee(callee), Args(args) {} - Value *Codegen() override; + CallExprAST(const std::string &Callee, + std::vector<std::unique_ptr<ExprAST>> Args) + : Callee(Callee), Args(std::move(Args)) {} + Value *codegen() override; }; /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { - ExprAST *Cond, *Then, *Else; + std::unique_ptr<ExprAST> Cond, Then, Else; public: - IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else) - : Cond(cond), Then(then), Else(_else) {} - Value *Codegen() override; + IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then, + std::unique_ptr<ExprAST> Else) + : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {} + Value *codegen() override; }; /// ForExprAST - Expression class for for/in. class ForExprAST : public ExprAST { std::string VarName; - ExprAST *Start, *End, *Step, *Body; + std::unique_ptr<ExprAST> Start, End, Step, Body; public: - ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end, - ExprAST *step, ExprAST *body) - : VarName(varname), Start(start), End(end), Step(step), Body(body) {} - Value *Codegen() override; + ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start, + std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step, + std::unique_ptr<ExprAST> Body) + : VarName(VarName), Start(std::move(Start)), End(std::move(End)), + Step(std::move(Step)), Body(std::move(Body)) {} + Value *codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, @@ -189,21 +192,22 @@ class PrototypeAST { std::vector<std::string> Args; public: - PrototypeAST(const std::string &name, const std::vector<std::string> &args) - : Name(name), Args(args) {} - - Function *Codegen(); + 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; } }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { - PrototypeAST *Proto; - ExprAST *Body; + std::unique_ptr<PrototypeAST> Proto; + std::unique_ptr<ExprAST> Body; public: - FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} - - Function *Codegen(); + FunctionAST(std::unique_ptr<PrototypeAST> Proto, + std::unique_ptr<ExprAST> Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} + Function *codegen(); }; } // end anonymous namespace @@ -234,41 +238,58 @@ static int GetTokPrecedence() { } /// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { +std::unique_ptr<ExprAST> Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str); - return 0; + return nullptr; } -PrototypeAST *ErrorP(const char *Str) { + +std::unique_ptr<PrototypeAST> ErrorP(const char *Str) { Error(Str); - return 0; + return nullptr; } -FunctionAST *ErrorF(const char *Str) { - Error(Str); - return 0; + +static std::unique_ptr<ExprAST> ParseExpression(); + +/// numberexpr ::= number +static std::unique_ptr<ExprAST> ParseNumberExpr() { + auto Result = llvm::make_unique<NumberExprAST>(NumVal); + getNextToken(); // consume the number + return std::move(Result); } -static ExprAST *ParseExpression(); +/// parenexpr ::= '(' expression ')' +static std::unique_ptr<ExprAST> ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { +static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; getNextToken(); // eat identifier. if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); + return llvm::make_unique<VariableExprAST>(IdName); // Call. getNextToken(); // eat ( - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) - return 0; - Args.push_back(Arg); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; if (CurTok == ')') break; @@ -282,60 +303,41 @@ static ExprAST *ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - return new CallExprAST(IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} - -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) - return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } /// ifexpr ::= 'if' expression 'then' expression 'else' expression -static ExprAST *ParseIfExpr() { +static std::unique_ptr<ExprAST> ParseIfExpr() { getNextToken(); // eat the if. // condition. - ExprAST *Cond = ParseExpression(); + auto Cond = ParseExpression(); if (!Cond) - return 0; + return nullptr; if (CurTok != tok_then) return Error("expected then"); getNextToken(); // eat the then - ExprAST *Then = ParseExpression(); - if (Then == 0) - return 0; + auto Then = ParseExpression(); + if (!Then) + return nullptr; if (CurTok != tok_else) return Error("expected else"); getNextToken(); - ExprAST *Else = ParseExpression(); + auto Else = ParseExpression(); if (!Else) - return 0; + return nullptr; - return new IfExprAST(Cond, Then, Else); + return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), + std::move(Else)); } /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression -static ExprAST *ParseForExpr() { +static std::unique_ptr<ExprAST> ParseForExpr() { getNextToken(); // eat the for. if (CurTok != tok_identifier) @@ -348,35 +350,36 @@ static ExprAST *ParseForExpr() { return Error("expected '=' after for"); getNextToken(); // eat '='. - ExprAST *Start = ParseExpression(); - if (Start == 0) - return 0; + auto Start = ParseExpression(); + if (!Start) + return nullptr; if (CurTok != ',') return Error("expected ',' after for start value"); getNextToken(); - ExprAST *End = ParseExpression(); - if (End == 0) - return 0; + auto End = ParseExpression(); + if (!End) + return nullptr; // The step value is optional. - ExprAST *Step = 0; + std::unique_ptr<ExprAST> Step; if (CurTok == ',') { getNextToken(); Step = ParseExpression(); - if (Step == 0) - return 0; + if (!Step) + return nullptr; } if (CurTok != tok_in) return Error("expected 'in' after for"); getNextToken(); // eat 'in'. - ExprAST *Body = ParseExpression(); - if (Body == 0) - return 0; + auto Body = ParseExpression(); + if (!Body) + return nullptr; - return new ForExprAST(IdName, Start, End, Step, Body); + return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End), + std::move(Step), std::move(Body)); } /// primary @@ -385,7 +388,7 @@ static ExprAST *ParseForExpr() { /// ::= parenexpr /// ::= ifexpr /// ::= forexpr -static ExprAST *ParsePrimary() { +static std::unique_ptr<ExprAST> ParsePrimary() { switch (CurTok) { default: return Error("unknown token when expecting an expression"); @@ -404,7 +407,8 @@ static ExprAST *ParsePrimary() { /// binoprhs /// ::= ('+' primary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { +static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, + std::unique_ptr<ExprAST> LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -419,38 +423,39 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { getNextToken(); // eat binop // Parse the primary expression after the binary operator. - ExprAST *RHS = ParsePrimary(); + auto RHS = ParsePrimary(); if (!RHS) - return 0; + return nullptr; // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec + 1, RHS); - if (RHS == 0) - return 0; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } // Merge LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS); + LHS = + llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } } /// expression /// ::= primary binoprhs /// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParsePrimary(); +static std::unique_ptr<ExprAST> ParseExpression() { + auto LHS = ParsePrimary(); if (!LHS) - return 0; + return nullptr; - return ParseBinOpRHS(0, LHS); + return ParseBinOpRHS(0, std::move(LHS)); } /// prototype /// ::= id '(' id* ')' -static PrototypeAST *ParsePrototype() { +static std::unique_ptr<PrototypeAST> ParsePrototype() { if (CurTok != tok_identifier) return ErrorP("Expected function name in prototype"); @@ -469,33 +474,34 @@ static PrototypeAST *ParsePrototype() { // success. getNextToken(); // eat ')'. - return new PrototypeAST(FnName, ArgNames); + return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames)); } /// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { +static std::unique_ptr<FunctionAST> ParseDefinition() { getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) - return 0; + auto Proto = ParsePrototype(); + if (!Proto) + return nullptr; - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; + if (auto E = ParseExpression()) + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); + return nullptr; } /// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { - if (ExprAST *E = ParseExpression()) { +static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { + if (auto E = ParseExpression()) { // Make an anonymous proto. - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); - return new FunctionAST(Proto, E); + auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr", + std::vector<std::string>()); + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); } - return 0; + return nullptr; } /// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { +static std::unique_ptr<PrototypeAST> ParseExtern() { getNextToken(); // eat extern. return ParsePrototype(); } @@ -504,31 +510,50 @@ static PrototypeAST *ParseExtern() { // Code Generation //===----------------------------------------------------------------------===// -static Module *TheModule; +static std::unique_ptr<Module> TheModule; static IRBuilder<> Builder(getGlobalContext()); static std::map<std::string, Value *> NamedValues; -static legacy::FunctionPassManager *TheFPM; +static std::unique_ptr<legacy::FunctionPassManager> TheFPM; +static std::unique_ptr<KaleidoscopeJIT> TheJIT; +static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos; Value *ErrorV(const char *Str) { Error(Str); - return 0; + return nullptr; +} + +Function *getFunction(std::string Name) { + // First, see if the function has already been added to the current module. + if (auto *F = TheModule->getFunction(Name)) + return F; + + // If not, check whether we can codegen the declaration from some existing + // prototype. + auto FI = FunctionProtos.find(Name); + if (FI != FunctionProtos.end()) + return FI->second->codegen(); + + // If no existing prototype exists, return null. + return nullptr; } -Value *NumberExprAST::Codegen() { +Value *NumberExprAST::codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); } -Value *VariableExprAST::Codegen() { +Value *VariableExprAST::codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - return V ? V : ErrorV("Unknown variable name"); + if (!V) + return ErrorV("Unknown variable name"); + return V; } -Value *BinaryExprAST::Codegen() { - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); - if (L == 0 || R == 0) - return 0; +Value *BinaryExprAST::codegen() { + Value *L = LHS->codegen(); + Value *R = RHS->codegen(); + if (!L || !R) + return nullptr; switch (Op) { case '+': @@ -547,10 +572,10 @@ Value *BinaryExprAST::Codegen() { } } -Value *CallExprAST::Codegen() { +Value *CallExprAST::codegen() { // Look up the name in the global module table. - Function *CalleeF = TheModule->getFunction(Callee); - if (CalleeF == 0) + Function *CalleeF = getFunction(Callee); + if (!CalleeF) return ErrorV("Unknown function referenced"); // If argument mismatch error. @@ -559,18 +584,18 @@ Value *CallExprAST::Codegen() { std::vector<Value *> ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) - return 0; + ArgsV.push_back(Args[i]->codegen()); + if (!ArgsV.back()) + return nullptr; } return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } -Value *IfExprAST::Codegen() { - Value *CondV = Cond->Codegen(); - if (CondV == 0) - return 0; +Value *IfExprAST::codegen() { + Value *CondV = Cond->codegen(); + if (!CondV) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. CondV = Builder.CreateFCmpONE( @@ -590,9 +615,9 @@ Value *IfExprAST::Codegen() { // Emit then value. Builder.SetInsertPoint(ThenBB); - Value *ThenV = Then->Codegen(); - if (ThenV == 0) - return 0; + Value *ThenV = Then->codegen(); + if (!ThenV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. @@ -602,9 +627,9 @@ Value *IfExprAST::Codegen() { TheFunction->getBasicBlockList().push_back(ElseBB); Builder.SetInsertPoint(ElseBB); - Value *ElseV = Else->Codegen(); - if (ElseV == 0) - return 0; + Value *ElseV = Else->codegen(); + if (!ElseV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. @@ -621,27 +646,26 @@ Value *IfExprAST::Codegen() { return PN; } -Value *ForExprAST::Codegen() { - // Output this as: - // ... - // start = startexpr - // goto loop - // loop: - // variable = phi [start, loopheader], [nextvariable, loopend] - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // nextvariable = variable + step - // endcond = endexpr - // br endcond, loop, endloop - // outloop: - +// Output for-loop as: +// ... +// start = startexpr +// goto loop +// loop: +// variable = phi [start, loopheader], [nextvariable, loopend] +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// nextvariable = variable + step +// endcond = endexpr +// br endcond, loop, endloop +// outloop: +Value *ForExprAST::codegen() { // Emit the start code first, without 'variable' in scope. - Value *StartVal = Start->Codegen(); - if (StartVal == 0) - return 0; + Value *StartVal = Start->codegen(); + if (!StartVal) + return nullptr; // Make the new basic block for the loop header, inserting after current // block. @@ -669,15 +693,15 @@ Value *ForExprAST::Codegen() { // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. - if (Body->Codegen() == 0) - return 0; + if (!Body->codegen()) + return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { - StepVal = Step->Codegen(); - if (StepVal == 0) - return 0; + StepVal = Step->codegen(); + if (!StepVal) + return nullptr; } else { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); @@ -686,9 +710,9 @@ Value *ForExprAST::Codegen() { Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar"); // Compute the end condition. - Value *EndCond = End->Codegen(); - if (EndCond == 0) - return EndCond; + Value *EndCond = End->codegen(); + if (!EndCond) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. EndCond = Builder.CreateFCmpONE( @@ -718,7 +742,7 @@ Value *ForExprAST::Codegen() { return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } -Function *PrototypeAST::Codegen() { +Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); @@ -726,60 +750,42 @@ Function *PrototypeAST::Codegen() { FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); Function *F = - Function::Create(FT, Function::ExternalLinkage, Name, TheModule); - - // If F conflicted, there was already something named 'Name'. If it has a - // body, don't allow redefinition or reextern. - if (F->getName() != Name) { - // Delete the one we just made and get the existing one. - F->eraseFromParent(); - F = TheModule->getFunction(Name); - - // If F already has a body, reject this. - if (!F->empty()) { - ErrorF("redefinition of function"); - return 0; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return 0; - } - } + Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get()); // Set names for all arguments. unsigned Idx = 0; - for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); - ++AI, ++Idx) { - AI->setName(Args[Idx]); - - // Add arguments to variable symbol table. - NamedValues[Args[Idx]] = AI; - } + for (auto &Arg : F->args()) + Arg.setName(Args[Idx++]); return F; } -Function *FunctionAST::Codegen() { - NamedValues.clear(); - - Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; +Function *FunctionAST::codegen() { + // Transfer ownership of the prototype to the FunctionProtos map, but keep a + // reference to it for use below. + auto &P = *Proto; + FunctionProtos[Proto->getName()] = std::move(Proto); + Function *TheFunction = getFunction(P.getName()); + if (!TheFunction) + return nullptr; // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); - if (Value *RetVal = Body->Codegen()) { + // 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); - // Optimize the function. + // Run the optimizer on the function. TheFPM->run(*TheFunction); return TheFunction; @@ -787,20 +793,40 @@ Function *FunctionAST::Codegen() { // Error reading body, remove function. TheFunction->eraseFromParent(); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// // Top-Level parsing and JIT Driver //===----------------------------------------------------------------------===// -static ExecutionEngine *TheExecutionEngine; +static void InitializeModuleAndPassManager() { + // Open a new module. + TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext()); + TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout()); + + // Create a new pass manager attached to it. + TheFPM = llvm::make_unique<legacy::FunctionPassManager>(TheModule.get()); + + // Do simple "peephole" optimizations and bit-twiddling optzns. + TheFPM->add(createInstructionCombiningPass()); + // Reassociate expressions. + TheFPM->add(createReassociatePass()); + // Eliminate Common SubExpressions. + TheFPM->add(createGVNPass()); + // Simplify the control flow graph (deleting unreachable blocks, etc). + TheFPM->add(createCFGSimplificationPass()); + + TheFPM->doInitialization(); +} static void HandleDefinition() { - if (FunctionAST *F = ParseDefinition()) { - if (Function *LF = F->Codegen()) { + if (auto FnAST = ParseDefinition()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read function definition:"); - LF->dump(); + FnIR->dump(); + TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); } } else { // Skip token for error recovery. @@ -809,10 +835,11 @@ static void HandleDefinition() { } static void HandleExtern() { - if (PrototypeAST *P = ParseExtern()) { - if (Function *F = P->Codegen()) { + if (auto ProtoAST = ParseExtern()) { + if (auto *FnIR = ProtoAST->codegen()) { fprintf(stderr, "Read extern: "); - F->dump(); + FnIR->dump(); + FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST); } } else { // Skip token for error recovery. @@ -822,16 +849,25 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - if (Function *LF = F->Codegen()) { - TheExecutionEngine->finalizeObject(); - // JIT the function, returning a function pointer. - void *FPtr = TheExecutionEngine->getPointerToFunction(LF); - - // Cast it to the right type (takes no arguments, returns a double) so we - // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)FPtr; + if (auto FnAST = ParseTopLevelExpr()) { + if (FnAST->codegen()) { + + // JIT the module containing the anonymous expression, keeping a handle so + // we can free it later. + auto H = TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); + + // Search the JIT for the __anon_expr symbol. + auto ExprSymbol = TheJIT->findSymbol("__anon_expr"); + assert(ExprSymbol && "Function not found"); + + // Get the symbol's address and cast it to the right type (takes no + // arguments, returns a double) so we can call it as a native function. + double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); fprintf(stderr, "Evaluated to %f\n", FP()); + + // Delete the anonymous expression module from the JIT. + TheJIT->removeModule(H); } } else { // Skip token for error recovery. @@ -846,9 +882,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -868,7 +904,13 @@ static void MainLoop() { /// putchard - putchar that takes a double and returns 0. extern "C" double putchard(double X) { - putchar((char)X); + fputc((char)X, stderr); + return 0; +} + +/// printd - printf that takes a double prints it as "%f\n", returning 0. +extern "C" double printd(double X) { + fprintf(stderr, "%f\n", X); return 0; } @@ -880,7 +922,6 @@ int main() { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); - LLVMContext &Context = getGlobalContext(); // Install standard binary operators. // 1 is lowest precedence. @@ -893,50 +934,12 @@ int main() { fprintf(stderr, "ready> "); getNextToken(); - // Make the module, which holds all the code. - std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context); - TheModule = Owner.get(); - - // Create the JIT. This takes ownership of the module. - std::string ErrStr; - TheExecutionEngine = - EngineBuilder(std::move(Owner)) - .setErrorStr(&ErrStr) - .setMCJITMemoryManager(llvm::make_unique<SectionMemoryManager>()) - .create(); - if (!TheExecutionEngine) { - fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); - exit(1); - } - - legacy::FunctionPassManager OurFPM(TheModule); - - // Set up the optimizer pipeline. Start with registering info about how the - // target lays out data structures. - TheModule->setDataLayout(*TheExecutionEngine->getDataLayout()); - // Provide basic AliasAnalysis support for GVN. - OurFPM.add(createBasicAliasAnalysisPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - OurFPM.add(createInstructionCombiningPass()); - // Reassociate expressions. - OurFPM.add(createReassociatePass()); - // Eliminate Common SubExpressions. - OurFPM.add(createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - OurFPM.add(createCFGSimplificationPass()); - - OurFPM.doInitialization(); + TheJIT = llvm::make_unique<KaleidoscopeJIT>(); - // Set the global so the code gen can use this. - TheFPM = &OurFPM; + InitializeModuleAndPassManager(); // Run the main "interpreter loop" now. MainLoop(); - TheFPM = 0; - - // Print out all of the generated code. - TheModule->dump(); - return 0; } diff --git a/examples/Kaleidoscope/Chapter6/CMakeLists.txt b/examples/Kaleidoscope/Chapter6/CMakeLists.txt index 7ac1ca49c4f9..49627f07ddf0 100644 --- a/examples/Kaleidoscope/Chapter6/CMakeLists.txt +++ b/examples/Kaleidoscope/Chapter6/CMakeLists.txt @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS Core ExecutionEngine InstCombine - MCJIT + Object RuntimeDyld ScalarOpts Support @@ -13,3 +13,5 @@ set(LLVM_LINK_COMPONENTS add_kaleidoscope_chapter(Kaleidoscope-Ch6 toy.cpp ) + +export_executable_symbols(Kaleidoscope-Ch6) diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp index e978a3ea3682..4d04f7e888af 100644 --- a/examples/Kaleidoscope/Chapter6/toy.cpp +++ b/examples/Kaleidoscope/Chapter6/toy.cpp @@ -1,10 +1,5 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/Passes.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/MCJIT.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" @@ -17,7 +12,10 @@ #include <map> #include <string> #include <vector> +#include "../include/KaleidoscopeJIT.h" + using namespace llvm; +using namespace llvm::orc; //===----------------------------------------------------------------------===// // Lexer @@ -92,7 +90,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -124,7 +122,7 @@ namespace { class ExprAST { public: virtual ~ExprAST() {} - virtual Value *Codegen() = 0; + virtual Value *codegen() = 0; }; /// NumberExprAST - Expression class for numeric literals like "1.0". @@ -132,8 +130,8 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} - Value *Codegen() override; + NumberExprAST(double Val) : Val(Val) {} + Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". @@ -141,63 +139,68 @@ class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(const std::string &name) : Name(name) {} - Value *Codegen() override; + VariableExprAST(const std::string &Name) : Name(Name) {} + Value *codegen() override; }; /// UnaryExprAST - Expression class for a unary operator. class UnaryExprAST : public ExprAST { char Opcode; - ExprAST *Operand; + std::unique_ptr<ExprAST> Operand; public: - UnaryExprAST(char opcode, ExprAST *operand) - : Opcode(opcode), Operand(operand) {} - Value *Codegen() override; + UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) + : Opcode(Opcode), Operand(std::move(Operand)) {} + Value *codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { char Op; - ExprAST *LHS, *RHS; + std::unique_ptr<ExprAST> LHS, RHS; public: - BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) - : Op(op), LHS(lhs), RHS(rhs) {} - Value *Codegen() override; + 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; }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; public: - CallExprAST(const std::string &callee, std::vector<ExprAST *> &args) - : Callee(callee), Args(args) {} - Value *Codegen() override; + CallExprAST(const std::string &Callee, + std::vector<std::unique_ptr<ExprAST>> Args) + : Callee(Callee), Args(std::move(Args)) {} + Value *codegen() override; }; /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { - ExprAST *Cond, *Then, *Else; + std::unique_ptr<ExprAST> Cond, Then, Else; public: - IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else) - : Cond(cond), Then(then), Else(_else) {} - Value *Codegen() override; + IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then, + std::unique_ptr<ExprAST> Else) + : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {} + Value *codegen() override; }; /// ForExprAST - Expression class for for/in. class ForExprAST : public ExprAST { std::string VarName; - ExprAST *Start, *End, *Step, *Body; + std::unique_ptr<ExprAST> Start, End, Step, Body; public: - ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end, - ExprAST *step, ExprAST *body) - : VarName(varname), Start(start), End(end), Step(step), Body(body) {} - Value *Codegen() override; + ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start, + std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step, + std::unique_ptr<ExprAST> Body) + : VarName(VarName), Start(std::move(Start)), End(std::move(End)), + Step(std::move(Step)), Body(std::move(Body)) {} + Value *codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, @@ -206,15 +209,19 @@ public: class PrototypeAST { std::string Name; std::vector<std::string> Args; - bool isOperator; + bool IsOperator; unsigned Precedence; // Precedence if a binary op. + public: - PrototypeAST(const std::string &name, const std::vector<std::string> &args, - bool isoperator = false, unsigned prec = 0) - : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {} + PrototypeAST(const std::string &Name, std::vector<std::string> Args, + bool IsOperator = false, unsigned Prec = 0) + : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), + Precedence(Prec) {} + Function *codegen(); + const std::string &getName() const { return Name; } - bool isUnaryOp() const { return isOperator && Args.size() == 1; } - bool isBinaryOp() const { return isOperator && Args.size() == 2; } + bool isUnaryOp() const { return IsOperator && Args.size() == 1; } + bool isBinaryOp() const { return IsOperator && Args.size() == 2; } char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); @@ -222,19 +229,18 @@ public: } unsigned getBinaryPrecedence() const { return Precedence; } - - Function *Codegen(); }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { - PrototypeAST *Proto; - ExprAST *Body; + std::unique_ptr<PrototypeAST> Proto; + std::unique_ptr<ExprAST> Body; public: - FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} - - Function *Codegen(); + FunctionAST(std::unique_ptr<PrototypeAST> Proto, + std::unique_ptr<ExprAST> Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} + Function *codegen(); }; } // end anonymous namespace @@ -265,41 +271,58 @@ static int GetTokPrecedence() { } /// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { +std::unique_ptr<ExprAST> Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str); - return 0; + return nullptr; } -PrototypeAST *ErrorP(const char *Str) { + +std::unique_ptr<PrototypeAST> ErrorP(const char *Str) { Error(Str); - return 0; + return nullptr; } -FunctionAST *ErrorF(const char *Str) { - Error(Str); - return 0; + +static std::unique_ptr<ExprAST> ParseExpression(); + +/// numberexpr ::= number +static std::unique_ptr<ExprAST> ParseNumberExpr() { + auto Result = llvm::make_unique<NumberExprAST>(NumVal); + getNextToken(); // consume the number + return std::move(Result); } -static ExprAST *ParseExpression(); +/// parenexpr ::= '(' expression ')' +static std::unique_ptr<ExprAST> ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { +static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; getNextToken(); // eat identifier. if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); + return llvm::make_unique<VariableExprAST>(IdName); // Call. getNextToken(); // eat ( - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) - return 0; - Args.push_back(Arg); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; if (CurTok == ')') break; @@ -313,60 +336,41 @@ static ExprAST *ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - return new CallExprAST(IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} - -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) - return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } /// ifexpr ::= 'if' expression 'then' expression 'else' expression -static ExprAST *ParseIfExpr() { +static std::unique_ptr<ExprAST> ParseIfExpr() { getNextToken(); // eat the if. // condition. - ExprAST *Cond = ParseExpression(); + auto Cond = ParseExpression(); if (!Cond) - return 0; + return nullptr; if (CurTok != tok_then) return Error("expected then"); getNextToken(); // eat the then - ExprAST *Then = ParseExpression(); - if (Then == 0) - return 0; + auto Then = ParseExpression(); + if (!Then) + return nullptr; if (CurTok != tok_else) return Error("expected else"); getNextToken(); - ExprAST *Else = ParseExpression(); + auto Else = ParseExpression(); if (!Else) - return 0; + return nullptr; - return new IfExprAST(Cond, Then, Else); + return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), + std::move(Else)); } /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression -static ExprAST *ParseForExpr() { +static std::unique_ptr<ExprAST> ParseForExpr() { getNextToken(); // eat the for. if (CurTok != tok_identifier) @@ -379,35 +383,36 @@ static ExprAST *ParseForExpr() { return Error("expected '=' after for"); getNextToken(); // eat '='. - ExprAST *Start = ParseExpression(); - if (Start == 0) - return 0; + auto Start = ParseExpression(); + if (!Start) + return nullptr; if (CurTok != ',') return Error("expected ',' after for start value"); getNextToken(); - ExprAST *End = ParseExpression(); - if (End == 0) - return 0; + auto End = ParseExpression(); + if (!End) + return nullptr; // The step value is optional. - ExprAST *Step = 0; + std::unique_ptr<ExprAST> Step; if (CurTok == ',') { getNextToken(); Step = ParseExpression(); - if (Step == 0) - return 0; + if (!Step) + return nullptr; } if (CurTok != tok_in) return Error("expected 'in' after for"); getNextToken(); // eat 'in'. - ExprAST *Body = ParseExpression(); - if (Body == 0) - return 0; + auto Body = ParseExpression(); + if (!Body) + return nullptr; - return new ForExprAST(IdName, Start, End, Step, Body); + return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End), + std::move(Step), std::move(Body)); } /// primary @@ -416,7 +421,7 @@ static ExprAST *ParseForExpr() { /// ::= parenexpr /// ::= ifexpr /// ::= forexpr -static ExprAST *ParsePrimary() { +static std::unique_ptr<ExprAST> ParsePrimary() { switch (CurTok) { default: return Error("unknown token when expecting an expression"); @@ -436,7 +441,7 @@ static ExprAST *ParsePrimary() { /// unary /// ::= primary /// ::= '!' unary -static ExprAST *ParseUnary() { +static std::unique_ptr<ExprAST> ParseUnary() { // If the current token is not an operator, it must be a primary expr. if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') return ParsePrimary(); @@ -444,14 +449,15 @@ static ExprAST *ParseUnary() { // If this is a unary operator, read it. int Opc = CurTok; getNextToken(); - if (ExprAST *Operand = ParseUnary()) - return new UnaryExprAST(Opc, Operand); - return 0; + if (auto Operand = ParseUnary()) + return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand)); + return nullptr; } /// binoprhs /// ::= ('+' unary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { +static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, + std::unique_ptr<ExprAST> LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -466,40 +472,41 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { getNextToken(); // eat binop // Parse the unary expression after the binary operator. - ExprAST *RHS = ParseUnary(); + auto RHS = ParseUnary(); if (!RHS) - return 0; + return nullptr; // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec + 1, RHS); - if (RHS == 0) - return 0; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } // Merge LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS); + LHS = + llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } } /// expression /// ::= unary binoprhs /// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParseUnary(); +static std::unique_ptr<ExprAST> ParseExpression() { + auto LHS = ParseUnary(); if (!LHS) - return 0; + return nullptr; - return ParseBinOpRHS(0, LHS); + return ParseBinOpRHS(0, std::move(LHS)); } /// prototype /// ::= id '(' id* ')' /// ::= binary LETTER number? (id, id) /// ::= unary LETTER (id) -static PrototypeAST *ParsePrototype() { +static std::unique_ptr<PrototypeAST> ParsePrototype() { std::string FnName; unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. @@ -557,33 +564,35 @@ static PrototypeAST *ParsePrototype() { if (Kind && ArgNames.size() != Kind) return ErrorP("Invalid number of operands for operator"); - return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence); + return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0, + BinaryPrecedence); } /// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { +static std::unique_ptr<FunctionAST> ParseDefinition() { getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) - return 0; + auto Proto = ParsePrototype(); + if (!Proto) + return nullptr; - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; + if (auto E = ParseExpression()) + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); + return nullptr; } /// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { - if (ExprAST *E = ParseExpression()) { +static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { + if (auto E = ParseExpression()) { // Make an anonymous proto. - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); - return new FunctionAST(Proto, E); + auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr", + std::vector<std::string>()); + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); } - return 0; + return nullptr; } /// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { +static std::unique_ptr<PrototypeAST> ParseExtern() { getNextToken(); // eat extern. return ParsePrototype(); } @@ -592,43 +601,62 @@ static PrototypeAST *ParseExtern() { // Code Generation //===----------------------------------------------------------------------===// -static Module *TheModule; +static std::unique_ptr<Module> TheModule; static IRBuilder<> Builder(getGlobalContext()); static std::map<std::string, Value *> NamedValues; -static legacy::FunctionPassManager *TheFPM; +static std::unique_ptr<legacy::FunctionPassManager> TheFPM; +static std::unique_ptr<KaleidoscopeJIT> TheJIT; +static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos; Value *ErrorV(const char *Str) { Error(Str); - return 0; + return nullptr; } -Value *NumberExprAST::Codegen() { +Function *getFunction(std::string Name) { + // First, see if the function has already been added to the current module. + if (auto *F = TheModule->getFunction(Name)) + return F; + + // If not, check whether we can codegen the declaration from some existing + // prototype. + auto FI = FunctionProtos.find(Name); + if (FI != FunctionProtos.end()) + return FI->second->codegen(); + + // If no existing prototype exists, return null. + return nullptr; +} + +Value *NumberExprAST::codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); } -Value *VariableExprAST::Codegen() { +Value *VariableExprAST::codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - return V ? V : ErrorV("Unknown variable name"); + if (!V) + return ErrorV("Unknown variable name"); + return V; } -Value *UnaryExprAST::Codegen() { - Value *OperandV = Operand->Codegen(); - if (OperandV == 0) - return 0; +Value *UnaryExprAST::codegen() { + Value *OperandV = Operand->codegen(); + if (!OperandV) + return nullptr; - Function *F = TheModule->getFunction(std::string("unary") + Opcode); - if (F == 0) + Function *F = getFunction(std::string("unary") + Opcode); + if (!F) return ErrorV("Unknown unary operator"); return Builder.CreateCall(F, OperandV, "unop"); } -Value *BinaryExprAST::Codegen() { - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); - if (L == 0 || R == 0) - return 0; +Value *BinaryExprAST::codegen() { + Value *L = LHS->codegen(); + Value *R = RHS->codegen(); + if (!L || !R) + return nullptr; switch (Op) { case '+': @@ -648,17 +676,17 @@ Value *BinaryExprAST::Codegen() { // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. - Function *F = TheModule->getFunction(std::string("binary") + Op); + Function *F = getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; + Value *Ops[] = {L, R}; return Builder.CreateCall(F, Ops, "binop"); } -Value *CallExprAST::Codegen() { +Value *CallExprAST::codegen() { // Look up the name in the global module table. - Function *CalleeF = TheModule->getFunction(Callee); - if (CalleeF == 0) + Function *CalleeF = getFunction(Callee); + if (!CalleeF) return ErrorV("Unknown function referenced"); // If argument mismatch error. @@ -667,18 +695,18 @@ Value *CallExprAST::Codegen() { std::vector<Value *> ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) - return 0; + ArgsV.push_back(Args[i]->codegen()); + if (!ArgsV.back()) + return nullptr; } return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } -Value *IfExprAST::Codegen() { - Value *CondV = Cond->Codegen(); - if (CondV == 0) - return 0; +Value *IfExprAST::codegen() { + Value *CondV = Cond->codegen(); + if (!CondV) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. CondV = Builder.CreateFCmpONE( @@ -698,9 +726,9 @@ Value *IfExprAST::Codegen() { // Emit then value. Builder.SetInsertPoint(ThenBB); - Value *ThenV = Then->Codegen(); - if (ThenV == 0) - return 0; + Value *ThenV = Then->codegen(); + if (!ThenV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. @@ -710,9 +738,9 @@ Value *IfExprAST::Codegen() { TheFunction->getBasicBlockList().push_back(ElseBB); Builder.SetInsertPoint(ElseBB); - Value *ElseV = Else->Codegen(); - if (ElseV == 0) - return 0; + Value *ElseV = Else->codegen(); + if (!ElseV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. @@ -729,27 +757,26 @@ Value *IfExprAST::Codegen() { return PN; } -Value *ForExprAST::Codegen() { - // Output this as: - // ... - // start = startexpr - // goto loop - // loop: - // variable = phi [start, loopheader], [nextvariable, loopend] - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // nextvariable = variable + step - // endcond = endexpr - // br endcond, loop, endloop - // outloop: - +// Output for-loop as: +// ... +// start = startexpr +// goto loop +// loop: +// variable = phi [start, loopheader], [nextvariable, loopend] +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// nextvariable = variable + step +// endcond = endexpr +// br endcond, loop, endloop +// outloop: +Value *ForExprAST::codegen() { // Emit the start code first, without 'variable' in scope. - Value *StartVal = Start->Codegen(); - if (StartVal == 0) - return 0; + Value *StartVal = Start->codegen(); + if (!StartVal) + return nullptr; // Make the new basic block for the loop header, inserting after current // block. @@ -777,15 +804,15 @@ Value *ForExprAST::Codegen() { // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. - if (Body->Codegen() == 0) - return 0; + if (!Body->codegen()) + return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { - StepVal = Step->Codegen(); - if (StepVal == 0) - return 0; + StepVal = Step->codegen(); + if (!StepVal) + return nullptr; } else { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); @@ -794,9 +821,9 @@ Value *ForExprAST::Codegen() { Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar"); // Compute the end condition. - Value *EndCond = End->Codegen(); - if (EndCond == 0) - return EndCond; + Value *EndCond = End->codegen(); + if (!EndCond) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. EndCond = Builder.CreateFCmpONE( @@ -826,7 +853,7 @@ Value *ForExprAST::Codegen() { return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } -Function *PrototypeAST::Codegen() { +Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); @@ -834,64 +861,46 @@ Function *PrototypeAST::Codegen() { FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); Function *F = - Function::Create(FT, Function::ExternalLinkage, Name, TheModule); - - // If F conflicted, there was already something named 'Name'. If it has a - // body, don't allow redefinition or reextern. - if (F->getName() != Name) { - // Delete the one we just made and get the existing one. - F->eraseFromParent(); - F = TheModule->getFunction(Name); - - // If F already has a body, reject this. - if (!F->empty()) { - ErrorF("redefinition of function"); - return 0; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return 0; - } - } + Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get()); // Set names for all arguments. unsigned Idx = 0; - for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); - ++AI, ++Idx) { - AI->setName(Args[Idx]); - - // Add arguments to variable symbol table. - NamedValues[Args[Idx]] = AI; - } + for (auto &Arg : F->args()) + Arg.setName(Args[Idx++]); return F; } -Function *FunctionAST::Codegen() { - NamedValues.clear(); - - Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; +Function *FunctionAST::codegen() { + // Transfer ownership of the prototype to the FunctionProtos map, but keep a + // reference to it for use below. + auto &P = *Proto; + FunctionProtos[Proto->getName()] = std::move(Proto); + Function *TheFunction = getFunction(P.getName()); + if (!TheFunction) + return nullptr; // If this is an operator, install it. - if (Proto->isBinaryOp()) - BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence(); + if (P.isBinaryOp()) + BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence(); // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); - if (Value *RetVal = Body->Codegen()) { + // 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); - // Optimize the function. + // Run the optimizer on the function. TheFPM->run(*TheFunction); return TheFunction; @@ -900,22 +909,42 @@ Function *FunctionAST::Codegen() { // Error reading body, remove function. TheFunction->eraseFromParent(); - if (Proto->isBinaryOp()) + if (P.isBinaryOp()) BinopPrecedence.erase(Proto->getOperatorName()); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// // Top-Level parsing and JIT Driver //===----------------------------------------------------------------------===// -static ExecutionEngine *TheExecutionEngine; +static void InitializeModuleAndPassManager() { + // Open a new module. + TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext()); + TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout()); + + // Create a new pass manager attached to it. + TheFPM = llvm::make_unique<legacy::FunctionPassManager>(TheModule.get()); + + // Do simple "peephole" optimizations and bit-twiddling optzns. + TheFPM->add(createInstructionCombiningPass()); + // Reassociate expressions. + TheFPM->add(createReassociatePass()); + // Eliminate Common SubExpressions. + TheFPM->add(createGVNPass()); + // Simplify the control flow graph (deleting unreachable blocks, etc). + TheFPM->add(createCFGSimplificationPass()); + + TheFPM->doInitialization(); +} static void HandleDefinition() { - if (FunctionAST *F = ParseDefinition()) { - if (Function *LF = F->Codegen()) { + if (auto FnAST = ParseDefinition()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read function definition:"); - LF->dump(); + FnIR->dump(); + TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); } } else { // Skip token for error recovery. @@ -924,10 +953,11 @@ static void HandleDefinition() { } static void HandleExtern() { - if (PrototypeAST *P = ParseExtern()) { - if (Function *F = P->Codegen()) { + if (auto ProtoAST = ParseExtern()) { + if (auto *FnIR = ProtoAST->codegen()) { fprintf(stderr, "Read extern: "); - F->dump(); + FnIR->dump(); + FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST); } } else { // Skip token for error recovery. @@ -937,16 +967,25 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - if (Function *LF = F->Codegen()) { - TheExecutionEngine->finalizeObject(); - // JIT the function, returning a function pointer. - void *FPtr = TheExecutionEngine->getPointerToFunction(LF); - - // Cast it to the right type (takes no arguments, returns a double) so we - // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)FPtr; + if (auto FnAST = ParseTopLevelExpr()) { + if (FnAST->codegen()) { + + // JIT the module containing the anonymous expression, keeping a handle so + // we can free it later. + auto H = TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); + + // Search the JIT for the __anon_expr symbol. + auto ExprSymbol = TheJIT->findSymbol("__anon_expr"); + assert(ExprSymbol && "Function not found"); + + // Get the symbol's address and cast it to the right type (takes no + // arguments, returns a double) so we can call it as a native function. + double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); fprintf(stderr, "Evaluated to %f\n", FP()); + + // Delete the anonymous expression module from the JIT. + TheJIT->removeModule(H); } } else { // Skip token for error recovery. @@ -961,9 +1000,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -983,13 +1022,13 @@ static void MainLoop() { /// putchard - putchar that takes a double and returns 0. extern "C" double putchard(double X) { - putchar((char)X); + fputc((char)X, stderr); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. extern "C" double printd(double X) { - printf("%f\n", X); + fprintf(stderr, "%f\n", X); return 0; } @@ -1001,7 +1040,6 @@ int main() { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); - LLVMContext &Context = getGlobalContext(); // Install standard binary operators. // 1 is lowest precedence. @@ -1014,50 +1052,12 @@ int main() { fprintf(stderr, "ready> "); getNextToken(); - // Make the module, which holds all the code. - std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context); - TheModule = Owner.get(); - - // Create the JIT. This takes ownership of the module. - std::string ErrStr; - TheExecutionEngine = - EngineBuilder(std::move(Owner)) - .setErrorStr(&ErrStr) - .setMCJITMemoryManager(llvm::make_unique<SectionMemoryManager>()) - .create(); - if (!TheExecutionEngine) { - fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); - exit(1); - } - - legacy::FunctionPassManager OurFPM(TheModule); - - // Set up the optimizer pipeline. Start with registering info about how the - // target lays out data structures. - TheModule->setDataLayout(*TheExecutionEngine->getDataLayout()); - // Provide basic AliasAnalysis support for GVN. - OurFPM.add(createBasicAliasAnalysisPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - OurFPM.add(createInstructionCombiningPass()); - // Reassociate expressions. - OurFPM.add(createReassociatePass()); - // Eliminate Common SubExpressions. - OurFPM.add(createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - OurFPM.add(createCFGSimplificationPass()); - - OurFPM.doInitialization(); + TheJIT = llvm::make_unique<KaleidoscopeJIT>(); - // Set the global so the code gen can use this. - TheFPM = &OurFPM; + InitializeModuleAndPassManager(); // Run the main "interpreter loop" now. MainLoop(); - TheFPM = 0; - - // Print out all of the generated code. - TheModule->dump(); - return 0; } diff --git a/examples/Kaleidoscope/Chapter7/CMakeLists.txt b/examples/Kaleidoscope/Chapter7/CMakeLists.txt index 8725e4761f78..e67d7928efe7 100644 --- a/examples/Kaleidoscope/Chapter7/CMakeLists.txt +++ b/examples/Kaleidoscope/Chapter7/CMakeLists.txt @@ -3,14 +3,15 @@ set(LLVM_LINK_COMPONENTS Core ExecutionEngine InstCombine - MCJIT + Object RuntimeDyld ScalarOpts Support - TransformUtils native ) add_kaleidoscope_chapter(Kaleidoscope-Ch7 toy.cpp ) + +export_executable_symbols(Kaleidoscope-Ch7) diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp index b1a41fa01b76..5c0094013d97 100644 --- a/examples/Kaleidoscope/Chapter7/toy.cpp +++ b/examples/Kaleidoscope/Chapter7/toy.cpp @@ -1,10 +1,5 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/Passes.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/MCJIT.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" @@ -17,7 +12,10 @@ #include <map> #include <string> #include <vector> +#include "../include/KaleidoscopeJIT.h" + using namespace llvm; +using namespace llvm::orc; //===----------------------------------------------------------------------===// // Lexer @@ -97,7 +95,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -129,7 +127,7 @@ namespace { class ExprAST { public: virtual ~ExprAST() {} - virtual Value *Codegen() = 0; + virtual Value *codegen() = 0; }; /// NumberExprAST - Expression class for numeric literals like "1.0". @@ -137,8 +135,8 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} - Value *Codegen() override; + NumberExprAST(double Val) : Val(Val) {} + Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". @@ -146,93 +144,103 @@ class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(const std::string &name) : Name(name) {} + VariableExprAST(const std::string &Name) : Name(Name) {} const std::string &getName() const { return Name; } - Value *Codegen() override; + Value *codegen() override; }; /// UnaryExprAST - Expression class for a unary operator. class UnaryExprAST : public ExprAST { char Opcode; - ExprAST *Operand; + std::unique_ptr<ExprAST> Operand; public: - UnaryExprAST(char opcode, ExprAST *operand) - : Opcode(opcode), Operand(operand) {} - Value *Codegen() override; + UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) + : Opcode(Opcode), Operand(std::move(Operand)) {} + Value *codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { char Op; - ExprAST *LHS, *RHS; + std::unique_ptr<ExprAST> LHS, RHS; public: - BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) - : Op(op), LHS(lhs), RHS(rhs) {} - Value *Codegen() override; + 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; }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; public: - CallExprAST(const std::string &callee, std::vector<ExprAST *> &args) - : Callee(callee), Args(args) {} - Value *Codegen() override; + CallExprAST(const std::string &Callee, + std::vector<std::unique_ptr<ExprAST>> Args) + : Callee(Callee), Args(std::move(Args)) {} + Value *codegen() override; }; /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { - ExprAST *Cond, *Then, *Else; + std::unique_ptr<ExprAST> Cond, Then, Else; public: - IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else) - : Cond(cond), Then(then), Else(_else) {} - Value *Codegen() override; + IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then, + std::unique_ptr<ExprAST> Else) + : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {} + Value *codegen() override; }; /// ForExprAST - Expression class for for/in. class ForExprAST : public ExprAST { std::string VarName; - ExprAST *Start, *End, *Step, *Body; + std::unique_ptr<ExprAST> Start, End, Step, Body; public: - ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end, - ExprAST *step, ExprAST *body) - : VarName(varname), Start(start), End(end), Step(step), Body(body) {} - Value *Codegen() override; + ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start, + std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step, + std::unique_ptr<ExprAST> Body) + : VarName(VarName), Start(std::move(Start)), End(std::move(End)), + Step(std::move(Step)), Body(std::move(Body)) {} + Value *codegen() override; }; /// VarExprAST - Expression class for var/in class VarExprAST : public ExprAST { - std::vector<std::pair<std::string, ExprAST *> > VarNames; - ExprAST *Body; + std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames; + std::unique_ptr<ExprAST> Body; public: - VarExprAST(const std::vector<std::pair<std::string, ExprAST *> > &varnames, - ExprAST *body) - : VarNames(varnames), Body(body) {} - - Value *Codegen() override; + VarExprAST( + std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames, + std::unique_ptr<ExprAST> Body) + : VarNames(std::move(VarNames)), Body(std::move(Body)) {} + Value *codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, -/// which captures its argument names as well as if it is an operator. +/// which captures its name, and its argument names (thus implicitly the number +/// of arguments the function takes), as well as if it is an operator. class PrototypeAST { std::string Name; std::vector<std::string> Args; - bool isOperator; + bool IsOperator; unsigned Precedence; // Precedence if a binary op. + public: - PrototypeAST(const std::string &name, const std::vector<std::string> &args, - bool isoperator = false, unsigned prec = 0) - : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {} + PrototypeAST(const std::string &Name, std::vector<std::string> Args, + bool IsOperator = false, unsigned Prec = 0) + : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), + Precedence(Prec) {} + Function *codegen(); + const std::string &getName() const { return Name; } - bool isUnaryOp() const { return isOperator && Args.size() == 1; } - bool isBinaryOp() const { return isOperator && Args.size() == 2; } + bool isUnaryOp() const { return IsOperator && Args.size() == 1; } + bool isBinaryOp() const { return IsOperator && Args.size() == 2; } char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); @@ -240,21 +248,18 @@ public: } unsigned getBinaryPrecedence() const { return Precedence; } - - Function *Codegen(); - - void CreateArgumentAllocas(Function *F); }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { - PrototypeAST *Proto; - ExprAST *Body; + std::unique_ptr<PrototypeAST> Proto; + std::unique_ptr<ExprAST> Body; public: - FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} - - Function *Codegen(); + FunctionAST(std::unique_ptr<PrototypeAST> Proto, + std::unique_ptr<ExprAST> Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} + Function *codegen(); }; } // end anonymous namespace @@ -285,41 +290,58 @@ static int GetTokPrecedence() { } /// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { +std::unique_ptr<ExprAST> Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str); - return 0; + return nullptr; } -PrototypeAST *ErrorP(const char *Str) { + +std::unique_ptr<PrototypeAST> ErrorP(const char *Str) { Error(Str); - return 0; + return nullptr; } -FunctionAST *ErrorF(const char *Str) { - Error(Str); - return 0; + +static std::unique_ptr<ExprAST> ParseExpression(); + +/// numberexpr ::= number +static std::unique_ptr<ExprAST> ParseNumberExpr() { + auto Result = llvm::make_unique<NumberExprAST>(NumVal); + getNextToken(); // consume the number + return std::move(Result); } -static ExprAST *ParseExpression(); +/// parenexpr ::= '(' expression ')' +static std::unique_ptr<ExprAST> ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { +static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; getNextToken(); // eat identifier. if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); + return llvm::make_unique<VariableExprAST>(IdName); // Call. getNextToken(); // eat ( - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) - return 0; - Args.push_back(Arg); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; if (CurTok == ')') break; @@ -333,60 +355,41 @@ static ExprAST *ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - return new CallExprAST(IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} - -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) - return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } /// ifexpr ::= 'if' expression 'then' expression 'else' expression -static ExprAST *ParseIfExpr() { +static std::unique_ptr<ExprAST> ParseIfExpr() { getNextToken(); // eat the if. // condition. - ExprAST *Cond = ParseExpression(); + auto Cond = ParseExpression(); if (!Cond) - return 0; + return nullptr; if (CurTok != tok_then) return Error("expected then"); getNextToken(); // eat the then - ExprAST *Then = ParseExpression(); - if (Then == 0) - return 0; + auto Then = ParseExpression(); + if (!Then) + return nullptr; if (CurTok != tok_else) return Error("expected else"); getNextToken(); - ExprAST *Else = ParseExpression(); + auto Else = ParseExpression(); if (!Else) - return 0; + return nullptr; - return new IfExprAST(Cond, Then, Else); + return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), + std::move(Else)); } /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression -static ExprAST *ParseForExpr() { +static std::unique_ptr<ExprAST> ParseForExpr() { getNextToken(); // eat the for. if (CurTok != tok_identifier) @@ -399,43 +402,44 @@ static ExprAST *ParseForExpr() { return Error("expected '=' after for"); getNextToken(); // eat '='. - ExprAST *Start = ParseExpression(); - if (Start == 0) - return 0; + auto Start = ParseExpression(); + if (!Start) + return nullptr; if (CurTok != ',') return Error("expected ',' after for start value"); getNextToken(); - ExprAST *End = ParseExpression(); - if (End == 0) - return 0; + auto End = ParseExpression(); + if (!End) + return nullptr; // The step value is optional. - ExprAST *Step = 0; + std::unique_ptr<ExprAST> Step; if (CurTok == ',') { getNextToken(); Step = ParseExpression(); - if (Step == 0) - return 0; + if (!Step) + return nullptr; } if (CurTok != tok_in) return Error("expected 'in' after for"); getNextToken(); // eat 'in'. - ExprAST *Body = ParseExpression(); - if (Body == 0) - return 0; + auto Body = ParseExpression(); + if (!Body) + return nullptr; - return new ForExprAST(IdName, Start, End, Step, Body); + return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End), + std::move(Step), std::move(Body)); } /// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression -static ExprAST *ParseVarExpr() { +static std::unique_ptr<ExprAST> ParseVarExpr() { getNextToken(); // eat the var. - std::vector<std::pair<std::string, ExprAST *> > VarNames; + std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames; // At least one variable name is required. if (CurTok != tok_identifier) @@ -446,16 +450,16 @@ static ExprAST *ParseVarExpr() { getNextToken(); // eat identifier. // Read the optional initializer. - ExprAST *Init = 0; + std::unique_ptr<ExprAST> Init = nullptr; if (CurTok == '=') { getNextToken(); // eat the '='. Init = ParseExpression(); - if (Init == 0) - return 0; + if (!Init) + return nullptr; } - VarNames.push_back(std::make_pair(Name, Init)); + VarNames.push_back(std::make_pair(Name, std::move(Init))); // End of var list, exit loop. if (CurTok != ',') @@ -471,11 +475,11 @@ static ExprAST *ParseVarExpr() { return Error("expected 'in' keyword after 'var'"); getNextToken(); // eat 'in'. - ExprAST *Body = ParseExpression(); - if (Body == 0) - return 0; + auto Body = ParseExpression(); + if (!Body) + return nullptr; - return new VarExprAST(VarNames, Body); + return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body)); } /// primary @@ -485,7 +489,7 @@ static ExprAST *ParseVarExpr() { /// ::= ifexpr /// ::= forexpr /// ::= varexpr -static ExprAST *ParsePrimary() { +static std::unique_ptr<ExprAST> ParsePrimary() { switch (CurTok) { default: return Error("unknown token when expecting an expression"); @@ -507,7 +511,7 @@ static ExprAST *ParsePrimary() { /// unary /// ::= primary /// ::= '!' unary -static ExprAST *ParseUnary() { +static std::unique_ptr<ExprAST> ParseUnary() { // If the current token is not an operator, it must be a primary expr. if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') return ParsePrimary(); @@ -515,14 +519,15 @@ static ExprAST *ParseUnary() { // If this is a unary operator, read it. int Opc = CurTok; getNextToken(); - if (ExprAST *Operand = ParseUnary()) - return new UnaryExprAST(Opc, Operand); - return 0; + if (auto Operand = ParseUnary()) + return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand)); + return nullptr; } /// binoprhs /// ::= ('+' unary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { +static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, + std::unique_ptr<ExprAST> LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -537,40 +542,41 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { getNextToken(); // eat binop // Parse the unary expression after the binary operator. - ExprAST *RHS = ParseUnary(); + auto RHS = ParseUnary(); if (!RHS) - return 0; + return nullptr; // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec + 1, RHS); - if (RHS == 0) - return 0; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } // Merge LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS); + LHS = + llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } } /// expression /// ::= unary binoprhs /// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParseUnary(); +static std::unique_ptr<ExprAST> ParseExpression() { + auto LHS = ParseUnary(); if (!LHS) - return 0; + return nullptr; - return ParseBinOpRHS(0, LHS); + return ParseBinOpRHS(0, std::move(LHS)); } /// prototype /// ::= id '(' id* ')' /// ::= binary LETTER number? (id, id) /// ::= unary LETTER (id) -static PrototypeAST *ParsePrototype() { +static std::unique_ptr<PrototypeAST> ParsePrototype() { std::string FnName; unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. @@ -628,33 +634,35 @@ static PrototypeAST *ParsePrototype() { if (Kind && ArgNames.size() != Kind) return ErrorP("Invalid number of operands for operator"); - return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence); + return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0, + BinaryPrecedence); } /// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { +static std::unique_ptr<FunctionAST> ParseDefinition() { getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) - return 0; + auto Proto = ParsePrototype(); + if (!Proto) + return nullptr; - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; + if (auto E = ParseExpression()) + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); + return nullptr; } /// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { - if (ExprAST *E = ParseExpression()) { +static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { + if (auto E = ParseExpression()) { // Make an anonymous proto. - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); - return new FunctionAST(Proto, E); + auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr", + std::vector<std::string>()); + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); } - return 0; + return nullptr; } /// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { +static std::unique_ptr<PrototypeAST> ParseExtern() { getNextToken(); // eat extern. return ParsePrototype(); } @@ -663,14 +671,31 @@ static PrototypeAST *ParseExtern() { // Code Generation //===----------------------------------------------------------------------===// -static Module *TheModule; +static std::unique_ptr<Module> TheModule; static IRBuilder<> Builder(getGlobalContext()); static std::map<std::string, AllocaInst *> NamedValues; -static legacy::FunctionPassManager *TheFPM; +static std::unique_ptr<legacy::FunctionPassManager> TheFPM; +static std::unique_ptr<KaleidoscopeJIT> TheJIT; +static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos; Value *ErrorV(const char *Str) { Error(Str); - return 0; + return nullptr; +} + +Function *getFunction(std::string Name) { + // First, see if the function has already been added to the current module. + if (auto *F = TheModule->getFunction(Name)) + return F; + + // If not, check whether we can codegen the declaration from some existing + // prototype. + auto FI = FunctionProtos.find(Name); + if (FI != FunctionProtos.end()) + return FI->second->codegen(); + + // If no existing prototype exists, return null. + return nullptr; } /// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of @@ -679,64 +704,64 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName) { IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin()); - return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, + return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr, VarName.c_str()); } -Value *NumberExprAST::Codegen() { +Value *NumberExprAST::codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); } -Value *VariableExprAST::Codegen() { +Value *VariableExprAST::codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - if (V == 0) + if (!V) return ErrorV("Unknown variable name"); // Load the value. return Builder.CreateLoad(V, Name.c_str()); } -Value *UnaryExprAST::Codegen() { - Value *OperandV = Operand->Codegen(); - if (OperandV == 0) - return 0; +Value *UnaryExprAST::codegen() { + Value *OperandV = Operand->codegen(); + if (!OperandV) + return nullptr; - Function *F = TheModule->getFunction(std::string("unary") + Opcode); - if (F == 0) + Function *F = getFunction(std::string("unary") + Opcode); + if (!F) return ErrorV("Unknown unary operator"); return Builder.CreateCall(F, OperandV, "unop"); } -Value *BinaryExprAST::Codegen() { +Value *BinaryExprAST::codegen() { // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { // Assignment requires the LHS to be an identifier. // This assume we're building without RTTI because LLVM builds that way by // default. If you build LLVM with RTTI this can be changed to a // dynamic_cast for automatic error checking. - VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS); + VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get()); if (!LHSE) return ErrorV("destination of '=' must be a variable"); // Codegen the RHS. - Value *Val = RHS->Codegen(); - if (Val == 0) - return 0; + Value *Val = RHS->codegen(); + if (!Val) + return nullptr; // Look up the name. Value *Variable = NamedValues[LHSE->getName()]; - if (Variable == 0) + if (!Variable) return ErrorV("Unknown variable name"); Builder.CreateStore(Val, Variable); return Val; } - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); - if (L == 0 || R == 0) - return 0; + Value *L = LHS->codegen(); + Value *R = RHS->codegen(); + if (!L || !R) + return nullptr; switch (Op) { case '+': @@ -756,17 +781,17 @@ Value *BinaryExprAST::Codegen() { // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. - Function *F = TheModule->getFunction(std::string("binary") + Op); + Function *F = getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; + Value *Ops[] = {L, R}; return Builder.CreateCall(F, Ops, "binop"); } -Value *CallExprAST::Codegen() { +Value *CallExprAST::codegen() { // Look up the name in the global module table. - Function *CalleeF = TheModule->getFunction(Callee); - if (CalleeF == 0) + Function *CalleeF = getFunction(Callee); + if (!CalleeF) return ErrorV("Unknown function referenced"); // If argument mismatch error. @@ -775,18 +800,18 @@ Value *CallExprAST::Codegen() { std::vector<Value *> ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) - return 0; + ArgsV.push_back(Args[i]->codegen()); + if (!ArgsV.back()) + return nullptr; } return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } -Value *IfExprAST::Codegen() { - Value *CondV = Cond->Codegen(); - if (CondV == 0) - return 0; +Value *IfExprAST::codegen() { + Value *CondV = Cond->codegen(); + if (!CondV) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. CondV = Builder.CreateFCmpONE( @@ -806,9 +831,9 @@ Value *IfExprAST::Codegen() { // Emit then value. Builder.SetInsertPoint(ThenBB); - Value *ThenV = Then->Codegen(); - if (ThenV == 0) - return 0; + Value *ThenV = Then->codegen(); + if (!ThenV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. @@ -818,9 +843,9 @@ Value *IfExprAST::Codegen() { TheFunction->getBasicBlockList().push_back(ElseBB); Builder.SetInsertPoint(ElseBB); - Value *ElseV = Else->Codegen(); - if (ElseV == 0) - return 0; + Value *ElseV = Else->codegen(); + if (!ElseV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. @@ -837,36 +862,35 @@ Value *IfExprAST::Codegen() { return PN; } -Value *ForExprAST::Codegen() { - // Output this as: - // var = alloca double - // ... - // start = startexpr - // store start -> var - // goto loop - // loop: - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // endcond = endexpr - // - // curvar = load var - // nextvar = curvar + step - // store nextvar -> var - // br endcond, loop, endloop - // outloop: - +// Output for-loop as: +// var = alloca double +// ... +// start = startexpr +// store start -> var +// goto loop +// loop: +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// endcond = endexpr +// +// curvar = load var +// nextvar = curvar + step +// store nextvar -> var +// br endcond, loop, endloop +// outloop: +Value *ForExprAST::codegen() { Function *TheFunction = Builder.GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); // Emit the start code first, without 'variable' in scope. - Value *StartVal = Start->Codegen(); - if (StartVal == 0) - return 0; + Value *StartVal = Start->codegen(); + if (!StartVal) + return nullptr; // Store the value into the alloca. Builder.CreateStore(StartVal, Alloca); @@ -890,24 +914,24 @@ Value *ForExprAST::Codegen() { // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. - if (Body->Codegen() == 0) - return 0; + if (!Body->codegen()) + return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { - StepVal = Step->Codegen(); - if (StepVal == 0) - return 0; + StepVal = Step->codegen(); + if (!StepVal) + return nullptr; } else { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); } // Compute the end condition. - Value *EndCond = End->Codegen(); - if (EndCond == 0) - return EndCond; + Value *EndCond = End->codegen(); + if (!EndCond) + return nullptr; // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. @@ -939,7 +963,7 @@ Value *ForExprAST::Codegen() { return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } -Value *VarExprAST::Codegen() { +Value *VarExprAST::codegen() { std::vector<AllocaInst *> OldBindings; Function *TheFunction = Builder.GetInsertBlock()->getParent(); @@ -947,7 +971,7 @@ Value *VarExprAST::Codegen() { // Register all variables and emit their initializer. for (unsigned i = 0, e = VarNames.size(); i != e; ++i) { const std::string &VarName = VarNames[i].first; - ExprAST *Init = VarNames[i].second; + ExprAST *Init = VarNames[i].second.get(); // Emit the initializer before adding the variable to scope, this prevents // the initializer from referencing the variable itself, and permits stuff @@ -956,9 +980,9 @@ Value *VarExprAST::Codegen() { // var a = a in ... # refers to outer 'a'. Value *InitVal; if (Init) { - InitVal = Init->Codegen(); - if (InitVal == 0) - return 0; + InitVal = Init->codegen(); + if (!InitVal) + return nullptr; } else { // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); } @@ -975,9 +999,9 @@ Value *VarExprAST::Codegen() { } // Codegen the body, now that all vars are in scope. - Value *BodyVal = Body->Codegen(); - if (BodyVal == 0) - return 0; + Value *BodyVal = Body->codegen(); + if (!BodyVal) + return nullptr; // Pop all our variables from scope. for (unsigned i = 0, e = VarNames.size(); i != e; ++i) @@ -987,7 +1011,7 @@ Value *VarExprAST::Codegen() { return BodyVal; } -Function *PrototypeAST::Codegen() { +Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); @@ -995,79 +1019,54 @@ Function *PrototypeAST::Codegen() { FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); Function *F = - Function::Create(FT, Function::ExternalLinkage, Name, TheModule); - - // If F conflicted, there was already something named 'Name'. If it has a - // body, don't allow redefinition or reextern. - if (F->getName() != Name) { - // Delete the one we just made and get the existing one. - F->eraseFromParent(); - F = TheModule->getFunction(Name); - - // If F already has a body, reject this. - if (!F->empty()) { - ErrorF("redefinition of function"); - return 0; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return 0; - } - } + Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get()); // Set names for all arguments. unsigned Idx = 0; - for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); - ++AI, ++Idx) - AI->setName(Args[Idx]); + for (auto &Arg : F->args()) + Arg.setName(Args[Idx++]); return F; } -/// CreateArgumentAllocas - Create an alloca for each argument and register the -/// argument in the symbol table so that references to it will succeed. -void PrototypeAST::CreateArgumentAllocas(Function *F) { - Function::arg_iterator AI = F->arg_begin(); - for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) { - // Create an alloca for this variable. - AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); - - // Store the initial value into the alloca. - Builder.CreateStore(AI, Alloca); - - // Add arguments to variable symbol table. - NamedValues[Args[Idx]] = Alloca; - } -} - -Function *FunctionAST::Codegen() { - NamedValues.clear(); - - Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; +Function *FunctionAST::codegen() { + // Transfer ownership of the prototype to the FunctionProtos map, but keep a + // reference to it for use below. + auto &P = *Proto; + FunctionProtos[Proto->getName()] = std::move(Proto); + Function *TheFunction = getFunction(P.getName()); + if (!TheFunction) + return nullptr; // If this is an operator, install it. - if (Proto->isBinaryOp()) - BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence(); + if (P.isBinaryOp()) + BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence(); // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); - // Add all arguments to the symbol table and create their allocas. - Proto->CreateArgumentAllocas(TheFunction); + // Record the function arguments in the NamedValues map. + NamedValues.clear(); + for (auto &Arg : TheFunction->args()) { + // Create an alloca for this variable. + AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName()); + + // Store the initial value into the alloca. + Builder.CreateStore(&Arg, Alloca); + + // Add arguments to variable symbol table. + NamedValues[Arg.getName()] = Alloca; + } - if (Value *RetVal = Body->Codegen()) { + if (Value *RetVal = Body->codegen()) { // Finish off the function. Builder.CreateRet(RetVal); // Validate the generated code, checking for consistency. verifyFunction(*TheFunction); - // Optimize the function. + // Run the optimizer on the function. TheFPM->run(*TheFunction); return TheFunction; @@ -1076,22 +1075,42 @@ Function *FunctionAST::Codegen() { // Error reading body, remove function. TheFunction->eraseFromParent(); - if (Proto->isBinaryOp()) + if (P.isBinaryOp()) BinopPrecedence.erase(Proto->getOperatorName()); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// // Top-Level parsing and JIT Driver //===----------------------------------------------------------------------===// -static ExecutionEngine *TheExecutionEngine; +static void InitializeModuleAndPassManager() { + // Open a new module. + TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext()); + TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout()); + + // Create a new pass manager attached to it. + TheFPM = llvm::make_unique<legacy::FunctionPassManager>(TheModule.get()); + + // Do simple "peephole" optimizations and bit-twiddling optzns. + TheFPM->add(createInstructionCombiningPass()); + // Reassociate expressions. + TheFPM->add(createReassociatePass()); + // Eliminate Common SubExpressions. + TheFPM->add(createGVNPass()); + // Simplify the control flow graph (deleting unreachable blocks, etc). + TheFPM->add(createCFGSimplificationPass()); + + TheFPM->doInitialization(); +} static void HandleDefinition() { - if (FunctionAST *F = ParseDefinition()) { - if (Function *LF = F->Codegen()) { + if (auto FnAST = ParseDefinition()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read function definition:"); - LF->dump(); + FnIR->dump(); + TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); } } else { // Skip token for error recovery. @@ -1100,10 +1119,11 @@ static void HandleDefinition() { } static void HandleExtern() { - if (PrototypeAST *P = ParseExtern()) { - if (Function *F = P->Codegen()) { + if (auto ProtoAST = ParseExtern()) { + if (auto *FnIR = ProtoAST->codegen()) { fprintf(stderr, "Read extern: "); - F->dump(); + FnIR->dump(); + FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST); } } else { // Skip token for error recovery. @@ -1113,16 +1133,25 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - if (Function *LF = F->Codegen()) { - TheExecutionEngine->finalizeObject(); - // JIT the function, returning a function pointer. - void *FPtr = TheExecutionEngine->getPointerToFunction(LF); - - // Cast it to the right type (takes no arguments, returns a double) so we - // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)FPtr; + if (auto FnAST = ParseTopLevelExpr()) { + if (FnAST->codegen()) { + + // JIT the module containing the anonymous expression, keeping a handle so + // we can free it later. + auto H = TheJIT->addModule(std::move(TheModule)); + InitializeModuleAndPassManager(); + + // Search the JIT for the __anon_expr symbol. + auto ExprSymbol = TheJIT->findSymbol("__anon_expr"); + assert(ExprSymbol && "Function not found"); + + // Get the symbol's address and cast it to the right type (takes no + // arguments, returns a double) so we can call it as a native function. + double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); fprintf(stderr, "Evaluated to %f\n", FP()); + + // Delete the anonymous expression module from the JIT. + TheJIT->removeModule(H); } } else { // Skip token for error recovery. @@ -1137,9 +1166,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -1159,13 +1188,13 @@ static void MainLoop() { /// putchard - putchar that takes a double and returns 0. extern "C" double putchard(double X) { - putchar((char)X); + fputc((char)X, stderr); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. extern "C" double printd(double X) { - printf("%f\n", X); + fprintf(stderr, "%f\n", X); return 0; } @@ -1177,7 +1206,6 @@ int main() { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); - LLVMContext &Context = getGlobalContext(); // Install standard binary operators. // 1 is lowest precedence. @@ -1191,52 +1219,12 @@ int main() { fprintf(stderr, "ready> "); getNextToken(); - // Make the module, which holds all the code. - std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context); - TheModule = Owner.get(); - - // Create the JIT. This takes ownership of the module. - std::string ErrStr; - TheExecutionEngine = - EngineBuilder(std::move(Owner)) - .setErrorStr(&ErrStr) - .setMCJITMemoryManager(llvm::make_unique<SectionMemoryManager>()) - .create(); - if (!TheExecutionEngine) { - fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); - exit(1); - } + TheJIT = llvm::make_unique<KaleidoscopeJIT>(); - legacy::FunctionPassManager OurFPM(TheModule); - - // Set up the optimizer pipeline. Start with registering info about how the - // target lays out data structures. - TheModule->setDataLayout(*TheExecutionEngine->getDataLayout()); - // Provide basic AliasAnalysis support for GVN. - OurFPM.add(createBasicAliasAnalysisPass()); - // Promote allocas to registers. - OurFPM.add(createPromoteMemoryToRegisterPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - OurFPM.add(createInstructionCombiningPass()); - // Reassociate expressions. - OurFPM.add(createReassociatePass()); - // Eliminate Common SubExpressions. - OurFPM.add(createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - OurFPM.add(createCFGSimplificationPass()); - - OurFPM.doInitialization(); - - // Set the global so the code gen can use this. - TheFPM = &OurFPM; + InitializeModuleAndPassManager(); // Run the main "interpreter loop" now. MainLoop(); - TheFPM = 0; - - // Print out all of the generated code. - TheModule->dump(); - return 0; } diff --git a/examples/Kaleidoscope/Chapter8/CMakeLists.txt b/examples/Kaleidoscope/Chapter8/CMakeLists.txt index f94ed7436189..d9b5cc421be3 100644 --- a/examples/Kaleidoscope/Chapter8/CMakeLists.txt +++ b/examples/Kaleidoscope/Chapter8/CMakeLists.txt @@ -1,8 +1,7 @@ set(LLVM_LINK_COMPONENTS Core ExecutionEngine - MCJIT - RuntimeDyld + Object Support native ) @@ -10,3 +9,5 @@ set(LLVM_LINK_COMPONENTS add_kaleidoscope_chapter(Kaleidoscope-Ch8 toy.cpp ) + +export_executable_symbols(Kaleidoscope-Ch8) diff --git a/examples/Kaleidoscope/Chapter8/toy.cpp b/examples/Kaleidoscope/Chapter8/toy.cpp index 71bc2f684027..289209b3df49 100644 --- a/examples/Kaleidoscope/Chapter8/toy.cpp +++ b/examples/Kaleidoscope/Chapter8/toy.cpp @@ -1,27 +1,23 @@ #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/Passes.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/MCJIT.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DIBuilder.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" -#include "llvm/Support/Host.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include <cctype> #include <cstdio> -#include <iostream> #include <map> #include <string> #include <vector> +#include "../include/KaleidoscopeJIT.h" + using namespace llvm; +using namespace llvm::orc; //===----------------------------------------------------------------------===// // Lexer @@ -96,20 +92,17 @@ struct DebugInfo { DICompileUnit *TheCU; DIType *DblTy; std::vector<DIScope *> LexicalBlocks; - std::map<const PrototypeAST *, DIScope *> FnScopeMap; void emitLocation(ExprAST *AST); DIType *getDoubleTy(); } KSDbgInfo; -static std::string IdentifierStr; // Filled in if tok_identifier -static double NumVal; // Filled in if tok_number struct SourceLocation { int Line; int Col; }; static SourceLocation CurLoc; -static SourceLocation LexLoc = { 1, 0 }; +static SourceLocation LexLoc = {1, 0}; static int advance() { int LastChar = getchar(); @@ -122,6 +115,9 @@ static int advance() { return LastChar; } +static std::string IdentifierStr; // Filled in if tok_identifier +static double NumVal; // Filled in if tok_number + /// gettok - Return the next token from standard input. static int gettok() { static int LastChar = ' '; @@ -167,7 +163,7 @@ static int gettok() { LastChar = advance(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -196,7 +192,7 @@ static int gettok() { //===----------------------------------------------------------------------===// namespace { -std::ostream &indent(std::ostream &O, int size) { +raw_ostream &indent(raw_ostream &O, int size) { return O << std::string(size, ' '); } @@ -205,14 +201,14 @@ class ExprAST { SourceLocation Loc; public: + ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {} + virtual ~ExprAST() {} + virtual Value *codegen() = 0; int getLine() const { return Loc.Line; } int getCol() const { return Loc.Col; } - ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {} - virtual std::ostream &dump(std::ostream &out, int ind) { + virtual raw_ostream &dump(raw_ostream &out, int ind) { return out << ':' << getLine() << ':' << getCol() << '\n'; } - virtual ~ExprAST() {} - virtual Value *Codegen() = 0; }; /// NumberExprAST - Expression class for numeric literals like "1.0". @@ -220,11 +216,11 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} - std::ostream &dump(std::ostream &out, int ind) override { + NumberExprAST(double Val) : Val(Val) {} + raw_ostream &dump(raw_ostream &out, int ind) override { return ExprAST::dump(out << Val, ind); } - Value *Codegen() override; + Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". @@ -232,93 +228,99 @@ class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(SourceLocation Loc, const std::string &name) - : ExprAST(Loc), Name(name) {} + VariableExprAST(SourceLocation Loc, const std::string &Name) + : ExprAST(Loc), Name(Name) {} const std::string &getName() const { return Name; } - std::ostream &dump(std::ostream &out, int ind) override { + Value *codegen() override; + raw_ostream &dump(raw_ostream &out, int ind) override { return ExprAST::dump(out << Name, ind); } - Value *Codegen() override; }; /// UnaryExprAST - Expression class for a unary operator. class UnaryExprAST : public ExprAST { char Opcode; - ExprAST *Operand; + std::unique_ptr<ExprAST> Operand; public: - UnaryExprAST(char opcode, ExprAST *operand) - : Opcode(opcode), Operand(operand) {} - std::ostream &dump(std::ostream &out, int ind) override { + UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) + : Opcode(Opcode), Operand(std::move(Operand)) {} + Value *codegen() override; + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "unary" << Opcode, ind); Operand->dump(out, ind + 1); return out; } - Value *Codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { char Op; - ExprAST *LHS, *RHS; + std::unique_ptr<ExprAST> LHS, RHS; public: - BinaryExprAST(SourceLocation Loc, char op, ExprAST *lhs, ExprAST *rhs) - : ExprAST(Loc), Op(op), LHS(lhs), RHS(rhs) {} - std::ostream &dump(std::ostream &out, int ind) override { + BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr<ExprAST> LHS, + std::unique_ptr<ExprAST> RHS) + : ExprAST(Loc), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} + Value *codegen() override; + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "binary" << Op, ind); LHS->dump(indent(out, ind) << "LHS:", ind + 1); RHS->dump(indent(out, ind) << "RHS:", ind + 1); return out; } - Value *Codegen() override; }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; public: - CallExprAST(SourceLocation Loc, const std::string &callee, - std::vector<ExprAST *> &args) - : ExprAST(Loc), Callee(callee), Args(args) {} - std::ostream &dump(std::ostream &out, int ind) override { + CallExprAST(SourceLocation Loc, const std::string &Callee, + std::vector<std::unique_ptr<ExprAST>> Args) + : ExprAST(Loc), Callee(Callee), Args(std::move(Args)) {} + Value *codegen() override; + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "call " << Callee, ind); - for (ExprAST *Arg : Args) + for (const auto &Arg : Args) Arg->dump(indent(out, ind + 1), ind + 1); return out; } - Value *Codegen() override; }; /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { - ExprAST *Cond, *Then, *Else; + std::unique_ptr<ExprAST> Cond, Then, Else; public: - IfExprAST(SourceLocation Loc, ExprAST *cond, ExprAST *then, ExprAST *_else) - : ExprAST(Loc), Cond(cond), Then(then), Else(_else) {} - std::ostream &dump(std::ostream &out, int ind) override { + IfExprAST(SourceLocation Loc, std::unique_ptr<ExprAST> Cond, + std::unique_ptr<ExprAST> Then, std::unique_ptr<ExprAST> Else) + : ExprAST(Loc), Cond(std::move(Cond)), Then(std::move(Then)), + Else(std::move(Else)) {} + Value *codegen() override; + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "if", ind); Cond->dump(indent(out, ind) << "Cond:", ind + 1); Then->dump(indent(out, ind) << "Then:", ind + 1); Else->dump(indent(out, ind) << "Else:", ind + 1); return out; } - Value *Codegen() override; }; /// ForExprAST - Expression class for for/in. class ForExprAST : public ExprAST { std::string VarName; - ExprAST *Start, *End, *Step, *Body; + std::unique_ptr<ExprAST> Start, End, Step, Body; public: - ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end, - ExprAST *step, ExprAST *body) - : VarName(varname), Start(start), End(end), Step(step), Body(body) {} - std::ostream &dump(std::ostream &out, int ind) override { + ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start, + std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step, + std::unique_ptr<ExprAST> Body) + : VarName(VarName), Start(std::move(Start)), End(std::move(End)), + Step(std::move(Step)), Body(std::move(Body)) {} + Value *codegen() override; + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "for", ind); Start->dump(indent(out, ind) << "Cond:", ind + 1); End->dump(indent(out, ind) << "End:", ind + 1); @@ -326,47 +328,49 @@ public: Body->dump(indent(out, ind) << "Body:", ind + 1); return out; } - Value *Codegen() override; }; /// VarExprAST - Expression class for var/in class VarExprAST : public ExprAST { - std::vector<std::pair<std::string, ExprAST *> > VarNames; - ExprAST *Body; + std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames; + std::unique_ptr<ExprAST> Body; public: - VarExprAST(const std::vector<std::pair<std::string, ExprAST *> > &varnames, - ExprAST *body) - : VarNames(varnames), Body(body) {} - - std::ostream &dump(std::ostream &out, int ind) override { + VarExprAST( + std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames, + std::unique_ptr<ExprAST> Body) + : VarNames(std::move(VarNames)), Body(std::move(Body)) {} + Value *codegen() override; + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "var", ind); for (const auto &NamedVar : VarNames) NamedVar.second->dump(indent(out, ind) << NamedVar.first << ':', ind + 1); Body->dump(indent(out, ind) << "Body:", ind + 1); return out; } - Value *Codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, -/// which captures its argument names as well as if it is an operator. +/// which captures its name, and its argument names (thus implicitly the number +/// of arguments the function takes), as well as if it is an operator. class PrototypeAST { std::string Name; std::vector<std::string> Args; - bool isOperator; + bool IsOperator; unsigned Precedence; // Precedence if a binary op. int Line; public: - PrototypeAST(SourceLocation Loc, const std::string &name, - const std::vector<std::string> &args, bool isoperator = false, - unsigned prec = 0) - : Name(name), Args(args), isOperator(isoperator), Precedence(prec), - Line(Loc.Line) {} + PrototypeAST(SourceLocation Loc, const std::string &Name, + std::vector<std::string> Args, bool IsOperator = false, + unsigned Prec = 0) + : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), + Precedence(Prec), Line(Loc.Line) {} + Function *codegen(); + const std::string &getName() const { return Name; } - bool isUnaryOp() const { return isOperator && Args.size() == 1; } - bool isBinaryOp() const { return isOperator && Args.size() == 2; } + bool isUnaryOp() const { return IsOperator && Args.size() == 1; } + bool isBinaryOp() const { return IsOperator && Args.size() == 2; } char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); @@ -374,29 +378,25 @@ public: } unsigned getBinaryPrecedence() const { return Precedence; } - - Function *Codegen(); - - void CreateArgumentAllocas(Function *F); - const std::vector<std::string> &getArgs() const { return Args; } + int getLine() const { return Line; } }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { - PrototypeAST *Proto; - ExprAST *Body; + std::unique_ptr<PrototypeAST> Proto; + std::unique_ptr<ExprAST> Body; public: - FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {} - - std::ostream &dump(std::ostream &out, int ind) { + FunctionAST(std::unique_ptr<PrototypeAST> Proto, + std::unique_ptr<ExprAST> Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} + Function *codegen(); + raw_ostream &dump(raw_ostream &out, int ind) { indent(out, ind) << "FunctionAST\n"; ++ind; indent(out, ind) << "Body:"; return Body ? Body->dump(out, ind) : out << "null\n"; } - - Function *Codegen(); }; } // end anonymous namespace @@ -427,25 +427,42 @@ static int GetTokPrecedence() { } /// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { +std::unique_ptr<ExprAST> Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str); - return 0; + return nullptr; } -PrototypeAST *ErrorP(const char *Str) { + +std::unique_ptr<PrototypeAST> ErrorP(const char *Str) { Error(Str); - return 0; + return nullptr; } -FunctionAST *ErrorF(const char *Str) { - Error(Str); - return 0; + +static std::unique_ptr<ExprAST> ParseExpression(); + +/// numberexpr ::= number +static std::unique_ptr<ExprAST> ParseNumberExpr() { + auto Result = llvm::make_unique<NumberExprAST>(NumVal); + getNextToken(); // consume the number + return std::move(Result); } -static ExprAST *ParseExpression(); +/// parenexpr ::= '(' expression ')' +static std::unique_ptr<ExprAST> ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { +static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; SourceLocation LitLoc = CurLoc; @@ -453,17 +470,17 @@ static ExprAST *ParseIdentifierExpr() { getNextToken(); // eat identifier. if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(LitLoc, IdName); + return llvm::make_unique<VariableExprAST>(LitLoc, IdName); // Call. getNextToken(); // eat ( - std::vector<ExprAST *> Args; + std::vector<std::unique_ptr<ExprAST>> Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) - return 0; - Args.push_back(Arg); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; if (CurTok == ')') break; @@ -477,62 +494,43 @@ static ExprAST *ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - return new CallExprAST(LitLoc, IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} - -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) - return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; + return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args)); } /// ifexpr ::= 'if' expression 'then' expression 'else' expression -static ExprAST *ParseIfExpr() { +static std::unique_ptr<ExprAST> ParseIfExpr() { SourceLocation IfLoc = CurLoc; getNextToken(); // eat the if. // condition. - ExprAST *Cond = ParseExpression(); + auto Cond = ParseExpression(); if (!Cond) - return 0; + return nullptr; if (CurTok != tok_then) return Error("expected then"); getNextToken(); // eat the then - ExprAST *Then = ParseExpression(); - if (Then == 0) - return 0; + auto Then = ParseExpression(); + if (!Then) + return nullptr; if (CurTok != tok_else) return Error("expected else"); getNextToken(); - ExprAST *Else = ParseExpression(); + auto Else = ParseExpression(); if (!Else) - return 0; + return nullptr; - return new IfExprAST(IfLoc, Cond, Then, Else); + return llvm::make_unique<IfExprAST>(IfLoc, std::move(Cond), std::move(Then), + std::move(Else)); } /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression -static ExprAST *ParseForExpr() { +static std::unique_ptr<ExprAST> ParseForExpr() { getNextToken(); // eat the for. if (CurTok != tok_identifier) @@ -545,43 +543,44 @@ static ExprAST *ParseForExpr() { return Error("expected '=' after for"); getNextToken(); // eat '='. - ExprAST *Start = ParseExpression(); - if (Start == 0) - return 0; + auto Start = ParseExpression(); + if (!Start) + return nullptr; if (CurTok != ',') return Error("expected ',' after for start value"); getNextToken(); - ExprAST *End = ParseExpression(); - if (End == 0) - return 0; + auto End = ParseExpression(); + if (!End) + return nullptr; // The step value is optional. - ExprAST *Step = 0; + std::unique_ptr<ExprAST> Step; if (CurTok == ',') { getNextToken(); Step = ParseExpression(); - if (Step == 0) - return 0; + if (!Step) + return nullptr; } if (CurTok != tok_in) return Error("expected 'in' after for"); getNextToken(); // eat 'in'. - ExprAST *Body = ParseExpression(); - if (Body == 0) - return 0; + auto Body = ParseExpression(); + if (!Body) + return nullptr; - return new ForExprAST(IdName, Start, End, Step, Body); + return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End), + std::move(Step), std::move(Body)); } /// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression -static ExprAST *ParseVarExpr() { +static std::unique_ptr<ExprAST> ParseVarExpr() { getNextToken(); // eat the var. - std::vector<std::pair<std::string, ExprAST *> > VarNames; + std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames; // At least one variable name is required. if (CurTok != tok_identifier) @@ -592,16 +591,16 @@ static ExprAST *ParseVarExpr() { getNextToken(); // eat identifier. // Read the optional initializer. - ExprAST *Init = 0; + std::unique_ptr<ExprAST> Init = nullptr; if (CurTok == '=') { getNextToken(); // eat the '='. Init = ParseExpression(); - if (Init == 0) - return 0; + if (!Init) + return nullptr; } - VarNames.push_back(std::make_pair(Name, Init)); + VarNames.push_back(std::make_pair(Name, std::move(Init))); // End of var list, exit loop. if (CurTok != ',') @@ -617,11 +616,11 @@ static ExprAST *ParseVarExpr() { return Error("expected 'in' keyword after 'var'"); getNextToken(); // eat 'in'. - ExprAST *Body = ParseExpression(); - if (Body == 0) - return 0; + auto Body = ParseExpression(); + if (!Body) + return nullptr; - return new VarExprAST(VarNames, Body); + return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body)); } /// primary @@ -631,7 +630,7 @@ static ExprAST *ParseVarExpr() { /// ::= ifexpr /// ::= forexpr /// ::= varexpr -static ExprAST *ParsePrimary() { +static std::unique_ptr<ExprAST> ParsePrimary() { switch (CurTok) { default: return Error("unknown token when expecting an expression"); @@ -653,7 +652,7 @@ static ExprAST *ParsePrimary() { /// unary /// ::= primary /// ::= '!' unary -static ExprAST *ParseUnary() { +static std::unique_ptr<ExprAST> ParseUnary() { // If the current token is not an operator, it must be a primary expr. if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') return ParsePrimary(); @@ -661,14 +660,15 @@ static ExprAST *ParseUnary() { // If this is a unary operator, read it. int Opc = CurTok; getNextToken(); - if (ExprAST *Operand = ParseUnary()) - return new UnaryExprAST(Opc, Operand); - return 0; + if (auto Operand = ParseUnary()) + return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand)); + return nullptr; } /// binoprhs /// ::= ('+' unary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { +static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, + std::unique_ptr<ExprAST> LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -684,40 +684,41 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { getNextToken(); // eat binop // Parse the unary expression after the binary operator. - ExprAST *RHS = ParseUnary(); + auto RHS = ParseUnary(); if (!RHS) - return 0; + return nullptr; // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec + 1, RHS); - if (RHS == 0) - return 0; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } // Merge LHS/RHS. - LHS = new BinaryExprAST(BinLoc, BinOp, LHS, RHS); + LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS), + std::move(RHS)); } } /// expression /// ::= unary binoprhs /// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParseUnary(); +static std::unique_ptr<ExprAST> ParseExpression() { + auto LHS = ParseUnary(); if (!LHS) - return 0; + return nullptr; - return ParseBinOpRHS(0, LHS); + return ParseBinOpRHS(0, std::move(LHS)); } /// prototype /// ::= id '(' id* ')' /// ::= binary LETTER number? (id, id) /// ::= unary LETTER (id) -static PrototypeAST *ParsePrototype() { +static std::unique_ptr<PrototypeAST> ParsePrototype() { std::string FnName; SourceLocation FnLoc = CurLoc; @@ -777,35 +778,36 @@ static PrototypeAST *ParsePrototype() { if (Kind && ArgNames.size() != Kind) return ErrorP("Invalid number of operands for operator"); - return new PrototypeAST(FnLoc, FnName, ArgNames, Kind != 0, BinaryPrecedence); + return llvm::make_unique<PrototypeAST>(FnLoc, FnName, ArgNames, Kind != 0, + BinaryPrecedence); } /// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { +static std::unique_ptr<FunctionAST> ParseDefinition() { getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) - return 0; + auto Proto = ParsePrototype(); + if (!Proto) + return nullptr; - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; + if (auto E = ParseExpression()) + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); + return nullptr; } /// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { +static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { SourceLocation FnLoc = CurLoc; - if (ExprAST *E = ParseExpression()) { + if (auto E = ParseExpression()) { // Make an anonymous proto. - PrototypeAST *Proto = - new PrototypeAST(FnLoc, "main", std::vector<std::string>()); - return new FunctionAST(Proto, E); + auto Proto = llvm::make_unique<PrototypeAST>(FnLoc, "__anon_expr", + std::vector<std::string>()); + return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E)); } - return 0; + return nullptr; } /// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { +static std::unique_ptr<PrototypeAST> ParseExtern() { getNextToken(); // eat extern. return ParsePrototype(); } @@ -814,7 +816,7 @@ static PrototypeAST *ParseExtern() { // Debug Info Support //===----------------------------------------------------------------------===// -static DIBuilder *DBuilder; +static std::unique_ptr<DIBuilder> DBuilder; DIType *DebugInfo::getDoubleTy() { if (DblTy) @@ -846,21 +848,36 @@ static DISubroutineType *CreateFunctionType(unsigned NumArgs, DIFile *Unit) { for (unsigned i = 0, e = NumArgs; i != e; ++i) EltTys.push_back(DblTy); - return DBuilder->createSubroutineType(Unit, - DBuilder->getOrCreateTypeArray(EltTys)); + return DBuilder->createSubroutineType(DBuilder->getOrCreateTypeArray(EltTys)); } //===----------------------------------------------------------------------===// // Code Generation //===----------------------------------------------------------------------===// -static Module *TheModule; +static std::unique_ptr<Module> TheModule; static std::map<std::string, AllocaInst *> NamedValues; -static legacy::FunctionPassManager *TheFPM; +static std::unique_ptr<KaleidoscopeJIT> TheJIT; +static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos; Value *ErrorV(const char *Str) { Error(Str); - return 0; + return nullptr; +} + +Function *getFunction(std::string Name) { + // First, see if the function has already been added to the current module. + if (auto *F = TheModule->getFunction(Name)) + return F; + + // If not, check whether we can codegen the declaration from some existing + // prototype. + auto FI = FunctionProtos.find(Name); + if (FI != FunctionProtos.end()) + return FI->second->codegen(); + + // If no existing prototype exists, return null. + return nullptr; } /// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of @@ -869,19 +886,19 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName) { IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin()); - return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, + return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr, VarName.c_str()); } -Value *NumberExprAST::Codegen() { +Value *NumberExprAST::codegen() { KSDbgInfo.emitLocation(this); return ConstantFP::get(getGlobalContext(), APFloat(Val)); } -Value *VariableExprAST::Codegen() { +Value *VariableExprAST::codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - if (V == 0) + if (!V) return ErrorV("Unknown variable name"); KSDbgInfo.emitLocation(this); @@ -889,20 +906,20 @@ Value *VariableExprAST::Codegen() { return Builder.CreateLoad(V, Name.c_str()); } -Value *UnaryExprAST::Codegen() { - Value *OperandV = Operand->Codegen(); - if (OperandV == 0) - return 0; +Value *UnaryExprAST::codegen() { + Value *OperandV = Operand->codegen(); + if (!OperandV) + return nullptr; - Function *F = TheModule->getFunction(std::string("unary") + Opcode); - if (F == 0) + Function *F = getFunction(std::string("unary") + Opcode); + if (!F) return ErrorV("Unknown unary operator"); KSDbgInfo.emitLocation(this); return Builder.CreateCall(F, OperandV, "unop"); } -Value *BinaryExprAST::Codegen() { +Value *BinaryExprAST::codegen() { KSDbgInfo.emitLocation(this); // Special case '=' because we don't want to emit the LHS as an expression. @@ -911,27 +928,27 @@ Value *BinaryExprAST::Codegen() { // This assume we're building without RTTI because LLVM builds that way by // default. If you build LLVM with RTTI this can be changed to a // dynamic_cast for automatic error checking. - VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS); + VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get()); if (!LHSE) return ErrorV("destination of '=' must be a variable"); // Codegen the RHS. - Value *Val = RHS->Codegen(); - if (Val == 0) - return 0; + Value *Val = RHS->codegen(); + if (!Val) + return nullptr; // Look up the name. Value *Variable = NamedValues[LHSE->getName()]; - if (Variable == 0) + if (!Variable) return ErrorV("Unknown variable name"); Builder.CreateStore(Val, Variable); return Val; } - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); - if (L == 0 || R == 0) - return 0; + Value *L = LHS->codegen(); + Value *R = RHS->codegen(); + if (!L || !R) + return nullptr; switch (Op) { case '+': @@ -951,19 +968,19 @@ Value *BinaryExprAST::Codegen() { // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. - Function *F = TheModule->getFunction(std::string("binary") + Op); + Function *F = getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; + Value *Ops[] = {L, R}; return Builder.CreateCall(F, Ops, "binop"); } -Value *CallExprAST::Codegen() { +Value *CallExprAST::codegen() { KSDbgInfo.emitLocation(this); // Look up the name in the global module table. - Function *CalleeF = TheModule->getFunction(Callee); - if (CalleeF == 0) + Function *CalleeF = getFunction(Callee); + if (!CalleeF) return ErrorV("Unknown function referenced"); // If argument mismatch error. @@ -972,20 +989,20 @@ Value *CallExprAST::Codegen() { std::vector<Value *> ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) - return 0; + ArgsV.push_back(Args[i]->codegen()); + if (!ArgsV.back()) + return nullptr; } return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } -Value *IfExprAST::Codegen() { +Value *IfExprAST::codegen() { KSDbgInfo.emitLocation(this); - Value *CondV = Cond->Codegen(); - if (CondV == 0) - return 0; + Value *CondV = Cond->codegen(); + if (!CondV) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. CondV = Builder.CreateFCmpONE( @@ -1005,9 +1022,9 @@ Value *IfExprAST::Codegen() { // Emit then value. Builder.SetInsertPoint(ThenBB); - Value *ThenV = Then->Codegen(); - if (ThenV == 0) - return 0; + Value *ThenV = Then->codegen(); + if (!ThenV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. @@ -1017,9 +1034,9 @@ Value *IfExprAST::Codegen() { TheFunction->getBasicBlockList().push_back(ElseBB); Builder.SetInsertPoint(ElseBB); - Value *ElseV = Else->Codegen(); - if (ElseV == 0) - return 0; + Value *ElseV = Else->codegen(); + if (!ElseV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. @@ -1036,27 +1053,26 @@ Value *IfExprAST::Codegen() { return PN; } -Value *ForExprAST::Codegen() { - // Output this as: - // var = alloca double - // ... - // start = startexpr - // store start -> var - // goto loop - // loop: - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // endcond = endexpr - // - // curvar = load var - // nextvar = curvar + step - // store nextvar -> var - // br endcond, loop, endloop - // outloop: - +// Output for-loop as: +// var = alloca double +// ... +// start = startexpr +// store start -> var +// goto loop +// loop: +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// endcond = endexpr +// +// curvar = load var +// nextvar = curvar + step +// store nextvar -> var +// br endcond, loop, endloop +// outloop: +Value *ForExprAST::codegen() { Function *TheFunction = Builder.GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. @@ -1065,9 +1081,9 @@ Value *ForExprAST::Codegen() { KSDbgInfo.emitLocation(this); // Emit the start code first, without 'variable' in scope. - Value *StartVal = Start->Codegen(); - if (StartVal == 0) - return 0; + Value *StartVal = Start->codegen(); + if (!StartVal) + return nullptr; // Store the value into the alloca. Builder.CreateStore(StartVal, Alloca); @@ -1091,24 +1107,24 @@ Value *ForExprAST::Codegen() { // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. - if (Body->Codegen() == 0) - return 0; + if (!Body->codegen()) + return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { - StepVal = Step->Codegen(); - if (StepVal == 0) - return 0; + StepVal = Step->codegen(); + if (!StepVal) + return nullptr; } else { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); } // Compute the end condition. - Value *EndCond = End->Codegen(); - if (EndCond == 0) - return EndCond; + Value *EndCond = End->codegen(); + if (!EndCond) + return nullptr; // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. @@ -1140,7 +1156,7 @@ Value *ForExprAST::Codegen() { return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } -Value *VarExprAST::Codegen() { +Value *VarExprAST::codegen() { std::vector<AllocaInst *> OldBindings; Function *TheFunction = Builder.GetInsertBlock()->getParent(); @@ -1148,7 +1164,7 @@ Value *VarExprAST::Codegen() { // Register all variables and emit their initializer. for (unsigned i = 0, e = VarNames.size(); i != e; ++i) { const std::string &VarName = VarNames[i].first; - ExprAST *Init = VarNames[i].second; + ExprAST *Init = VarNames[i].second.get(); // Emit the initializer before adding the variable to scope, this prevents // the initializer from referencing the variable itself, and permits stuff @@ -1157,9 +1173,9 @@ Value *VarExprAST::Codegen() { // var a = a in ... # refers to outer 'a'. Value *InitVal; if (Init) { - InitVal = Init->Codegen(); - if (InitVal == 0) - return 0; + InitVal = Init->codegen(); + if (!InitVal) + return nullptr; } else { // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); } @@ -1178,9 +1194,9 @@ Value *VarExprAST::Codegen() { KSDbgInfo.emitLocation(this); // Codegen the body, now that all vars are in scope. - Value *BodyVal = Body->Codegen(); - if (BodyVal == 0) - return 0; + Value *BodyVal = Body->codegen(); + if (!BodyVal) + return nullptr; // Pop all our variables from scope. for (unsigned i = 0, e = VarNames.size(); i != e; ++i) @@ -1190,7 +1206,7 @@ Value *VarExprAST::Codegen() { return BodyVal; } -Function *PrototypeAST::Codegen() { +Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); @@ -1198,106 +1214,80 @@ Function *PrototypeAST::Codegen() { FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); Function *F = - Function::Create(FT, Function::ExternalLinkage, Name, TheModule); - - // If F conflicted, there was already something named 'Name'. If it has a - // body, don't allow redefinition or reextern. - if (F->getName() != Name) { - // Delete the one we just made and get the existing one. - F->eraseFromParent(); - F = TheModule->getFunction(Name); - - // If F already has a body, reject this. - if (!F->empty()) { - ErrorF("redefinition of function"); - return 0; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return 0; - } - } + Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get()); // Set names for all arguments. unsigned Idx = 0; - for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); - ++AI, ++Idx) - AI->setName(Args[Idx]); + for (auto &Arg : F->args()) + Arg.setName(Args[Idx++]); + + return F; +} + +Function *FunctionAST::codegen() { + // Transfer ownership of the prototype to the FunctionProtos map, but keep a + // reference to it for use below. + auto &P = *Proto; + FunctionProtos[Proto->getName()] = std::move(Proto); + Function *TheFunction = getFunction(P.getName()); + if (!TheFunction) + return nullptr; + + // If this is an operator, install it. + if (P.isBinaryOp()) + BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence(); + + // Create a new basic block to start insertion into. + BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); + Builder.SetInsertPoint(BB); // Create a subprogram DIE for this function. DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(), KSDbgInfo.TheCU->getDirectory()); DIScope *FContext = Unit; - unsigned LineNo = Line; - unsigned ScopeLine = Line; + unsigned LineNo = P.getLine(); + unsigned ScopeLine = LineNo; DISubprogram *SP = DBuilder->createFunction( - FContext, Name, StringRef(), Unit, LineNo, - CreateFunctionType(Args.size(), Unit), false /* internal linkage */, - true /* definition */, ScopeLine, DINode::FlagPrototyped, false, F); + FContext, P.getName(), StringRef(), Unit, LineNo, + CreateFunctionType(TheFunction->arg_size(), Unit), + false /* internal linkage */, true /* definition */, ScopeLine, + DINode::FlagPrototyped, false); + TheFunction->setSubprogram(SP); - KSDbgInfo.FnScopeMap[this] = SP; - return F; -} + // Push the current scope. + KSDbgInfo.LexicalBlocks.push_back(SP); + + // Unset the location for the prologue emission (leading instructions with no + // location in a function are considered part of the prologue and the debugger + // will run past them when breaking on a function) + KSDbgInfo.emitLocation(nullptr); -/// CreateArgumentAllocas - Create an alloca for each argument and register the -/// argument in the symbol table so that references to it will succeed. -void PrototypeAST::CreateArgumentAllocas(Function *F) { - Function::arg_iterator AI = F->arg_begin(); - for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) { + // Record the function arguments in the NamedValues map. + NamedValues.clear(); + unsigned ArgIdx = 0; + for (auto &Arg : TheFunction->args()) { // Create an alloca for this variable. - AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); + AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName()); // Create a debug descriptor for the variable. - DIScope *Scope = KSDbgInfo.LexicalBlocks.back(); - DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(), - KSDbgInfo.TheCU->getDirectory()); - DILocalVariable *D = DBuilder->createLocalVariable( - dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line, - KSDbgInfo.getDoubleTy(), Idx); + DILocalVariable *D = DBuilder->createParameterVariable( + SP, Arg.getName(), ++ArgIdx, Unit, LineNo, KSDbgInfo.getDoubleTy(), + true); DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(), - DebugLoc::get(Line, 0, Scope), + DebugLoc::get(LineNo, 0, SP), Builder.GetInsertBlock()); // Store the initial value into the alloca. - Builder.CreateStore(AI, Alloca); + Builder.CreateStore(&Arg, Alloca); // Add arguments to variable symbol table. - NamedValues[Args[Idx]] = Alloca; + NamedValues[Arg.getName()] = Alloca; } -} -Function *FunctionAST::Codegen() { - NamedValues.clear(); + KSDbgInfo.emitLocation(Body.get()); - Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; - - // Push the current scope. - KSDbgInfo.LexicalBlocks.push_back(KSDbgInfo.FnScopeMap[Proto]); - - // Unset the location for the prologue emission (leading instructions with no - // location in a function are considered part of the prologue and the debugger - // will run past them when breaking on a function) - KSDbgInfo.emitLocation(nullptr); - - // If this is an operator, install it. - if (Proto->isBinaryOp()) - BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence(); - - // Create a new basic block to start insertion into. - BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); - Builder.SetInsertPoint(BB); - - // Add all arguments to the symbol table and create their allocas. - Proto->CreateArgumentAllocas(TheFunction); - - KSDbgInfo.emitLocation(Body); - - if (Value *RetVal = Body->Codegen()) { + if (Value *RetVal = Body->codegen()) { // Finish off the function. Builder.CreateRet(RetVal); @@ -1307,36 +1297,36 @@ Function *FunctionAST::Codegen() { // Validate the generated code, checking for consistency. verifyFunction(*TheFunction); - // Optimize the function. - TheFPM->run(*TheFunction); - return TheFunction; } // Error reading body, remove function. TheFunction->eraseFromParent(); - if (Proto->isBinaryOp()) + if (P.isBinaryOp()) BinopPrecedence.erase(Proto->getOperatorName()); // Pop off the lexical block for the function since we added it // unconditionally. KSDbgInfo.LexicalBlocks.pop_back(); - return 0; + return nullptr; } //===----------------------------------------------------------------------===// // Top-Level parsing and JIT Driver //===----------------------------------------------------------------------===// -static ExecutionEngine *TheExecutionEngine; +static void InitializeModule() { + // Open a new module. + TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext()); + TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout()); +} static void HandleDefinition() { - if (FunctionAST *F = ParseDefinition()) { - if (!F->Codegen()) { + if (auto FnAST = ParseDefinition()) { + if (!FnAST->codegen()) fprintf(stderr, "Error reading function definition:"); - } } else { // Skip token for error recovery. getNextToken(); @@ -1344,10 +1334,11 @@ static void HandleDefinition() { } static void HandleExtern() { - if (PrototypeAST *P = ParseExtern()) { - if (!P->Codegen()) { + if (auto ProtoAST = ParseExtern()) { + if (!ProtoAST->codegen()) fprintf(stderr, "Error reading extern"); - } + else + FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST); } else { // Skip token for error recovery. getNextToken(); @@ -1356,8 +1347,8 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - if (!F->Codegen()) { + if (auto FnAST = ParseTopLevelExpr()) { + if (!FnAST->codegen()) { fprintf(stderr, "Error generating code for top level expr"); } } else { @@ -1372,9 +1363,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -1394,13 +1385,13 @@ static void MainLoop() { /// putchard - putchar that takes a double and returns 0. extern "C" double putchard(double X) { - putchar((char)X); + fputc((char)X, stderr); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. extern "C" double printd(double X) { - printf("%f\n", X); + fprintf(stderr, "%f\n", X); return 0; } @@ -1412,7 +1403,6 @@ int main() { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); - LLVMContext &Context = getGlobalContext(); // Install standard binary operators. // 1 is lowest precedence. @@ -1425,9 +1415,9 @@ int main() { // Prime the first token. getNextToken(); - // Make the module, which holds all the code. - std::unique_ptr<Module> Owner = make_unique<Module>("my cool jit", Context); - TheModule = Owner.get(); + TheJIT = llvm::make_unique<KaleidoscopeJIT>(); + + InitializeModule(); // Add the current debug info version into the module. TheModule->addModuleFlag(Module::Warning, "Debug Info Version", @@ -1438,7 +1428,7 @@ int main() { TheModule->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 2); // Construct the DIBuilder, we do this here because we need the module. - DBuilder = new DIBuilder(*TheModule); + DBuilder = llvm::make_unique<DIBuilder>(*TheModule); // Create the compile unit for the module. // Currently down as "fib.ks" as a filename since we're redirecting stdin @@ -1446,47 +1436,9 @@ int main() { KSDbgInfo.TheCU = DBuilder->createCompileUnit( dwarf::DW_LANG_C, "fib.ks", ".", "Kaleidoscope Compiler", 0, "", 0); - // Create the JIT. This takes ownership of the module. - std::string ErrStr; - TheExecutionEngine = - EngineBuilder(std::move(Owner)) - .setErrorStr(&ErrStr) - .setMCJITMemoryManager(llvm::make_unique<SectionMemoryManager>()) - .create(); - if (!TheExecutionEngine) { - fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); - exit(1); - } - - legacy::FunctionPassManager OurFPM(TheModule); - - // Set up the optimizer pipeline. Start with registering info about how the - // target lays out data structures. - TheModule->setDataLayout(*TheExecutionEngine->getDataLayout()); -#if 0 - // Provide basic AliasAnalysis support for GVN. - OurFPM.add(createBasicAliasAnalysisPass()); - // Promote allocas to registers. - OurFPM.add(createPromoteMemoryToRegisterPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - OurFPM.add(createInstructionCombiningPass()); - // Reassociate expressions. - OurFPM.add(createReassociatePass()); - // Eliminate Common SubExpressions. - OurFPM.add(createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - OurFPM.add(createCFGSimplificationPass()); - #endif - OurFPM.doInitialization(); - - // Set the global so the code gen can use this. - TheFPM = &OurFPM; - // Run the main "interpreter loop" now. MainLoop(); - TheFPM = 0; - // Finalize the debug info. DBuilder->finalize(); diff --git a/examples/Kaleidoscope/Orc/fully_lazy/toy.cpp b/examples/Kaleidoscope/Orc/fully_lazy/toy.cpp index c9b2c6af5658..78184f5d32cd 100644 --- a/examples/Kaleidoscope/Orc/fully_lazy/toy.cpp +++ b/examples/Kaleidoscope/Orc/fully_lazy/toy.cpp @@ -39,14 +39,14 @@ enum Token { // primary tok_identifier = -4, tok_number = -5, - + // control tok_if = -6, tok_then = -7, tok_else = -8, tok_for = -9, tok_in = -10, - + // operators tok_binary = -11, tok_unary = -12, - + // var definition tok_var = -13 }; @@ -87,7 +87,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -95,11 +95,11 @@ static int gettok() { // Comment until end of line. do LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -140,7 +140,7 @@ struct VariableExprAST : public ExprAST { /// UnaryExprAST - Expression class for a unary operator. struct UnaryExprAST : public ExprAST { - UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) + UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {} Value *IRGen(IRGenContext &C) const override; @@ -152,7 +152,7 @@ struct UnaryExprAST : public ExprAST { /// BinaryExprAST - Expression class for a binary operator. struct BinaryExprAST : public ExprAST { BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS, - std::unique_ptr<ExprAST> RHS) + std::unique_ptr<ExprAST> RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} Value *IRGen(IRGenContext &C) const override; @@ -224,7 +224,7 @@ struct PrototypeAST { bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } - + char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); return Name[Name.size()-1]; @@ -268,7 +268,7 @@ static std::map<char, int> BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; if (TokPrec <= 0) return -1; @@ -294,12 +294,12 @@ static std::unique_ptr<ExprAST> ParseExpression(); /// ::= identifier '(' expression* ')' static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; - + getNextToken(); // eat identifier. - + if (CurTok != '(') // Simple variable ref. return llvm::make_unique<VariableExprAST>(IdName); - + // Call. getNextToken(); // eat ( std::vector<std::unique_ptr<ExprAST>> Args; @@ -319,7 +319,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } @@ -336,7 +336,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { auto V = ParseExpression(); if (!V) return nullptr; - + if (CurTok != ')') return ErrorU<ExprAST>("expected ')'"); getNextToken(); // eat ). @@ -346,29 +346,29 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr<ExprAST> ParseIfExpr() { getNextToken(); // eat the if. - + // condition. auto Cond = ParseExpression(); if (!Cond) return nullptr; - + if (CurTok != tok_then) return ErrorU<ExprAST>("expected then"); getNextToken(); // eat the then - + auto Then = ParseExpression(); if (!Then) return nullptr; - + if (CurTok != tok_else) return ErrorU<ExprAST>("expected else"); - + getNextToken(); - + auto Else = ParseExpression(); if (!Else) return nullptr; - + return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), std::move(Else)); } @@ -379,26 +379,25 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (CurTok != tok_identifier) return ErrorU<ForExprAST>("expected identifier after for"); - + std::string IdName = IdentifierStr; getNextToken(); // eat identifier. - + if (CurTok != '=') return ErrorU<ForExprAST>("expected '=' after for"); getNextToken(); // eat '='. - - + auto Start = ParseExpression(); if (!Start) return nullptr; if (CurTok != ',') return ErrorU<ForExprAST>("expected ',' after for start value"); getNextToken(); - + auto End = ParseExpression(); if (!End) return nullptr; - + // The step value is optional. std::unique_ptr<ExprAST> Step; if (CurTok == ',') { @@ -407,11 +406,11 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (!Step) return nullptr; } - + if (CurTok != tok_in) return ErrorU<ForExprAST>("expected 'in' after for"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (Body) return nullptr; @@ -420,7 +419,7 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { std::move(Step), std::move(Body)); } -/// varexpr ::= 'var' identifier ('=' expression)? +/// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression static std::unique_ptr<VarExprAST> ParseVarExpr() { getNextToken(); // eat the var. @@ -430,7 +429,7 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { // At least one variable name is required. if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier after var"); - + while (1) { std::string Name = IdentifierStr; getNextToken(); // eat identifier. @@ -439,31 +438,31 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { std::unique_ptr<ExprAST> Init; if (CurTok == '=') { getNextToken(); // eat the '='. - + Init = ParseExpression(); if (!Init) return nullptr; } - + VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init))); - + // End of var list, exit loop. if (CurTok != ',') break; getNextToken(); // eat the ','. - + if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier list after var"); } - + // At this point, we have to have 'in'. if (CurTok != tok_in) return ErrorU<VarExprAST>("expected 'in' keyword after 'var'"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (!Body) return nullptr; - + return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body)); } @@ -493,7 +492,7 @@ static std::unique_ptr<ExprAST> ParseUnary() { // If the current token is not an operator, it must be a primary expr. if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') return ParsePrimary(); - + // If this is a unary operator, read it. int Opc = CurTok; getNextToken(); @@ -509,21 +508,21 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; getNextToken(); // eat binop - + // Parse the unary expression after the binary operator. auto RHS = ParseUnary(); if (!RHS) return nullptr; - + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); @@ -532,7 +531,7 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, if (!RHS) return nullptr; } - + // Merge LHS/RHS. LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } @@ -545,7 +544,7 @@ static std::unique_ptr<ExprAST> ParseExpression() { auto LHS = ParseUnary(); if (!LHS) return nullptr; - + return ParseBinOpRHS(0, std::move(LHS)); } @@ -555,10 +554,10 @@ static std::unique_ptr<ExprAST> ParseExpression() { /// ::= unary LETTER (id) static std::unique_ptr<PrototypeAST> ParsePrototype() { std::string FnName; - + unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. unsigned BinaryPrecedence = 30; - + switch (CurTok) { default: return ErrorU<PrototypeAST>("Expected function name in prototype"); @@ -584,7 +583,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { FnName += (char)CurTok; Kind = 2; getNextToken(); - + // Read the precedence if present. if (CurTok == tok_number) { if (NumVal < 1 || NumVal > 100) @@ -594,23 +593,23 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { } break; } - + if (CurTok != '(') return ErrorU<PrototypeAST>("Expected '(' in prototype"); - + std::vector<std::string> ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorU<PrototypeAST>("Expected ')' in prototype"); - + // success. getNextToken(); // eat ')'. - + // Verify right number of names for operator. if (Kind && ArgNames.size() != Kind) return ErrorU<PrototypeAST>("Invalid number of operands for operator"); - + return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0, BinaryPrecedence); } @@ -691,10 +690,10 @@ public: PrototypeAST* getPrototypeAST(const std::string &Name); private: typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap; - + LLVMContext &Context; std::unique_ptr<TargetMachine> TM; - + PrototypeMap Prototypes; }; @@ -717,7 +716,7 @@ public: M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -748,7 +747,7 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName) { IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin()); - return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, + return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr, VarName.c_str()); } @@ -760,7 +759,7 @@ Value *VariableExprAST::IRGen(IRGenContext &C) const { // Look this variable up in the function. Value *V = C.NamedValues[Name]; - if (V == 0) + if (!V) return ErrorP<Value>("Unknown variable name '" + Name + "'"); // Load the value. @@ -783,7 +782,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { // Assignment requires the LHS to be an identifier. - auto LHSVar = static_cast<VariableExprAST&>(*LHS); + auto &LHSVar = static_cast<VariableExprAST &>(*LHS); // Codegen the RHS. Value *Val = RHS->IRGen(C); if (!Val) return nullptr; @@ -795,11 +794,11 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { } return ErrorP<Value>("Unknown variable name"); } - + Value *L = LHS->IRGen(C); Value *R = RHS->IRGen(C); if (!L || !R) return nullptr; - + switch (Op) { case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp"); case '-': return C.getBuilder().CreateFSub(L, R, "subtmp"); @@ -812,7 +811,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { "booltmp"); default: break; } - + // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. std::string FnName = MakeLegalFunctionName(std::string("binary")+Op); @@ -820,7 +819,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { Value *Ops[] = { L, R }; return C.getBuilder().CreateCall(F, Ops, "binop"); } - + return ErrorP<Value>("Unknown binary operator"); } @@ -836,7 +835,7 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { ArgsV.push_back(Args[i]->IRGen(C)); if (!ArgsV.back()) return nullptr; } - + return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp"); } @@ -846,49 +845,49 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { Value *IfExprAST::IRGen(IRGenContext &C) const { Value *CondV = Cond->IRGen(C); if (!CondV) return nullptr; - + // Convert condition to a bool by comparing equal to 0.0. - ConstantFP *FPZero = + ConstantFP *FPZero = ConstantFP::get(C.getLLVMContext(), APFloat(0.0)); CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond"); - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); - + // Create blocks for the then and else cases. Insert the 'then' block at the // end of the function. BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction); BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else"); BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont"); - + C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB); - + // Emit then value. C.getBuilder().SetInsertPoint(ThenBB); - + Value *ThenV = Then->IRGen(C); if (!ThenV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. ThenBB = C.getBuilder().GetInsertBlock(); - + // Emit else block. TheFunction->getBasicBlockList().push_back(ElseBB); C.getBuilder().SetInsertPoint(ElseBB); - + Value *ElseV = Else->IRGen(C); if (!ElseV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. ElseBB = C.getBuilder().GetInsertBlock(); - + // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); C.getBuilder().SetInsertPoint(MergeBB); PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); - + PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); return PN; @@ -901,7 +900,7 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // start = startexpr // store start -> var // goto loop - // loop: + // loop: // ... // bodyexpr // ... @@ -914,40 +913,40 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // store nextvar -> var // br endcond, loop, endloop // outloop: - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); - + // Emit the start code first, without 'variable' in scope. Value *StartVal = Start->IRGen(C); if (!StartVal) return nullptr; - + // Store the value into the alloca. C.getBuilder().CreateStore(StartVal, Alloca); - + // Make the new basic block for the loop header, inserting after current // block. BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); - + // Insert an explicit fall through from the current block to the LoopBB. C.getBuilder().CreateBr(LoopBB); // Start insertion in LoopBB. C.getBuilder().SetInsertPoint(LoopBB); - + // Within the loop, the variable is defined equal to the PHI node. If it // shadows an existing variable, we have to restore it, so save it now. AllocaInst *OldVal = C.NamedValues[VarName]; C.NamedValues[VarName] = Alloca; - + // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. if (!Body->IRGen(C)) return nullptr; - + // Emit the step value. Value *StepVal; if (Step) { @@ -957,52 +956,51 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); } - + // Compute the end condition. Value *EndCond = End->IRGen(C); - if (EndCond == 0) return EndCond; - + if (!EndCond) return nullptr; + // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str()); Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar"); C.getBuilder().CreateStore(NextVar, Alloca); - + // Convert condition to a bool by comparing equal to 0.0. - EndCond = C.getBuilder().CreateFCmpONE(EndCond, + EndCond = C.getBuilder().CreateFCmpONE(EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond"); - + // Create the "after loop" block and insert it. BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); - + // Insert the conditional branch into the end of LoopEndBB. C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB); - + // Any new code will be inserted in AfterBB. C.getBuilder().SetInsertPoint(AfterBB); - + // Restore the unshadowed variable. if (OldVal) C.NamedValues[VarName] = OldVal; else C.NamedValues.erase(VarName); - // for expr always returns 0.0. return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } Value *VarExprAST::IRGen(IRGenContext &C) const { std::vector<AllocaInst *> OldBindings; - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Register all variables and emit their initializer. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) { auto &VarName = VarBindings[i].first; auto &Init = VarBindings[i].second; - + // Emit the initializer before adding the variable to scope, this prevents // the initializer from referencing the variable itself, and permits stuff // like this: @@ -1014,22 +1012,22 @@ Value *VarExprAST::IRGen(IRGenContext &C) const { if (!InitVal) return nullptr; } else // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); - + AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); C.getBuilder().CreateStore(InitVal, Alloca); // Remember the old variable binding so that we can restore the binding when // we unrecurse. OldBindings.push_back(C.NamedValues[VarName]); - + // Remember this binding. C.NamedValues[VarName] = Alloca; } - + // Codegen the body, now that all vars are in scope. Value *BodyVal = Body->IRGen(C); if (!BodyVal) return nullptr; - + // Pop all our variables from scope. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) C.NamedValues[VarBindings[i].first] = OldBindings[i]; @@ -1042,7 +1040,7 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { std::string FnName = MakeLegalFunctionName(Name); // Make the function type: double(double,double) etc. - std::vector<Type*> Doubles(Args.size(), + std::vector<Type*> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1055,26 +1053,26 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { // Delete the one we just made and get the existing one. F->eraseFromParent(); F = C.getM().getFunction(Name); - + // If F already has a body, reject this. if (!F->empty()) { ErrorP<Function>("redefinition of function"); return nullptr; } - + // If F took a different number of args, reject. if (F->arg_size() != Args.size()) { ErrorP<Function>("redefinition of function with different # args"); return nullptr; } } - + // Set names for all arguments. unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); ++AI, ++Idx) AI->setName(Args[Idx]); - + return F; } @@ -1087,7 +1085,7 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); // Store the initial value into the alloca. - C.getBuilder().CreateStore(AI, Alloca); + C.getBuilder().CreateStore(&*AI, Alloca); // Add arguments to variable symbol table. C.NamedValues[Args[Idx]] = Alloca; @@ -1096,19 +1094,19 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { Function *FunctionAST::IRGen(IRGenContext &C) const { C.NamedValues.clear(); - + Function *TheFunction = Proto->IRGen(C); if (!TheFunction) return nullptr; - + // If this is an operator, install it. if (Proto->isBinaryOp()) BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence; - + // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); C.getBuilder().SetInsertPoint(BB); - + // Add all arguments to the symbol table and create their allocas. Proto->CreateArgumentAllocas(TheFunction, C); @@ -1121,7 +1119,7 @@ Function *FunctionAST::IRGen(IRGenContext &C) const { return TheFunction; } - + // Error reading body, remove function. TheFunction->eraseFromParent(); @@ -1170,16 +1168,14 @@ public: : Session(Session), CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())), LazyEmitLayer(CompileLayer), - CompileCallbacks(LazyEmitLayer, CCMgrMemMgr, Session.getLLVMContext(), - reinterpret_cast<uintptr_t>(EarthShatteringKaboom), - 64) {} + CompileCallbacks(reinterpret_cast<uintptr_t>(EarthShatteringKaboom)) {} std::string mangle(const std::string &Name) { std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); Mangler::getNameWithPrefix(MangledNameStream, Name, - *Session.getTarget().getDataLayout()); + Session.getTarget().createDataLayout()); } return MangledName; } @@ -1236,7 +1232,7 @@ private: RuntimeDyld::SymbolInfo searchFunctionASTs(const std::string &Name) { auto DefI = FunctionDefs.find(Name); if (DefI == FunctionDefs.end()) - return 0; + return nullptr; // Return the address of the stub. // Take the FunctionAST out of the map. @@ -1262,8 +1258,7 @@ private: // the function. The resulting CallbackInfo type will let us set the // compile and update actions for the callback, and get a pointer to // the jit trampoline that we need to call to trigger those actions. - auto CallbackInfo = - CompileCallbacks.getCompileCallback(F->getContext()); + auto CallbackInfo = CompileCallbacks.getCompileCallback(); // Step 3) Create a stub that will indirectly call the body of this // function once it is compiled. Initially, set the function @@ -1313,7 +1308,7 @@ private: std::map<std::string, std::unique_ptr<FunctionAST>> FunctionDefs; - JITCompileCallbackManager<LazyEmitLayerT, OrcX86_64> CompileCallbacks; + LocalJITCompileCallbackManager<OrcX86_64> CompileCallbacks; }; static void HandleDefinition(SessionContext &S, KaleidoscopeJIT &J) { @@ -1350,7 +1345,7 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { // Get the address of the JIT'd function in memory. auto ExprSymbol = J.findUnmangledSymbol("__anon_expr"); - + // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); @@ -1393,20 +1388,20 @@ static void MainLoop() { //===----------------------------------------------------------------------===// /// putchard - putchar that takes a double and returns 0. -extern "C" +extern "C" double putchard(double X) { putchar((char)X); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. -extern "C" +extern "C" double printd(double X) { printf("%f", X); return 0; } -extern "C" +extern "C" double printlf() { printf("\n"); return 0; @@ -1443,4 +1438,3 @@ int main() { return 0; } - diff --git a/examples/Kaleidoscope/Orc/initial/toy.cpp b/examples/Kaleidoscope/Orc/initial/toy.cpp index 7e99c0f5ba54..2a6bb92246d0 100644 --- a/examples/Kaleidoscope/Orc/initial/toy.cpp +++ b/examples/Kaleidoscope/Orc/initial/toy.cpp @@ -38,14 +38,14 @@ enum Token { // primary tok_identifier = -4, tok_number = -5, - + // control tok_if = -6, tok_then = -7, tok_else = -8, tok_for = -9, tok_in = -10, - + // operators tok_binary = -11, tok_unary = -12, - + // var definition tok_var = -13 }; @@ -86,7 +86,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -94,11 +94,11 @@ static int gettok() { // Comment until end of line. do LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -139,7 +139,7 @@ struct VariableExprAST : public ExprAST { /// UnaryExprAST - Expression class for a unary operator. struct UnaryExprAST : public ExprAST { - UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) + UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {} Value *IRGen(IRGenContext &C) const override; @@ -151,7 +151,7 @@ struct UnaryExprAST : public ExprAST { /// BinaryExprAST - Expression class for a binary operator. struct BinaryExprAST : public ExprAST { BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS, - std::unique_ptr<ExprAST> RHS) + std::unique_ptr<ExprAST> RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} Value *IRGen(IRGenContext &C) const override; @@ -223,7 +223,7 @@ struct PrototypeAST { bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } - + char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); return Name[Name.size()-1]; @@ -267,7 +267,7 @@ static std::map<char, int> BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; if (TokPrec <= 0) return -1; @@ -293,12 +293,12 @@ static std::unique_ptr<ExprAST> ParseExpression(); /// ::= identifier '(' expression* ')' static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; - + getNextToken(); // eat identifier. - + if (CurTok != '(') // Simple variable ref. return llvm::make_unique<VariableExprAST>(IdName); - + // Call. getNextToken(); // eat ( std::vector<std::unique_ptr<ExprAST>> Args; @@ -318,7 +318,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } @@ -335,7 +335,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { auto V = ParseExpression(); if (!V) return nullptr; - + if (CurTok != ')') return ErrorU<ExprAST>("expected ')'"); getNextToken(); // eat ). @@ -345,29 +345,29 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr<ExprAST> ParseIfExpr() { getNextToken(); // eat the if. - + // condition. auto Cond = ParseExpression(); if (!Cond) return nullptr; - + if (CurTok != tok_then) return ErrorU<ExprAST>("expected then"); getNextToken(); // eat the then - + auto Then = ParseExpression(); if (!Then) return nullptr; - + if (CurTok != tok_else) return ErrorU<ExprAST>("expected else"); - + getNextToken(); - + auto Else = ParseExpression(); if (!Else) return nullptr; - + return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), std::move(Else)); } @@ -378,26 +378,25 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (CurTok != tok_identifier) return ErrorU<ForExprAST>("expected identifier after for"); - + std::string IdName = IdentifierStr; getNextToken(); // eat identifier. - + if (CurTok != '=') return ErrorU<ForExprAST>("expected '=' after for"); getNextToken(); // eat '='. - - + auto Start = ParseExpression(); if (!Start) return nullptr; if (CurTok != ',') return ErrorU<ForExprAST>("expected ',' after for start value"); getNextToken(); - + auto End = ParseExpression(); if (!End) return nullptr; - + // The step value is optional. std::unique_ptr<ExprAST> Step; if (CurTok == ',') { @@ -406,11 +405,11 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (!Step) return nullptr; } - + if (CurTok != tok_in) return ErrorU<ForExprAST>("expected 'in' after for"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (Body) return nullptr; @@ -419,7 +418,7 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { std::move(Step), std::move(Body)); } -/// varexpr ::= 'var' identifier ('=' expression)? +/// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression static std::unique_ptr<VarExprAST> ParseVarExpr() { getNextToken(); // eat the var. @@ -429,7 +428,7 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { // At least one variable name is required. if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier after var"); - + while (1) { std::string Name = IdentifierStr; getNextToken(); // eat identifier. @@ -438,31 +437,31 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { std::unique_ptr<ExprAST> Init; if (CurTok == '=') { getNextToken(); // eat the '='. - + Init = ParseExpression(); if (!Init) return nullptr; } - + VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init))); - + // End of var list, exit loop. if (CurTok != ',') break; getNextToken(); // eat the ','. - + if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier list after var"); } - + // At this point, we have to have 'in'. if (CurTok != tok_in) return ErrorU<VarExprAST>("expected 'in' keyword after 'var'"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (!Body) return nullptr; - + return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body)); } @@ -492,7 +491,7 @@ static std::unique_ptr<ExprAST> ParseUnary() { // If the current token is not an operator, it must be a primary expr. if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') return ParsePrimary(); - + // If this is a unary operator, read it. int Opc = CurTok; getNextToken(); @@ -508,21 +507,21 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; getNextToken(); // eat binop - + // Parse the unary expression after the binary operator. auto RHS = ParseUnary(); if (!RHS) return nullptr; - + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); @@ -531,7 +530,7 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, if (!RHS) return nullptr; } - + // Merge LHS/RHS. LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } @@ -544,7 +543,7 @@ static std::unique_ptr<ExprAST> ParseExpression() { auto LHS = ParseUnary(); if (!LHS) return nullptr; - + return ParseBinOpRHS(0, std::move(LHS)); } @@ -554,10 +553,10 @@ static std::unique_ptr<ExprAST> ParseExpression() { /// ::= unary LETTER (id) static std::unique_ptr<PrototypeAST> ParsePrototype() { std::string FnName; - + unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. unsigned BinaryPrecedence = 30; - + switch (CurTok) { default: return ErrorU<PrototypeAST>("Expected function name in prototype"); @@ -583,7 +582,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { FnName += (char)CurTok; Kind = 2; getNextToken(); - + // Read the precedence if present. if (CurTok == tok_number) { if (NumVal < 1 || NumVal > 100) @@ -593,23 +592,23 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { } break; } - + if (CurTok != '(') return ErrorU<PrototypeAST>("Expected '(' in prototype"); - + std::vector<std::string> ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorU<PrototypeAST>("Expected ')' in prototype"); - + // success. getNextToken(); // eat ')'. - + // Verify right number of names for operator. if (Kind && ArgNames.size() != Kind) return ErrorU<PrototypeAST>("Invalid number of operands for operator"); - + return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0, BinaryPrecedence); } @@ -690,10 +689,10 @@ public: PrototypeAST* getPrototypeAST(const std::string &Name); private: typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap; - + LLVMContext &Context; std::unique_ptr<TargetMachine> TM; - + PrototypeMap Prototypes; }; @@ -716,7 +715,7 @@ public: M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -747,7 +746,7 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName) { IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin()); - return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, + return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr, VarName.c_str()); } @@ -759,7 +758,7 @@ Value *VariableExprAST::IRGen(IRGenContext &C) const { // Look this variable up in the function. Value *V = C.NamedValues[Name]; - if (V == 0) + if (!V) return ErrorP<Value>("Unknown variable name '" + Name + "'"); // Load the value. @@ -782,7 +781,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { // Assignment requires the LHS to be an identifier. - auto LHSVar = static_cast<VariableExprAST&>(*LHS); + auto &LHSVar = static_cast<VariableExprAST &>(*LHS); // Codegen the RHS. Value *Val = RHS->IRGen(C); if (!Val) return nullptr; @@ -794,11 +793,11 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { } return ErrorP<Value>("Unknown variable name"); } - + Value *L = LHS->IRGen(C); Value *R = RHS->IRGen(C); if (!L || !R) return nullptr; - + switch (Op) { case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp"); case '-': return C.getBuilder().CreateFSub(L, R, "subtmp"); @@ -811,7 +810,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { "booltmp"); default: break; } - + // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. std::string FnName = MakeLegalFunctionName(std::string("binary")+Op); @@ -819,7 +818,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { Value *Ops[] = { L, R }; return C.getBuilder().CreateCall(F, Ops, "binop"); } - + return ErrorP<Value>("Unknown binary operator"); } @@ -835,7 +834,7 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { ArgsV.push_back(Args[i]->IRGen(C)); if (!ArgsV.back()) return nullptr; } - + return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp"); } @@ -845,49 +844,49 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { Value *IfExprAST::IRGen(IRGenContext &C) const { Value *CondV = Cond->IRGen(C); if (!CondV) return nullptr; - + // Convert condition to a bool by comparing equal to 0.0. - ConstantFP *FPZero = + ConstantFP *FPZero = ConstantFP::get(C.getLLVMContext(), APFloat(0.0)); CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond"); - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); - + // Create blocks for the then and else cases. Insert the 'then' block at the // end of the function. BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction); BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else"); BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont"); - + C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB); - + // Emit then value. C.getBuilder().SetInsertPoint(ThenBB); - + Value *ThenV = Then->IRGen(C); if (!ThenV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. ThenBB = C.getBuilder().GetInsertBlock(); - + // Emit else block. TheFunction->getBasicBlockList().push_back(ElseBB); C.getBuilder().SetInsertPoint(ElseBB); - + Value *ElseV = Else->IRGen(C); if (!ElseV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. ElseBB = C.getBuilder().GetInsertBlock(); - + // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); C.getBuilder().SetInsertPoint(MergeBB); PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); - + PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); return PN; @@ -900,7 +899,7 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // start = startexpr // store start -> var // goto loop - // loop: + // loop: // ... // bodyexpr // ... @@ -913,40 +912,40 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // store nextvar -> var // br endcond, loop, endloop // outloop: - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); - + // Emit the start code first, without 'variable' in scope. Value *StartVal = Start->IRGen(C); if (!StartVal) return nullptr; - + // Store the value into the alloca. C.getBuilder().CreateStore(StartVal, Alloca); - + // Make the new basic block for the loop header, inserting after current // block. BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); - + // Insert an explicit fall through from the current block to the LoopBB. C.getBuilder().CreateBr(LoopBB); // Start insertion in LoopBB. C.getBuilder().SetInsertPoint(LoopBB); - + // Within the loop, the variable is defined equal to the PHI node. If it // shadows an existing variable, we have to restore it, so save it now. AllocaInst *OldVal = C.NamedValues[VarName]; C.NamedValues[VarName] = Alloca; - + // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. if (!Body->IRGen(C)) return nullptr; - + // Emit the step value. Value *StepVal; if (Step) { @@ -956,52 +955,51 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); } - + // Compute the end condition. Value *EndCond = End->IRGen(C); - if (EndCond == 0) return EndCond; - + if (!EndCond) return nullptr; + // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str()); Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar"); C.getBuilder().CreateStore(NextVar, Alloca); - + // Convert condition to a bool by comparing equal to 0.0. - EndCond = C.getBuilder().CreateFCmpONE(EndCond, + EndCond = C.getBuilder().CreateFCmpONE(EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond"); - + // Create the "after loop" block and insert it. BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); - + // Insert the conditional branch into the end of LoopEndBB. C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB); - + // Any new code will be inserted in AfterBB. C.getBuilder().SetInsertPoint(AfterBB); - + // Restore the unshadowed variable. if (OldVal) C.NamedValues[VarName] = OldVal; else C.NamedValues.erase(VarName); - // for expr always returns 0.0. return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } Value *VarExprAST::IRGen(IRGenContext &C) const { std::vector<AllocaInst *> OldBindings; - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Register all variables and emit their initializer. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) { auto &VarName = VarBindings[i].first; auto &Init = VarBindings[i].second; - + // Emit the initializer before adding the variable to scope, this prevents // the initializer from referencing the variable itself, and permits stuff // like this: @@ -1013,22 +1011,22 @@ Value *VarExprAST::IRGen(IRGenContext &C) const { if (!InitVal) return nullptr; } else // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); - + AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); C.getBuilder().CreateStore(InitVal, Alloca); // Remember the old variable binding so that we can restore the binding when // we unrecurse. OldBindings.push_back(C.NamedValues[VarName]); - + // Remember this binding. C.NamedValues[VarName] = Alloca; } - + // Codegen the body, now that all vars are in scope. Value *BodyVal = Body->IRGen(C); if (!BodyVal) return nullptr; - + // Pop all our variables from scope. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) C.NamedValues[VarBindings[i].first] = OldBindings[i]; @@ -1041,7 +1039,7 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { std::string FnName = MakeLegalFunctionName(Name); // Make the function type: double(double,double) etc. - std::vector<Type*> Doubles(Args.size(), + std::vector<Type*> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1054,26 +1052,26 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { // Delete the one we just made and get the existing one. F->eraseFromParent(); F = C.getM().getFunction(Name); - + // If F already has a body, reject this. if (!F->empty()) { ErrorP<Function>("redefinition of function"); return nullptr; } - + // If F took a different number of args, reject. if (F->arg_size() != Args.size()) { ErrorP<Function>("redefinition of function with different # args"); return nullptr; } } - + // Set names for all arguments. unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); ++AI, ++Idx) AI->setName(Args[Idx]); - + return F; } @@ -1086,7 +1084,7 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); // Store the initial value into the alloca. - C.getBuilder().CreateStore(AI, Alloca); + C.getBuilder().CreateStore(&*AI, Alloca); // Add arguments to variable symbol table. C.NamedValues[Args[Idx]] = Alloca; @@ -1095,19 +1093,19 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { Function *FunctionAST::IRGen(IRGenContext &C) const { C.NamedValues.clear(); - + Function *TheFunction = Proto->IRGen(C); if (!TheFunction) return nullptr; - + // If this is an operator, install it. if (Proto->isBinaryOp()) BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence; - + // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); C.getBuilder().SetInsertPoint(BB); - + // Add all arguments to the symbol table and create their allocas. Proto->CreateArgumentAllocas(TheFunction, C); @@ -1120,7 +1118,7 @@ Function *FunctionAST::IRGen(IRGenContext &C) const { return TheFunction; } - + // Error reading body, remove function. TheFunction->eraseFromParent(); @@ -1160,7 +1158,7 @@ public: typedef CompileLayerT::ModuleSetHandleT ModuleHandleT; KaleidoscopeJIT(SessionContext &Session) - : DL(*Session.getTarget().getDataLayout()), + : DL(Session.getTarget().createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())) {} std::string mangle(const std::string &Name) { @@ -1201,7 +1199,7 @@ public: } private: - const DataLayout &DL; + const DataLayout DL; ObjLayerT ObjectLayer; CompileLayerT CompileLayer; }; @@ -1242,7 +1240,7 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { // Get the address of the JIT'd function in memory. auto ExprSymbol = J.findUnmangledSymbol("__anon_expr"); - + // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); @@ -1285,20 +1283,20 @@ static void MainLoop() { //===----------------------------------------------------------------------===// /// putchard - putchar that takes a double and returns 0. -extern "C" +extern "C" double putchard(double X) { putchar((char)X); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. -extern "C" +extern "C" double printd(double X) { printf("%f", X); return 0; } -extern "C" +extern "C" double printlf() { printf("\n"); return 0; @@ -1335,4 +1333,3 @@ int main() { return 0; } - diff --git a/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp b/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp index 4b4c191171b4..5205b406ed71 100644 --- a/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp +++ b/examples/Kaleidoscope/Orc/lazy_codegen/toy.cpp @@ -38,14 +38,14 @@ enum Token { // primary tok_identifier = -4, tok_number = -5, - + // control tok_if = -6, tok_then = -7, tok_else = -8, tok_for = -9, tok_in = -10, - + // operators tok_binary = -11, tok_unary = -12, - + // var definition tok_var = -13 }; @@ -86,7 +86,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -94,11 +94,11 @@ static int gettok() { // Comment until end of line. do LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -139,7 +139,7 @@ struct VariableExprAST : public ExprAST { /// UnaryExprAST - Expression class for a unary operator. struct UnaryExprAST : public ExprAST { - UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) + UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {} Value *IRGen(IRGenContext &C) const override; @@ -151,7 +151,7 @@ struct UnaryExprAST : public ExprAST { /// BinaryExprAST - Expression class for a binary operator. struct BinaryExprAST : public ExprAST { BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS, - std::unique_ptr<ExprAST> RHS) + std::unique_ptr<ExprAST> RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} Value *IRGen(IRGenContext &C) const override; @@ -223,7 +223,7 @@ struct PrototypeAST { bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } - + char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); return Name[Name.size()-1]; @@ -267,7 +267,7 @@ static std::map<char, int> BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; if (TokPrec <= 0) return -1; @@ -293,12 +293,12 @@ static std::unique_ptr<ExprAST> ParseExpression(); /// ::= identifier '(' expression* ')' static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; - + getNextToken(); // eat identifier. - + if (CurTok != '(') // Simple variable ref. return llvm::make_unique<VariableExprAST>(IdName); - + // Call. getNextToken(); // eat ( std::vector<std::unique_ptr<ExprAST>> Args; @@ -318,7 +318,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } @@ -335,7 +335,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { auto V = ParseExpression(); if (!V) return nullptr; - + if (CurTok != ')') return ErrorU<ExprAST>("expected ')'"); getNextToken(); // eat ). @@ -345,29 +345,29 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr<ExprAST> ParseIfExpr() { getNextToken(); // eat the if. - + // condition. auto Cond = ParseExpression(); if (!Cond) return nullptr; - + if (CurTok != tok_then) return ErrorU<ExprAST>("expected then"); getNextToken(); // eat the then - + auto Then = ParseExpression(); if (!Then) return nullptr; - + if (CurTok != tok_else) return ErrorU<ExprAST>("expected else"); - + getNextToken(); - + auto Else = ParseExpression(); if (!Else) return nullptr; - + return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), std::move(Else)); } @@ -378,26 +378,25 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (CurTok != tok_identifier) return ErrorU<ForExprAST>("expected identifier after for"); - + std::string IdName = IdentifierStr; getNextToken(); // eat identifier. - + if (CurTok != '=') return ErrorU<ForExprAST>("expected '=' after for"); getNextToken(); // eat '='. - - + auto Start = ParseExpression(); if (!Start) return nullptr; if (CurTok != ',') return ErrorU<ForExprAST>("expected ',' after for start value"); getNextToken(); - + auto End = ParseExpression(); if (!End) return nullptr; - + // The step value is optional. std::unique_ptr<ExprAST> Step; if (CurTok == ',') { @@ -406,11 +405,11 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (!Step) return nullptr; } - + if (CurTok != tok_in) return ErrorU<ForExprAST>("expected 'in' after for"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (Body) return nullptr; @@ -419,7 +418,7 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { std::move(Step), std::move(Body)); } -/// varexpr ::= 'var' identifier ('=' expression)? +/// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression static std::unique_ptr<VarExprAST> ParseVarExpr() { getNextToken(); // eat the var. @@ -429,7 +428,7 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { // At least one variable name is required. if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier after var"); - + while (1) { std::string Name = IdentifierStr; getNextToken(); // eat identifier. @@ -438,31 +437,31 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { std::unique_ptr<ExprAST> Init; if (CurTok == '=') { getNextToken(); // eat the '='. - + Init = ParseExpression(); if (!Init) return nullptr; } - + VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init))); - + // End of var list, exit loop. if (CurTok != ',') break; getNextToken(); // eat the ','. - + if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier list after var"); } - + // At this point, we have to have 'in'. if (CurTok != tok_in) return ErrorU<VarExprAST>("expected 'in' keyword after 'var'"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (!Body) return nullptr; - + return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body)); } @@ -492,7 +491,7 @@ static std::unique_ptr<ExprAST> ParseUnary() { // If the current token is not an operator, it must be a primary expr. if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') return ParsePrimary(); - + // If this is a unary operator, read it. int Opc = CurTok; getNextToken(); @@ -508,21 +507,21 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; getNextToken(); // eat binop - + // Parse the unary expression after the binary operator. auto RHS = ParseUnary(); if (!RHS) return nullptr; - + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); @@ -531,7 +530,7 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, if (!RHS) return nullptr; } - + // Merge LHS/RHS. LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } @@ -544,7 +543,7 @@ static std::unique_ptr<ExprAST> ParseExpression() { auto LHS = ParseUnary(); if (!LHS) return nullptr; - + return ParseBinOpRHS(0, std::move(LHS)); } @@ -554,10 +553,10 @@ static std::unique_ptr<ExprAST> ParseExpression() { /// ::= unary LETTER (id) static std::unique_ptr<PrototypeAST> ParsePrototype() { std::string FnName; - + unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. unsigned BinaryPrecedence = 30; - + switch (CurTok) { default: return ErrorU<PrototypeAST>("Expected function name in prototype"); @@ -583,7 +582,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { FnName += (char)CurTok; Kind = 2; getNextToken(); - + // Read the precedence if present. if (CurTok == tok_number) { if (NumVal < 1 || NumVal > 100) @@ -593,23 +592,23 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { } break; } - + if (CurTok != '(') return ErrorU<PrototypeAST>("Expected '(' in prototype"); - + std::vector<std::string> ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorU<PrototypeAST>("Expected ')' in prototype"); - + // success. getNextToken(); // eat ')'. - + // Verify right number of names for operator. if (Kind && ArgNames.size() != Kind) return ErrorU<PrototypeAST>("Invalid number of operands for operator"); - + return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0, BinaryPrecedence); } @@ -690,10 +689,10 @@ public: PrototypeAST* getPrototypeAST(const std::string &Name); private: typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap; - + LLVMContext &Context; std::unique_ptr<TargetMachine> TM; - + PrototypeMap Prototypes; }; @@ -716,7 +715,7 @@ public: M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -747,7 +746,7 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName) { IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin()); - return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, + return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr, VarName.c_str()); } @@ -759,7 +758,7 @@ Value *VariableExprAST::IRGen(IRGenContext &C) const { // Look this variable up in the function. Value *V = C.NamedValues[Name]; - if (V == 0) + if (!V) return ErrorP<Value>("Unknown variable name '" + Name + "'"); // Load the value. @@ -782,7 +781,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { // Assignment requires the LHS to be an identifier. - auto LHSVar = static_cast<VariableExprAST&>(*LHS); + auto &LHSVar = static_cast<VariableExprAST &>(*LHS); // Codegen the RHS. Value *Val = RHS->IRGen(C); if (!Val) return nullptr; @@ -794,11 +793,11 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { } return ErrorP<Value>("Unknown variable name"); } - + Value *L = LHS->IRGen(C); Value *R = RHS->IRGen(C); if (!L || !R) return nullptr; - + switch (Op) { case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp"); case '-': return C.getBuilder().CreateFSub(L, R, "subtmp"); @@ -811,7 +810,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { "booltmp"); default: break; } - + // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. std::string FnName = MakeLegalFunctionName(std::string("binary")+Op); @@ -819,7 +818,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { Value *Ops[] = { L, R }; return C.getBuilder().CreateCall(F, Ops, "binop"); } - + return ErrorP<Value>("Unknown binary operator"); } @@ -835,7 +834,7 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { ArgsV.push_back(Args[i]->IRGen(C)); if (!ArgsV.back()) return nullptr; } - + return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp"); } @@ -845,49 +844,49 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { Value *IfExprAST::IRGen(IRGenContext &C) const { Value *CondV = Cond->IRGen(C); if (!CondV) return nullptr; - + // Convert condition to a bool by comparing equal to 0.0. - ConstantFP *FPZero = + ConstantFP *FPZero = ConstantFP::get(C.getLLVMContext(), APFloat(0.0)); CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond"); - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); - + // Create blocks for the then and else cases. Insert the 'then' block at the // end of the function. BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction); BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else"); BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont"); - + C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB); - + // Emit then value. C.getBuilder().SetInsertPoint(ThenBB); - + Value *ThenV = Then->IRGen(C); if (!ThenV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. ThenBB = C.getBuilder().GetInsertBlock(); - + // Emit else block. TheFunction->getBasicBlockList().push_back(ElseBB); C.getBuilder().SetInsertPoint(ElseBB); - + Value *ElseV = Else->IRGen(C); if (!ElseV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. ElseBB = C.getBuilder().GetInsertBlock(); - + // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); C.getBuilder().SetInsertPoint(MergeBB); PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); - + PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); return PN; @@ -900,7 +899,7 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // start = startexpr // store start -> var // goto loop - // loop: + // loop: // ... // bodyexpr // ... @@ -913,40 +912,40 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // store nextvar -> var // br endcond, loop, endloop // outloop: - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); - + // Emit the start code first, without 'variable' in scope. Value *StartVal = Start->IRGen(C); if (!StartVal) return nullptr; - + // Store the value into the alloca. C.getBuilder().CreateStore(StartVal, Alloca); - + // Make the new basic block for the loop header, inserting after current // block. BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); - + // Insert an explicit fall through from the current block to the LoopBB. C.getBuilder().CreateBr(LoopBB); // Start insertion in LoopBB. C.getBuilder().SetInsertPoint(LoopBB); - + // Within the loop, the variable is defined equal to the PHI node. If it // shadows an existing variable, we have to restore it, so save it now. AllocaInst *OldVal = C.NamedValues[VarName]; C.NamedValues[VarName] = Alloca; - + // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. if (!Body->IRGen(C)) return nullptr; - + // Emit the step value. Value *StepVal; if (Step) { @@ -956,52 +955,51 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); } - + // Compute the end condition. Value *EndCond = End->IRGen(C); - if (EndCond == 0) return EndCond; - + if (!EndCond) return nullptr; + // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str()); Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar"); C.getBuilder().CreateStore(NextVar, Alloca); - + // Convert condition to a bool by comparing equal to 0.0. - EndCond = C.getBuilder().CreateFCmpONE(EndCond, + EndCond = C.getBuilder().CreateFCmpONE(EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond"); - + // Create the "after loop" block and insert it. BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); - + // Insert the conditional branch into the end of LoopEndBB. C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB); - + // Any new code will be inserted in AfterBB. C.getBuilder().SetInsertPoint(AfterBB); - + // Restore the unshadowed variable. if (OldVal) C.NamedValues[VarName] = OldVal; else C.NamedValues.erase(VarName); - // for expr always returns 0.0. return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } Value *VarExprAST::IRGen(IRGenContext &C) const { std::vector<AllocaInst *> OldBindings; - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Register all variables and emit their initializer. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) { auto &VarName = VarBindings[i].first; auto &Init = VarBindings[i].second; - + // Emit the initializer before adding the variable to scope, this prevents // the initializer from referencing the variable itself, and permits stuff // like this: @@ -1013,22 +1011,22 @@ Value *VarExprAST::IRGen(IRGenContext &C) const { if (!InitVal) return nullptr; } else // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); - + AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); C.getBuilder().CreateStore(InitVal, Alloca); // Remember the old variable binding so that we can restore the binding when // we unrecurse. OldBindings.push_back(C.NamedValues[VarName]); - + // Remember this binding. C.NamedValues[VarName] = Alloca; } - + // Codegen the body, now that all vars are in scope. Value *BodyVal = Body->IRGen(C); if (!BodyVal) return nullptr; - + // Pop all our variables from scope. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) C.NamedValues[VarBindings[i].first] = OldBindings[i]; @@ -1041,7 +1039,7 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { std::string FnName = MakeLegalFunctionName(Name); // Make the function type: double(double,double) etc. - std::vector<Type*> Doubles(Args.size(), + std::vector<Type*> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1054,26 +1052,26 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { // Delete the one we just made and get the existing one. F->eraseFromParent(); F = C.getM().getFunction(Name); - + // If F already has a body, reject this. if (!F->empty()) { ErrorP<Function>("redefinition of function"); return nullptr; } - + // If F took a different number of args, reject. if (F->arg_size() != Args.size()) { ErrorP<Function>("redefinition of function with different # args"); return nullptr; } } - + // Set names for all arguments. unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); ++AI, ++Idx) AI->setName(Args[Idx]); - + return F; } @@ -1086,7 +1084,7 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); // Store the initial value into the alloca. - C.getBuilder().CreateStore(AI, Alloca); + C.getBuilder().CreateStore(&*AI, Alloca); // Add arguments to variable symbol table. C.NamedValues[Args[Idx]] = Alloca; @@ -1095,19 +1093,19 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { Function *FunctionAST::IRGen(IRGenContext &C) const { C.NamedValues.clear(); - + Function *TheFunction = Proto->IRGen(C); if (!TheFunction) return nullptr; - + // If this is an operator, install it. if (Proto->isBinaryOp()) BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence; - + // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); C.getBuilder().SetInsertPoint(BB); - + // Add all arguments to the symbol table and create their allocas. Proto->CreateArgumentAllocas(TheFunction, C); @@ -1120,7 +1118,7 @@ Function *FunctionAST::IRGen(IRGenContext &C) const { return TheFunction; } - + // Error reading body, remove function. TheFunction->eraseFromParent(); @@ -1162,7 +1160,7 @@ public: typedef LazyEmitLayerT::ModuleSetHandleT ModuleHandleT; KaleidoscopeJIT(SessionContext &Session) - : DL(*Session.getTarget().getDataLayout()), + : DL(Session.getTarget().createDataLayout()), CompileLayer(ObjectLayer, SimpleCompiler(Session.getTarget())), LazyEmitLayer(CompileLayer) {} @@ -1204,7 +1202,7 @@ public: } private: - const DataLayout &DL; + const DataLayout DL; ObjLayerT ObjectLayer; CompileLayerT CompileLayer; LazyEmitLayerT LazyEmitLayer; @@ -1246,7 +1244,7 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { // Get the address of the JIT'd function in memory. auto ExprSymbol = J.findUnmangledSymbol("__anon_expr"); - + // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); @@ -1289,20 +1287,20 @@ static void MainLoop() { //===----------------------------------------------------------------------===// /// putchard - putchar that takes a double and returns 0. -extern "C" +extern "C" double putchard(double X) { putchar((char)X); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. -extern "C" +extern "C" double printd(double X) { printf("%f", X); return 0; } -extern "C" +extern "C" double printlf() { printf("\n"); return 0; @@ -1339,4 +1337,3 @@ int main() { return 0; } - diff --git a/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp b/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp index ca34de7e2244..ebaff49e89b2 100644 --- a/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp +++ b/examples/Kaleidoscope/Orc/lazy_irgen/toy.cpp @@ -38,14 +38,14 @@ enum Token { // primary tok_identifier = -4, tok_number = -5, - + // control tok_if = -6, tok_then = -7, tok_else = -8, tok_for = -9, tok_in = -10, - + // operators tok_binary = -11, tok_unary = -12, - + // var definition tok_var = -13 }; @@ -86,7 +86,7 @@ static int gettok() { LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); - NumVal = strtod(NumStr.c_str(), 0); + NumVal = strtod(NumStr.c_str(), nullptr); return tok_number; } @@ -94,11 +94,11 @@ static int gettok() { // Comment until end of line. do LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -139,7 +139,7 @@ struct VariableExprAST : public ExprAST { /// UnaryExprAST - Expression class for a unary operator. struct UnaryExprAST : public ExprAST { - UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) + UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand) : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {} Value *IRGen(IRGenContext &C) const override; @@ -151,7 +151,7 @@ struct UnaryExprAST : public ExprAST { /// BinaryExprAST - Expression class for a binary operator. struct BinaryExprAST : public ExprAST { BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS, - std::unique_ptr<ExprAST> RHS) + std::unique_ptr<ExprAST> RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} Value *IRGen(IRGenContext &C) const override; @@ -223,7 +223,7 @@ struct PrototypeAST { bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } - + char getOperatorName() const { assert(isUnaryOp() || isBinaryOp()); return Name[Name.size()-1]; @@ -267,7 +267,7 @@ static std::map<char, int> BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; if (TokPrec <= 0) return -1; @@ -293,12 +293,12 @@ static std::unique_ptr<ExprAST> ParseExpression(); /// ::= identifier '(' expression* ')' static std::unique_ptr<ExprAST> ParseIdentifierExpr() { std::string IdName = IdentifierStr; - + getNextToken(); // eat identifier. - + if (CurTok != '(') // Simple variable ref. return llvm::make_unique<VariableExprAST>(IdName); - + // Call. getNextToken(); // eat ( std::vector<std::unique_ptr<ExprAST>> Args; @@ -318,7 +318,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() { // Eat the ')'. getNextToken(); - + return llvm::make_unique<CallExprAST>(IdName, std::move(Args)); } @@ -335,7 +335,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { auto V = ParseExpression(); if (!V) return nullptr; - + if (CurTok != ')') return ErrorU<ExprAST>("expected ')'"); getNextToken(); // eat ). @@ -345,29 +345,29 @@ static std::unique_ptr<ExprAST> ParseParenExpr() { /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr<ExprAST> ParseIfExpr() { getNextToken(); // eat the if. - + // condition. auto Cond = ParseExpression(); if (!Cond) return nullptr; - + if (CurTok != tok_then) return ErrorU<ExprAST>("expected then"); getNextToken(); // eat the then - + auto Then = ParseExpression(); if (!Then) return nullptr; - + if (CurTok != tok_else) return ErrorU<ExprAST>("expected else"); - + getNextToken(); - + auto Else = ParseExpression(); if (!Else) return nullptr; - + return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then), std::move(Else)); } @@ -378,26 +378,25 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (CurTok != tok_identifier) return ErrorU<ForExprAST>("expected identifier after for"); - + std::string IdName = IdentifierStr; getNextToken(); // eat identifier. - + if (CurTok != '=') return ErrorU<ForExprAST>("expected '=' after for"); getNextToken(); // eat '='. - - + auto Start = ParseExpression(); if (!Start) return nullptr; if (CurTok != ',') return ErrorU<ForExprAST>("expected ',' after for start value"); getNextToken(); - + auto End = ParseExpression(); if (!End) return nullptr; - + // The step value is optional. std::unique_ptr<ExprAST> Step; if (CurTok == ',') { @@ -406,11 +405,11 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { if (!Step) return nullptr; } - + if (CurTok != tok_in) return ErrorU<ForExprAST>("expected 'in' after for"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (Body) return nullptr; @@ -419,7 +418,7 @@ static std::unique_ptr<ForExprAST> ParseForExpr() { std::move(Step), std::move(Body)); } -/// varexpr ::= 'var' identifier ('=' expression)? +/// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression static std::unique_ptr<VarExprAST> ParseVarExpr() { getNextToken(); // eat the var. @@ -429,7 +428,7 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { // At least one variable name is required. if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier after var"); - + while (1) { std::string Name = IdentifierStr; getNextToken(); // eat identifier. @@ -438,31 +437,31 @@ static std::unique_ptr<VarExprAST> ParseVarExpr() { std::unique_ptr<ExprAST> Init; if (CurTok == '=') { getNextToken(); // eat the '='. - + Init = ParseExpression(); if (!Init) return nullptr; } - + VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init))); - + // End of var list, exit loop. if (CurTok != ',') break; getNextToken(); // eat the ','. - + if (CurTok != tok_identifier) return ErrorU<VarExprAST>("expected identifier list after var"); } - + // At this point, we have to have 'in'. if (CurTok != tok_in) return ErrorU<VarExprAST>("expected 'in' keyword after 'var'"); getNextToken(); // eat 'in'. - + auto Body = ParseExpression(); if (!Body) return nullptr; - + return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body)); } @@ -492,7 +491,7 @@ static std::unique_ptr<ExprAST> ParseUnary() { // If the current token is not an operator, it must be a primary expr. if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') return ParsePrimary(); - + // If this is a unary operator, read it. int Opc = CurTok; getNextToken(); @@ -508,21 +507,21 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; getNextToken(); // eat binop - + // Parse the unary expression after the binary operator. auto RHS = ParseUnary(); if (!RHS) return nullptr; - + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); @@ -531,7 +530,7 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, if (!RHS) return nullptr; } - + // Merge LHS/RHS. LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS)); } @@ -544,7 +543,7 @@ static std::unique_ptr<ExprAST> ParseExpression() { auto LHS = ParseUnary(); if (!LHS) return nullptr; - + return ParseBinOpRHS(0, std::move(LHS)); } @@ -554,10 +553,10 @@ static std::unique_ptr<ExprAST> ParseExpression() { /// ::= unary LETTER (id) static std::unique_ptr<PrototypeAST> ParsePrototype() { std::string FnName; - + unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. unsigned BinaryPrecedence = 30; - + switch (CurTok) { default: return ErrorU<PrototypeAST>("Expected function name in prototype"); @@ -583,7 +582,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { FnName += (char)CurTok; Kind = 2; getNextToken(); - + // Read the precedence if present. if (CurTok == tok_number) { if (NumVal < 1 || NumVal > 100) @@ -593,23 +592,23 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { } break; } - + if (CurTok != '(') return ErrorU<PrototypeAST>("Expected '(' in prototype"); - + std::vector<std::string> ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorU<PrototypeAST>("Expected ')' in prototype"); - + // success. getNextToken(); // eat ')'. - + // Verify right number of names for operator. if (Kind && ArgNames.size() != Kind) return ErrorU<PrototypeAST>("Invalid number of operands for operator"); - + return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0, BinaryPrecedence); } @@ -690,10 +689,10 @@ public: PrototypeAST* getPrototypeAST(const std::string &Name); private: typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap; - + LLVMContext &Context; std::unique_ptr<TargetMachine> TM; - + PrototypeMap Prototypes; }; @@ -716,7 +715,7 @@ public: M(new Module(GenerateUniqueName("jit_module_"), Session.getLLVMContext())), Builder(Session.getLLVMContext()) { - M->setDataLayout(*Session.getTarget().getDataLayout()); + M->setDataLayout(Session.getTarget().createDataLayout()); } SessionContext& getSession() { return Session; } @@ -747,7 +746,7 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, const std::string &VarName) { IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin()); - return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0, + return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), nullptr, VarName.c_str()); } @@ -759,7 +758,7 @@ Value *VariableExprAST::IRGen(IRGenContext &C) const { // Look this variable up in the function. Value *V = C.NamedValues[Name]; - if (V == 0) + if (!V) return ErrorP<Value>("Unknown variable name '" + Name + "'"); // Load the value. @@ -782,7 +781,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { // Assignment requires the LHS to be an identifier. - auto LHSVar = static_cast<VariableExprAST&>(*LHS); + auto &LHSVar = static_cast<VariableExprAST &>(*LHS); // Codegen the RHS. Value *Val = RHS->IRGen(C); if (!Val) return nullptr; @@ -794,11 +793,11 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { } return ErrorP<Value>("Unknown variable name"); } - + Value *L = LHS->IRGen(C); Value *R = RHS->IRGen(C); if (!L || !R) return nullptr; - + switch (Op) { case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp"); case '-': return C.getBuilder().CreateFSub(L, R, "subtmp"); @@ -811,7 +810,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { "booltmp"); default: break; } - + // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. std::string FnName = MakeLegalFunctionName(std::string("binary")+Op); @@ -819,7 +818,7 @@ Value *BinaryExprAST::IRGen(IRGenContext &C) const { Value *Ops[] = { L, R }; return C.getBuilder().CreateCall(F, Ops, "binop"); } - + return ErrorP<Value>("Unknown binary operator"); } @@ -835,7 +834,7 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { ArgsV.push_back(Args[i]->IRGen(C)); if (!ArgsV.back()) return nullptr; } - + return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp"); } @@ -845,49 +844,49 @@ Value *CallExprAST::IRGen(IRGenContext &C) const { Value *IfExprAST::IRGen(IRGenContext &C) const { Value *CondV = Cond->IRGen(C); if (!CondV) return nullptr; - + // Convert condition to a bool by comparing equal to 0.0. - ConstantFP *FPZero = + ConstantFP *FPZero = ConstantFP::get(C.getLLVMContext(), APFloat(0.0)); CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond"); - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); - + // Create blocks for the then and else cases. Insert the 'then' block at the // end of the function. BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction); BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else"); BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont"); - + C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB); - + // Emit then value. C.getBuilder().SetInsertPoint(ThenBB); - + Value *ThenV = Then->IRGen(C); if (!ThenV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. ThenBB = C.getBuilder().GetInsertBlock(); - + // Emit else block. TheFunction->getBasicBlockList().push_back(ElseBB); C.getBuilder().SetInsertPoint(ElseBB); - + Value *ElseV = Else->IRGen(C); if (!ElseV) return nullptr; - + C.getBuilder().CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. ElseBB = C.getBuilder().GetInsertBlock(); - + // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); C.getBuilder().SetInsertPoint(MergeBB); PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); - + PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); return PN; @@ -900,7 +899,7 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // start = startexpr // store start -> var // goto loop - // loop: + // loop: // ... // bodyexpr // ... @@ -913,40 +912,40 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // store nextvar -> var // br endcond, loop, endloop // outloop: - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); - + // Emit the start code first, without 'variable' in scope. Value *StartVal = Start->IRGen(C); if (!StartVal) return nullptr; - + // Store the value into the alloca. C.getBuilder().CreateStore(StartVal, Alloca); - + // Make the new basic block for the loop header, inserting after current // block. BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); - + // Insert an explicit fall through from the current block to the LoopBB. C.getBuilder().CreateBr(LoopBB); // Start insertion in LoopBB. C.getBuilder().SetInsertPoint(LoopBB); - + // Within the loop, the variable is defined equal to the PHI node. If it // shadows an existing variable, we have to restore it, so save it now. AllocaInst *OldVal = C.NamedValues[VarName]; C.NamedValues[VarName] = Alloca; - + // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. if (!Body->IRGen(C)) return nullptr; - + // Emit the step value. Value *StepVal; if (Step) { @@ -956,52 +955,51 @@ Value *ForExprAST::IRGen(IRGenContext &C) const { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); } - + // Compute the end condition. Value *EndCond = End->IRGen(C); - if (EndCond == 0) return EndCond; - + if (!EndCond) return nullptr; + // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str()); Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar"); C.getBuilder().CreateStore(NextVar, Alloca); - + // Convert condition to a bool by comparing equal to 0.0. - EndCond = C.getBuilder().CreateFCmpONE(EndCond, + EndCond = C.getBuilder().CreateFCmpONE(EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond"); - + // Create the "after loop" block and insert it. BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); - + // Insert the conditional branch into the end of LoopEndBB. C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB); - + // Any new code will be inserted in AfterBB. C.getBuilder().SetInsertPoint(AfterBB); - + // Restore the unshadowed variable. if (OldVal) C.NamedValues[VarName] = OldVal; else C.NamedValues.erase(VarName); - // for expr always returns 0.0. return Constant::getNullValue(Type::getDoubleTy(getGlobalContext())); } Value *VarExprAST::IRGen(IRGenContext &C) const { std::vector<AllocaInst *> OldBindings; - + Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent(); // Register all variables and emit their initializer. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) { auto &VarName = VarBindings[i].first; auto &Init = VarBindings[i].second; - + // Emit the initializer before adding the variable to scope, this prevents // the initializer from referencing the variable itself, and permits stuff // like this: @@ -1013,22 +1011,22 @@ Value *VarExprAST::IRGen(IRGenContext &C) const { if (!InitVal) return nullptr; } else // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); - + AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); C.getBuilder().CreateStore(InitVal, Alloca); // Remember the old variable binding so that we can restore the binding when // we unrecurse. OldBindings.push_back(C.NamedValues[VarName]); - + // Remember this binding. C.NamedValues[VarName] = Alloca; } - + // Codegen the body, now that all vars are in scope. Value *BodyVal = Body->IRGen(C); if (!BodyVal) return nullptr; - + // Pop all our variables from scope. for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) C.NamedValues[VarBindings[i].first] = OldBindings[i]; @@ -1041,7 +1039,7 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { std::string FnName = MakeLegalFunctionName(Name); // Make the function type: double(double,double) etc. - std::vector<Type*> Doubles(Args.size(), + std::vector<Type*> Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1054,26 +1052,26 @@ Function *PrototypeAST::IRGen(IRGenContext &C) const { // Delete the one we just made and get the existing one. F->eraseFromParent(); F = C.getM().getFunction(Name); - + // If F already has a body, reject this. if (!F->empty()) { ErrorP<Function>("redefinition of function"); return nullptr; } - + // If F took a different number of args, reject. if (F->arg_size() != Args.size()) { ErrorP<Function>("redefinition of function with different # args"); return nullptr; } } - + // Set names for all arguments. unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); ++AI, ++Idx) AI->setName(Args[Idx]); - + return F; } @@ -1086,7 +1084,7 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]); // Store the initial value into the alloca. - C.getBuilder().CreateStore(AI, Alloca); + C.getBuilder().CreateStore(&*AI, Alloca); // Add arguments to variable symbol table. C.NamedValues[Args[Idx]] = Alloca; @@ -1095,19 +1093,19 @@ void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) { Function *FunctionAST::IRGen(IRGenContext &C) const { C.NamedValues.clear(); - + Function *TheFunction = Proto->IRGen(C); if (!TheFunction) return nullptr; - + // If this is an operator, install it. if (Proto->isBinaryOp()) BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence; - + // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); C.getBuilder().SetInsertPoint(BB); - + // Add all arguments to the symbol table and create their allocas. Proto->CreateArgumentAllocas(TheFunction, C); @@ -1120,7 +1118,7 @@ Function *FunctionAST::IRGen(IRGenContext &C) const { return TheFunction; } - + // Error reading body, remove function. TheFunction->eraseFromParent(); @@ -1170,7 +1168,7 @@ public: { raw_string_ostream MangledNameStream(MangledName); Mangler::getNameWithPrefix(MangledNameStream, Name, - *Session.getTarget().getDataLayout()); + Session.getTarget().createDataLayout()); } return MangledName; } @@ -1223,7 +1221,7 @@ private: RuntimeDyld::SymbolInfo searchFunctionASTs(const std::string &Name) { auto DefI = FunctionDefs.find(Name); if (DefI == FunctionDefs.end()) - return 0; + return nullptr; // Take the FunctionAST out of the map. auto FnAST = std::move(DefI->second); @@ -1277,7 +1275,7 @@ static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) { // Get the address of the JIT'd function in memory. auto ExprSymbol = J.findUnmangledSymbol("__anon_expr"); - + // Cast it to the right type (takes no arguments, returns a double) so we // can call it as a native function. double (*FP)() = (double (*)())(intptr_t)ExprSymbol.getAddress(); @@ -1320,20 +1318,20 @@ static void MainLoop() { //===----------------------------------------------------------------------===// /// putchard - putchar that takes a double and returns 0. -extern "C" +extern "C" double putchard(double X) { putchar((char)X); return 0; } /// printd - printf that takes a double prints it as "%f\n", returning 0. -extern "C" +extern "C" double printd(double X) { printf("%f", X); return 0; } -extern "C" +extern "C" double printlf() { printf("\n"); return 0; @@ -1370,4 +1368,3 @@ int main() { return 0; } - diff --git a/examples/Kaleidoscope/include/KaleidoscopeJIT.h b/examples/Kaleidoscope/include/KaleidoscopeJIT.h new file mode 100644 index 000000000000..0c825cc94c0e --- /dev/null +++ b/examples/Kaleidoscope/include/KaleidoscopeJIT.h @@ -0,0 +1,114 @@ +//===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Contains a simple JIT definition for use in the kaleidoscope tutorials. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H +#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H + +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" +#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" +#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/IR/Mangler.h" +#include "llvm/Support/DynamicLibrary.h" + +namespace llvm { +namespace orc { + +class KaleidoscopeJIT { +public: + typedef ObjectLinkingLayer<> ObjLayerT; + typedef IRCompileLayer<ObjLayerT> CompileLayerT; + typedef CompileLayerT::ModuleSetHandleT ModuleHandleT; + + KaleidoscopeJIT() + : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), + CompileLayer(ObjectLayer, SimpleCompiler(*TM)) { + llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); + } + + TargetMachine &getTargetMachine() { return *TM; } + + ModuleHandleT addModule(std::unique_ptr<Module> M) { + // We need a memory manager to allocate memory and resolve symbols for this + // new module. Create one that resolves symbols by looking back into the + // JIT. + auto Resolver = createLambdaResolver( + [&](const std::string &Name) { + if (auto Sym = findMangledSymbol(Name)) + return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags()); + return RuntimeDyld::SymbolInfo(nullptr); + }, + [](const std::string &S) { return nullptr; }); + auto H = CompileLayer.addModuleSet(singletonSet(std::move(M)), + make_unique<SectionMemoryManager>(), + std::move(Resolver)); + + ModuleHandles.push_back(H); + return H; + } + + void removeModule(ModuleHandleT H) { + ModuleHandles.erase( + std::find(ModuleHandles.begin(), ModuleHandles.end(), H)); + CompileLayer.removeModuleSet(H); + } + + JITSymbol findSymbol(const std::string Name) { + return findMangledSymbol(mangle(Name)); + } + +private: + + std::string mangle(const std::string &Name) { + std::string MangledName; + { + raw_string_ostream MangledNameStream(MangledName); + Mangler::getNameWithPrefix(MangledNameStream, Name, DL); + } + return MangledName; + } + + template <typename T> static std::vector<T> singletonSet(T t) { + std::vector<T> Vec; + Vec.push_back(std::move(t)); + return Vec; + } + + JITSymbol findMangledSymbol(const std::string &Name) { + // Search modules in reverse order: from last added to first added. + // This is the opposite of the usual search order for dlsym, but makes more + // sense in a REPL where we want to bind to the newest available definition. + for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend())) + if (auto Sym = CompileLayer.findSymbolIn(H, Name, true)) + return Sym; + + // If we can't find the symbol in the JIT, try looking in the host process. + if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) + return JITSymbol(SymAddr, JITSymbolFlags::Exported); + + return nullptr; + } + + std::unique_ptr<TargetMachine> TM; + const DataLayout DL; + ObjLayerT ObjectLayer; + CompileLayerT CompileLayer; + std::vector<ModuleHandleT> ModuleHandles; +}; + +} // End namespace orc. +} // End namespace llvm + +#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H diff --git a/examples/ParallelJIT/ParallelJIT.cpp b/examples/ParallelJIT/ParallelJIT.cpp index b2c53a9bb10e..3c485d4c964d 100644 --- a/examples/ParallelJIT/ParallelJIT.cpp +++ b/examples/ParallelJIT/ParallelJIT.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/TargetSelect.h" #include <iostream> #include <pthread.h> + using namespace llvm; static Function* createAdd1(Module *M) { @@ -38,7 +39,7 @@ static Function* createAdd1(Module *M) { cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(M->getContext()), Type::getInt32Ty(M->getContext()), - (Type *)0)); + nullptr)); // Add a basic block to the function. As before, it automatically inserts // because of the last argument. @@ -49,7 +50,7 @@ static Function* createAdd1(Module *M) { // Get pointers to the integer argument of the add1 function... assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg - Argument *ArgX = Add1F->arg_begin(); // Get the arg + Argument *ArgX = &*Add1F->arg_begin(); // Get the arg ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. // Create the add instruction, inserting it into the end of BB. @@ -69,7 +70,7 @@ static Function *CreateFibFunction(Module *M) { cast<Function>(M->getOrInsertFunction("fib", Type::getInt32Ty(M->getContext()), Type::getInt32Ty(M->getContext()), - (Type *)0)); + nullptr)); // Add a basic block to the function. BasicBlock *BB = BasicBlock::Create(M->getContext(), "EntryBlock", FibF); @@ -79,7 +80,7 @@ static Function *CreateFibFunction(Module *M) { Value *Two = ConstantInt::get(Type::getInt32Ty(M->getContext()), 2); // Get pointer to the integer argument of the add1 function... - Argument *ArgX = FibF->arg_begin(); // Get the arg. + Argument *ArgX = &*FibF->arg_begin(); // Get the arg. ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. // Create the true_block. @@ -129,10 +130,10 @@ public: n = 0; waitFor = 0; - int result = pthread_cond_init( &condition, NULL ); + int result = pthread_cond_init( &condition, nullptr ); assert( result == 0 ); - result = pthread_mutex_init( &mutex, NULL ); + result = pthread_mutex_init( &mutex, nullptr ); assert( result == 0 ); } @@ -261,21 +262,21 @@ int main() { struct threadParams fib2 = { EE, fibF, 42 }; pthread_t add1Thread; - int result = pthread_create( &add1Thread, NULL, callFunc, &add1 ); + int result = pthread_create( &add1Thread, nullptr, callFunc, &add1 ); if ( result != 0 ) { std::cerr << "Could not create thread" << std::endl; return 1; } pthread_t fibThread1; - result = pthread_create( &fibThread1, NULL, callFunc, &fib1 ); + result = pthread_create( &fibThread1, nullptr, callFunc, &fib1 ); if ( result != 0 ) { std::cerr << "Could not create thread" << std::endl; return 1; } pthread_t fibThread2; - result = pthread_create( &fibThread2, NULL, callFunc, &fib2 ); + result = pthread_create( &fibThread2, nullptr, callFunc, &fib2 ); if ( result != 0 ) { std::cerr << "Could not create thread" << std::endl; return 1; |