summaryrefslogtreecommitdiffstats
path: root/llvm/examples/Kaleidoscope/Chapter3/toy.cpp
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2015-08-26 03:07:41 +0000
committerLang Hames <lhames@gmail.com>2015-08-26 03:07:41 +0000
commit2d789c3699e75b31798fc696c38fcfb3f8d47477 (patch)
tree36abf050f79f78d374e44ddbe2e8e328f3cc97fc /llvm/examples/Kaleidoscope/Chapter3/toy.cpp
parent9dc042a0b62c817412a2f0fbddcab7b2f953aec8 (diff)
downloadbcm5719-llvm-2d789c3699e75b31798fc696c38fcfb3f8d47477.tar.gz
bcm5719-llvm-2d789c3699e75b31798fc696c38fcfb3f8d47477.zip
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
Diffstat (limited to 'llvm/examples/Kaleidoscope/Chapter3/toy.cpp')
-rw-r--r--llvm/examples/Kaleidoscope/Chapter3/toy.cpp109
1 files changed, 42 insertions, 67 deletions
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 <cctype>
#include <cstdio>
#include <map>
@@ -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<ExprAST> LHS,
std::unique_ptr<ExprAST> 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<std::unique_ptr<ExprAST>> 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<std::string> 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<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
- Function *Codegen();
+ Function *codegen();
};
} // end anonymous namespace
@@ -197,10 +197,6 @@ std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
Error(Str);
return nullptr;
}
-std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
- Error(Str);
- return nullptr;
-}
static std::unique_ptr<ExprAST> ParseExpression();
@@ -365,8 +361,8 @@ static std::unique_ptr<FunctionAST> ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto =
- llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
+ std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
@@ -382,20 +378,20 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//
+static std::unique_ptr<Module> TheModule;
+static IRBuilder<> Builder(getGlobalContext());
+static std::map<std::string, Value *> NamedValues;
+
Value *ErrorV(const char *Str) {
Error(Str);
return nullptr;
}
-static Module *TheModule;
-static IRBuilder<> Builder(getGlobalContext());
-static std::map<std::string, Value *> 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<Value *> 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<Type *> 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<Module> Owner =
- llvm::make_unique<Module>("my cool jit", Context);
- TheModule = Owner.get();
+ TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
// Run the main "interpreter loop" now.
MainLoop();
OpenPOWER on IntegriCloud