aboutsummaryrefslogtreecommitdiff
path: root/examples/Kaleidoscope/Chapter6/toy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/Kaleidoscope/Chapter6/toy.cpp')
-rw-r--r--examples/Kaleidoscope/Chapter6/toy.cpp117
1 files changed, 62 insertions, 55 deletions
diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp
index 4d04f7e888af..85d953b0c756 100644
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -1,18 +1,30 @@
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Scalar/GVN.h"
+#include "../include/KaleidoscopeJIT.h"
+#include <cassert>
#include <cctype>
+#include <cstdint>
#include <cstdio>
+#include <cstdlib>
#include <map>
+#include <memory>
#include <string>
#include <vector>
-#include "../include/KaleidoscopeJIT.h"
using namespace llvm;
using namespace llvm::orc;
@@ -271,13 +283,13 @@ static int GetTokPrecedence() {
}
/// Error* - These are little helper functions for error handling.
-std::unique_ptr<ExprAST> Error(const char *Str) {
+std::unique_ptr<ExprAST> LogError(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
-std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
- Error(Str);
+std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -298,7 +310,7 @@ static std::unique_ptr<ExprAST> ParseParenExpr() {
return nullptr;
if (CurTok != ')')
- return Error("expected ')'");
+ return LogError("expected ')'");
getNextToken(); // eat ).
return V;
}
@@ -318,7 +330,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
- while (1) {
+ while (true) {
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
@@ -328,7 +340,7 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
break;
if (CurTok != ',')
- return Error("Expected ')' or ',' in argument list");
+ return LogError("Expected ')' or ',' in argument list");
getNextToken();
}
}
@@ -349,7 +361,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_then)
- return Error("expected then");
+ return LogError("expected then");
getNextToken(); // eat the then
auto Then = ParseExpression();
@@ -357,7 +369,7 @@ static std::unique_ptr<ExprAST> ParseIfExpr() {
return nullptr;
if (CurTok != tok_else)
- return Error("expected else");
+ return LogError("expected else");
getNextToken();
@@ -374,20 +386,20 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
- return Error("expected identifier after for");
+ return LogError("expected identifier after for");
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '=')
- return Error("expected '=' after for");
+ return LogError("expected '=' after for");
getNextToken(); // eat '='.
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
- return Error("expected ',' after for start value");
+ return LogError("expected ',' after for start value");
getNextToken();
auto End = ParseExpression();
@@ -404,7 +416,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
}
if (CurTok != tok_in)
- return Error("expected 'in' after for");
+ return LogError("expected 'in' after for");
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
@@ -424,7 +436,7 @@ static std::unique_ptr<ExprAST> ParseForExpr() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
- return Error("unknown token when expecting an expression");
+ return LogError("unknown token when expecting an expression");
case tok_identifier:
return ParseIdentifierExpr();
case tok_number:
@@ -459,7 +471,7 @@ static std::unique_ptr<ExprAST> ParseUnary() {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
- while (1) {
+ while (true) {
int TokPrec = GetTokPrecedence();
// If this is a binop that binds at least as tightly as the current binop,
@@ -514,7 +526,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
switch (CurTok) {
default:
- return ErrorP("Expected function name in prototype");
+ return LogErrorP("Expected function name in prototype");
case tok_identifier:
FnName = IdentifierStr;
Kind = 0;
@@ -523,7 +535,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_unary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected unary operator");
+ return LogErrorP("Expected unary operator");
FnName = "unary";
FnName += (char)CurTok;
Kind = 1;
@@ -532,7 +544,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
case tok_binary:
getNextToken();
if (!isascii(CurTok))
- return ErrorP("Expected binary operator");
+ return LogErrorP("Expected binary operator");
FnName = "binary";
FnName += (char)CurTok;
Kind = 2;
@@ -541,7 +553,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return ErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedecnce: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -549,20 +561,20 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
}
if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
+ return LogErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
+ return LogErrorP("Expected ')' in prototype");
// success.
getNextToken(); // eat ')'.
// Verify right number of names for operator.
if (Kind && ArgNames.size() != Kind)
- return ErrorP("Invalid number of operands for operator");
+ return LogErrorP("Invalid number of operands for operator");
return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
BinaryPrecedence);
@@ -601,15 +613,16 @@ static std::unique_ptr<PrototypeAST> ParseExtern() {
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
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);
+Value *LogErrorV(const char *Str) {
+ LogError(Str);
return nullptr;
}
@@ -629,14 +642,14 @@ Function *getFunction(std::string Name) {
}
Value *NumberExprAST::codegen() {
- return ConstantFP::get(getGlobalContext(), APFloat(Val));
+ return ConstantFP::get(TheContext, APFloat(Val));
}
Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
- return ErrorV("Unknown variable name");
+ return LogErrorV("Unknown variable name");
return V;
}
@@ -647,7 +660,7 @@ Value *UnaryExprAST::codegen() {
Function *F = getFunction(std::string("unary") + Opcode);
if (!F)
- return ErrorV("Unknown unary operator");
+ return LogErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
}
@@ -668,8 +681,7 @@ Value *BinaryExprAST::codegen() {
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");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
default:
break;
}
@@ -687,11 +699,11 @@ Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = getFunction(Callee);
if (!CalleeF)
- return ErrorV("Unknown function referenced");
+ return LogErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
- return ErrorV("Incorrect # arguments passed");
+ return LogErrorV("Incorrect # arguments passed");
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
@@ -710,16 +722,15 @@ Value *IfExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
- CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond");
+ CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
- BasicBlock *ThenBB =
- BasicBlock::Create(getGlobalContext(), "then", TheFunction);
- BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
- BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
+ BasicBlock *ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
+ BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else");
+ BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, ElseBB);
@@ -749,8 +760,7 @@ Value *IfExprAST::codegen() {
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
- PHINode *PN =
- Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp");
+ PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
@@ -782,8 +792,7 @@ Value *ForExprAST::codegen() {
// block.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
BasicBlock *PreheaderBB = Builder.GetInsertBlock();
- BasicBlock *LoopBB =
- BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
+ BasicBlock *LoopBB = BasicBlock::Create(TheContext, "loop", TheFunction);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
@@ -792,8 +801,8 @@ Value *ForExprAST::codegen() {
Builder.SetInsertPoint(LoopBB);
// Start the PHI node with an entry for Start.
- PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
- 2, VarName.c_str());
+ PHINode *Variable =
+ Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, VarName);
Variable->addIncoming(StartVal, PreheaderBB);
// Within the loop, the variable is defined equal to the PHI node. If it
@@ -815,7 +824,7 @@ Value *ForExprAST::codegen() {
return nullptr;
} else {
// If not specified, use 1.0.
- StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
+ StepVal = ConstantFP::get(TheContext, APFloat(1.0));
}
Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar");
@@ -827,12 +836,12 @@ Value *ForExprAST::codegen() {
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
- EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond");
+ EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it.
BasicBlock *LoopEndBB = Builder.GetInsertBlock();
BasicBlock *AfterBB =
- BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
+ BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
@@ -850,15 +859,14 @@ Value *ForExprAST::codegen() {
NamedValues.erase(VarName);
// for expr always returns 0.0.
- return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
}
Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type *> Doubles(Args.size(),
- Type::getDoubleTy(getGlobalContext()));
+ std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(TheContext));
FunctionType *FT =
- FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
+ FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
Function *F =
Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
@@ -885,7 +893,7 @@ Function *FunctionAST::codegen() {
BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
// Create a new basic block to start insertion into.
- BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
+ BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
Builder.SetInsertPoint(BB);
// Record the function arguments in the NamedValues map.
@@ -920,7 +928,7 @@ Function *FunctionAST::codegen() {
static void InitializeModuleAndPassManager() {
// Open a new module.
- TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
+ TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
// Create a new pass manager attached to it.
@@ -969,7 +977,6 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
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));
@@ -995,7 +1002,7 @@ static void HandleTopLevelExpression() {
/// top ::= definition | external | expression | ';'
static void MainLoop() {
- while (1) {
+ while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof: