summaryrefslogtreecommitdiffstats
path: root/llvm/examples/Kaleidoscope/Chapter3/toy.cpp
diff options
context:
space:
mode:
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