From 2d789c3699e75b31798fc696c38fcfb3f8d47477 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 26 Aug 2015 03:07:41 +0000 Subject: Big Kaleidoscope tutorial update. This commit switches the underlying JIT for the Kaleidoscope tutorials from MCJIT to a custom ORC-based JIT, KaleidoscopeJIT. This fixes a lot of the bugs in Kaleidoscope that were introduced when we deleted the legacy JIT. The documentation for Chapter 4, which introduces the JIT APIs, is updated to reflect the change. Also included are a number of C++11 modernizations and general cleanup. Where appropriate, the docs have been updated to reflect these changes too. llvm-svn: 246002 --- llvm/examples/Kaleidoscope/Chapter3/toy.cpp | 109 +++++++++++----------------- 1 file changed, 42 insertions(+), 67 deletions(-) (limited to 'llvm/examples/Kaleidoscope/Chapter3/toy.cpp') diff --git a/llvm/examples/Kaleidoscope/Chapter3/toy.cpp b/llvm/examples/Kaleidoscope/Chapter3/toy.cpp index cb4f75f7917..328189c1184 100644 --- a/llvm/examples/Kaleidoscope/Chapter3/toy.cpp +++ b/llvm/examples/Kaleidoscope/Chapter3/toy.cpp @@ -1,9 +1,8 @@ #include "llvm/ADT/STLExtras.h" -#include "llvm/IR/Verifier.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" #include #include #include @@ -91,7 +90,7 @@ namespace { class ExprAST { public: virtual ~ExprAST() {} - virtual Value *Codegen() = 0; + virtual Value *codegen() = 0; }; /// NumberExprAST - Expression class for numeric literals like "1.0". @@ -100,7 +99,7 @@ class NumberExprAST : public ExprAST { public: NumberExprAST(double Val) : Val(Val) {} - Value *Codegen() override; + Value *codegen() override; }; /// VariableExprAST - Expression class for referencing a variable, like "a". @@ -109,7 +108,7 @@ class VariableExprAST : public ExprAST { public: VariableExprAST(const std::string &Name) : Name(Name) {} - Value *Codegen() override; + Value *codegen() override; }; /// BinaryExprAST - Expression class for a binary operator. @@ -121,7 +120,7 @@ public: BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} - Value *Codegen() override; + Value *codegen() override; }; /// CallExprAST - Expression class for function calls. @@ -133,7 +132,7 @@ public: CallExprAST(const std::string &Callee, std::vector> Args) : Callee(Callee), Args(std::move(Args)) {} - Value *Codegen() override; + Value *codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, @@ -146,7 +145,8 @@ class PrototypeAST { public: PrototypeAST(const std::string &Name, std::vector Args) : Name(Name), Args(std::move(Args)) {} - Function *Codegen(); + Function *codegen(); + const std::string &getName() const { return Name; } }; /// FunctionAST - This class represents a function definition itself. @@ -158,7 +158,7 @@ public: FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} - Function *Codegen(); + Function *codegen(); }; } // end anonymous namespace @@ -197,10 +197,6 @@ std::unique_ptr ErrorP(const char *Str) { Error(Str); return nullptr; } -std::unique_ptr ErrorF(const char *Str) { - Error(Str); - return nullptr; -} static std::unique_ptr ParseExpression(); @@ -365,8 +361,8 @@ static std::unique_ptr ParseDefinition() { static std::unique_ptr ParseTopLevelExpr() { if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = - llvm::make_unique("", std::vector()); + auto Proto = llvm::make_unique("__anon_expr", + std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -382,20 +378,20 @@ static std::unique_ptr ParseExtern() { // Code Generation //===----------------------------------------------------------------------===// +static std::unique_ptr TheModule; +static IRBuilder<> Builder(getGlobalContext()); +static std::map NamedValues; + Value *ErrorV(const char *Str) { Error(Str); return nullptr; } -static Module *TheModule; -static IRBuilder<> Builder(getGlobalContext()); -static std::map NamedValues; - -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) @@ -403,9 +399,9 @@ Value *VariableExprAST::Codegen() { return V; } -Value *BinaryExprAST::Codegen() { - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); +Value *BinaryExprAST::codegen() { + Value *L = LHS->codegen(); + Value *R = RHS->codegen(); if (!L || !R) return nullptr; @@ -426,7 +422,7 @@ 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) @@ -438,7 +434,7 @@ Value *CallExprAST::Codegen() { std::vector ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); + ArgsV.push_back(Args[i]->codegen()); if (!ArgsV.back()) return nullptr; } @@ -446,7 +442,7 @@ Value *CallExprAST::Codegen() { return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } -Function *PrototypeAST::Codegen() { +Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. std::vector Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); @@ -454,45 +450,23 @@ 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 nullptr; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return nullptr; - } - } + 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 *FunctionAST::codegen() { + // First, check for an existing function from a previous 'extern' declaration. + Function *TheFunction = TheModule->getFunction(Proto->getName()); + + if (!TheFunction) + TheFunction = Proto->codegen(); - Function *TheFunction = Proto->Codegen(); if (!TheFunction) return nullptr; @@ -500,7 +474,12 @@ Function *FunctionAST::Codegen() { 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); @@ -521,7 +500,7 @@ Function *FunctionAST::Codegen() { static void HandleDefinition() { if (auto FnAST = ParseDefinition()) { - if (auto *FnIR = FnAST->Codegen()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read function definition:"); FnIR->dump(); } @@ -533,7 +512,7 @@ static void HandleDefinition() { static void HandleExtern() { if (auto ProtoAST = ParseExtern()) { - if (auto *FnIR = ProtoAST->Codegen()) { + if (auto *FnIR = ProtoAST->codegen()) { fprintf(stderr, "Read extern: "); FnIR->dump(); } @@ -546,7 +525,7 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. if (auto FnAST = ParseTopLevelExpr()) { - if (auto *FnIR = FnAST->Codegen()) { + if (auto *FnIR = FnAST->codegen()) { fprintf(stderr, "Read top-level expression:"); FnIR->dump(); } @@ -584,8 +563,6 @@ static void MainLoop() { //===----------------------------------------------------------------------===// int main() { - LLVMContext &Context = getGlobalContext(); - // Install standard binary operators. // 1 is lowest precedence. BinopPrecedence['<'] = 10; @@ -598,9 +575,7 @@ int main() { getNextToken(); // Make the module, which holds all the code. - std::unique_ptr Owner = - llvm::make_unique("my cool jit", Context); - TheModule = Owner.get(); + TheModule = llvm::make_unique("my cool jit", getGlobalContext()); // Run the main "interpreter loop" now. MainLoop(); -- cgit v1.2.3