#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 <map>
#include <string>
#include <vector>
+#include "../include/KaleidoscopeJIT.h"
+
using namespace llvm;
+using namespace llvm::orc;
//===----------------------------------------------------------------------===//
// Lexer
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;
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 = ' ';
LastChar = advance();
} while (isdigit(LastChar) || LastChar == '.');
- NumVal = strtod(NumStr.c_str(), 0);
+ NumVal = strtod(NumStr.c_str(), nullptr);
return tok_number;
}
public:
ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {}
virtual ~ExprAST() {}
- virtual Value *Codegen() = 0;
+ virtual Value *codegen() = 0;
int getLine() const { return Loc.Line; }
int getCol() const { return Loc.Col; }
virtual raw_ostream &dump(raw_ostream &out, int ind) {
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".
VariableExprAST(SourceLocation Loc, const std::string &Name)
: ExprAST(Loc), Name(Name) {}
const std::string &getName() const { return Name; }
+ 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.
public:
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.
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.
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 (const auto &Arg : Args)
Arg->dump(indent(out, ind + 1), ind + 1);
return out;
}
- Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
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);
Else->dump(indent(out, ind) << "Else:", ind + 1);
return out;
}
- Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
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);
Body->dump(indent(out, ind) << "Body:", ind + 1);
return out;
}
- Value *Codegen() override;
};
/// VarExprAST - Expression class for var/in
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)
Body->dump(indent(out, ind) << "Body:", ind + 1);
return out;
}
- Value *Codegen() override;
};
/// PrototypeAST - This class represents the "prototype" for a function,
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; }
}
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.
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
fprintf(stderr, "Error: %s\n", Str);
return nullptr;
}
+
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();
SourceLocation FnLoc = CurLoc;
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>(FnLoc, "main",
+ auto Proto = llvm::make_unique<PrototypeAST>(FnLoc, "__anon_expr",
std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
// Debug Info Support
//===----------------------------------------------------------------------===//
-static DIBuilder *DBuilder;
+static std::unique_ptr<DIBuilder> DBuilder;
DIType *DebugInfo::getDoubleTy() {
if (DblTy)
// 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 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
/// the function. This is used for mutable variables etc.
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)
return Builder.CreateLoad(V, Name.c_str());
}
-Value *UnaryExprAST::Codegen() {
- Value *OperandV = Operand->Codegen();
+Value *UnaryExprAST::codegen() {
+ Value *OperandV = Operand->codegen();
if (!OperandV)
return nullptr;
- Function *F = TheModule->getFunction(std::string("unary") + Opcode);
+ 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() {
KSDbgInfo.emitLocation(this);
// Special case '=' because we don't want to emit the LHS as an expression.
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
- Value *Val = RHS->Codegen();
+ Value *Val = RHS->codegen();
if (!Val)
return nullptr;
return Val;
}
- Value *L = LHS->Codegen();
- Value *R = RHS->Codegen();
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
if (!L || !R)
return nullptr;
// 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};
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);
+ Function *CalleeF = getFunction(Callee);
if (!CalleeF)
return ErrorV("Unknown function referenced");
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;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
-Value *IfExprAST::Codegen() {
+Value *IfExprAST::codegen() {
KSDbgInfo.emitLocation(this);
- Value *CondV = Cond->Codegen();
+ Value *CondV = Cond->codegen();
if (!CondV)
return nullptr;
// Emit then value.
Builder.SetInsertPoint(ThenBB);
- Value *ThenV = Then->Codegen();
+ Value *ThenV = Then->codegen();
if (!ThenV)
return nullptr;
TheFunction->getBasicBlockList().push_back(ElseBB);
Builder.SetInsertPoint(ElseBB);
- Value *ElseV = Else->Codegen();
+ Value *ElseV = Else->codegen();
if (!ElseV)
return nullptr;
// store nextvar -> var
// br endcond, loop, endloop
// outloop:
-Value *ForExprAST::Codegen() {
+Value *ForExprAST::codegen() {
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create an alloca for the variable in the entry block.
KSDbgInfo.emitLocation(this);
// Emit the start code first, without 'variable' in scope.
- Value *StartVal = Start->Codegen();
+ Value *StartVal = Start->codegen();
if (!StartVal)
return nullptr;
// 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())
+ if (!Body->codegen())
return nullptr;
// Emit the step value.
Value *StepVal = nullptr;
if (Step) {
- StepVal = Step->Codegen();
+ StepVal = Step->codegen();
if (!StepVal)
return nullptr;
} else {
}
// Compute the end condition.
- Value *EndCond = End->Codegen();
+ Value *EndCond = End->codegen();
if (!EndCond)
return nullptr;
return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
}
-Value *VarExprAST::Codegen() {
+Value *VarExprAST::codegen() {
std::vector<AllocaInst *> OldBindings;
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// var a = a in ... # refers to outer 'a'.
Value *InitVal;
if (Init) {
- InitVal = Init->Codegen();
+ InitVal = Init->codegen();
if (!InitVal)
return nullptr;
} else { // If not specified, use 0.0.
KSDbgInfo.emitLocation(this);
// Codegen the body, now that all vars are in scope.
- Value *BodyVal = Body->Codegen();
+ Value *BodyVal = Body->codegen();
if (!BodyVal)
return nullptr;
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()));
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]);
+ 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);
- 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->createParameterVariable(
- Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true);
+ 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();
-
- Function *TheFunction = Proto->Codegen();
- if (!TheFunction)
- return nullptr;
-
- // Push the current scope.
- KSDbgInfo.LexicalBlocks.push_back(KSDbgInfo.FnScopeMap[Proto.get()]);
-
- // 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.get());
- 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.
- 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
// 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 (auto FnAST = ParseDefinition()) {
- if (!FnAST->Codegen()) {
+ if (!FnAST->codegen())
fprintf(stderr, "Error reading function definition:");
- }
} else {
// Skip token for error recovery.
getNextToken();
static void HandleExtern() {
if (auto ProtoAST = ParseExtern()) {
- if (!ProtoAST->Codegen()) {
+ if (!ProtoAST->codegen())
fprintf(stderr, "Error reading extern");
- }
+ else
+ FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
} else {
// Skip token for error recovery.
getNextToken();
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
- if (!FnAST->Codegen()) {
+ if (!FnAST->codegen()) {
fprintf(stderr, "Error generating code for top level expr");
}
} else {
/// 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;
}
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
- LLVMContext &Context = getGlobalContext();
// Install standard binary operators.
// 1 is lowest precedence.
// 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",
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
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();