New Kaleidoscope chapter: Creating object files
This new chapter describes compiling LLVM IR to object files.
The new chaper is chapter 8, so later chapters have been renumbered.
Since this brings us to 10 chapters total, I've also needed to rename
the other chapters to use two digit numbering.
Differential Revision: http://reviews.llvm.org/D18070
llvm-svn: 274441
diff --git a/llvm/examples/Kaleidoscope/Chapter8/toy.cpp b/llvm/examples/Kaleidoscope/Chapter8/toy.cpp
index 99ff52b..f880bb8 100644
--- a/llvm/examples/Kaleidoscope/Chapter8/toy.cpp
+++ b/llvm/examples/Kaleidoscope/Chapter8/toy.cpp
@@ -1,28 +1,20 @@
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/Passes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
-#include "../include/KaleidoscopeJIT.h"
-#include <cassert>
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Transforms/Scalar.h"
#include <cctype>
#include <cstdio>
#include <cstdlib>
@@ -33,7 +25,7 @@
#include <vector>
using namespace llvm;
-using namespace llvm::orc;
+using namespace llvm::sys;
//===----------------------------------------------------------------------===//
// Lexer
@@ -67,71 +59,6 @@
tok_var = -13
};
-std::string getTokName(int Tok) {
- switch (Tok) {
- case tok_eof:
- return "eof";
- case tok_def:
- return "def";
- case tok_extern:
- return "extern";
- case tok_identifier:
- return "identifier";
- case tok_number:
- return "number";
- case tok_if:
- return "if";
- case tok_then:
- return "then";
- case tok_else:
- return "else";
- case tok_for:
- return "for";
- case tok_in:
- return "in";
- case tok_binary:
- return "binary";
- case tok_unary:
- return "unary";
- case tok_var:
- return "var";
- }
- return std::string(1, (char)Tok);
-}
-
-namespace {
-class ExprAST;
-} // end anonymous namespace
-
-static LLVMContext TheContext;
-static IRBuilder<> Builder(TheContext);
-struct DebugInfo {
- DICompileUnit *TheCU;
- DIType *DblTy;
- std::vector<DIScope *> LexicalBlocks;
-
- void emitLocation(ExprAST *AST);
- DIType *getDoubleTy();
-} KSDbgInfo;
-
-struct SourceLocation {
- int Line;
- int Col;
-};
-static SourceLocation CurLoc;
-static SourceLocation LexLoc = {1, 0};
-
-static int advance() {
- int LastChar = getchar();
-
- if (LastChar == '\n' || LastChar == '\r') {
- LexLoc.Line++;
- LexLoc.Col = 0;
- } else
- LexLoc.Col++;
- return LastChar;
-}
-
static std::string IdentifierStr; // Filled in if tok_identifier
static double NumVal; // Filled in if tok_number
@@ -141,13 +68,11 @@
// Skip any whitespace.
while (isspace(LastChar))
- LastChar = advance();
-
- CurLoc = LexLoc;
+ LastChar = getchar();
if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
IdentifierStr = LastChar;
- while (isalnum((LastChar = advance())))
+ while (isalnum((LastChar = getchar())))
IdentifierStr += LastChar;
if (IdentifierStr == "def")
@@ -177,7 +102,7 @@
std::string NumStr;
do {
NumStr += LastChar;
- LastChar = advance();
+ LastChar = getchar();
} while (isdigit(LastChar) || LastChar == '.');
NumVal = strtod(NumStr.c_str(), nullptr);
@@ -187,7 +112,7 @@
if (LastChar == '#') {
// Comment until end of line.
do
- LastChar = advance();
+ LastChar = getchar();
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
if (LastChar != EOF)
@@ -200,7 +125,7 @@
// Otherwise, just return the character as its ascii value.
int ThisChar = LastChar;
- LastChar = advance();
+ LastChar = getchar();
return ThisChar;
}
@@ -208,25 +133,11 @@
// Abstract Syntax Tree (aka Parse Tree)
//===----------------------------------------------------------------------===//
namespace {
-
-raw_ostream &indent(raw_ostream &O, int size) {
- return O << std::string(size, ' ');
-}
-
/// ExprAST - Base class for all expression nodes.
class ExprAST {
- SourceLocation Loc;
-
public:
- ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {}
virtual ~ExprAST() {}
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) {
- return out << ':' << getLine() << ':' << getCol() << '\n';
- }
};
/// NumberExprAST - Expression class for numeric literals like "1.0".
@@ -236,10 +147,6 @@
public:
NumberExprAST(double Val) : Val(Val) {}
Value *codegen() override;
-
- raw_ostream &dump(raw_ostream &out, int ind) override {
- return ExprAST::dump(out << Val, ind);
- }
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
@@ -247,14 +154,9 @@
std::string Name;
public:
- VariableExprAST(SourceLocation Loc, const std::string &Name)
- : ExprAST(Loc), Name(Name) {}
+ VariableExprAST(const std::string &Name) : 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);
- }
};
/// UnaryExprAST - Expression class for a unary operator.
@@ -266,12 +168,6 @@
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;
- }
};
/// BinaryExprAST - Expression class for a binary operator.
@@ -280,17 +176,10 @@
std::unique_ptr<ExprAST> LHS, RHS;
public:
- BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr<ExprAST> LHS,
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
- : ExprAST(Loc), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ : 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;
- }
};
/// CallExprAST - Expression class for function calls.
@@ -299,17 +188,10 @@
std::vector<std::unique_ptr<ExprAST>> Args;
public:
- CallExprAST(SourceLocation Loc, const std::string &Callee,
+ CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
- : ExprAST(Loc), Callee(Callee), Args(std::move(Args)) {}
+ : 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;
- }
};
/// IfExprAST - Expression class for if/then/else.
@@ -317,19 +199,10 @@
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
- IfExprAST(SourceLocation Loc, std::unique_ptr<ExprAST> Cond,
- std::unique_ptr<ExprAST> Then, std::unique_ptr<ExprAST> Else)
- : ExprAST(Loc), Cond(std::move(Cond)), Then(std::move(Then)),
- Else(std::move(Else)) {}
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : 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);
- Then->dump(indent(out, ind) << "Then:", ind + 1);
- Else->dump(indent(out, ind) << "Else:", ind + 1);
- return out;
- }
};
/// ForExprAST - Expression class for for/in.
@@ -344,15 +217,6 @@
: 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);
- End->dump(indent(out, ind) << "End:", ind + 1);
- Step->dump(indent(out, ind) << "Step:", ind + 1);
- Body->dump(indent(out, ind) << "Body:", ind + 1);
- return out;
- }
};
/// VarExprAST - Expression class for var/in
@@ -366,14 +230,6 @@
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)
- NamedVar.second->dump(indent(out, ind) << NamedVar.first << ':', ind + 1);
- Body->dump(indent(out, ind) << "Body:", ind + 1);
- return out;
- }
};
/// PrototypeAST - This class represents the "prototype" for a function,
@@ -384,14 +240,12 @@
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
- int Line;
public:
- PrototypeAST(SourceLocation Loc, const std::string &Name,
- std::vector<std::string> Args, bool IsOperator = false,
- unsigned Prec = 0)
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
: Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
- Precedence(Prec), Line(Loc.Line) {}
+ Precedence(Prec) {}
Function *codegen();
const std::string &getName() const { return Name; }
@@ -404,7 +258,6 @@
}
unsigned getBinaryPrecedence() const { return Precedence; }
- int getLine() const { return Line; }
};
/// FunctionAST - This class represents a function definition itself.
@@ -417,13 +270,6 @@
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";
- }
};
} // end anonymous namespace
@@ -492,12 +338,10 @@
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
- SourceLocation LitLoc = CurLoc;
-
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return llvm::make_unique<VariableExprAST>(LitLoc, IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
@@ -521,13 +365,11 @@
// Eat the ')'.
getNextToken();
- return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args));
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static std::unique_ptr<ExprAST> ParseIfExpr() {
- SourceLocation IfLoc = CurLoc;
-
getNextToken(); // eat the if.
// condition.
@@ -552,7 +394,7 @@
if (!Else)
return nullptr;
- return llvm::make_unique<IfExprAST>(IfLoc, std::move(Cond), std::move(Then),
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
}
@@ -707,7 +549,6 @@
// Okay, we know this is a binop.
int BinOp = CurTok;
- SourceLocation BinLoc = CurLoc;
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
@@ -725,8 +566,8 @@
}
// Merge LHS/RHS.
- LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS),
- std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
}
}
@@ -748,8 +589,6 @@
static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
- SourceLocation FnLoc = CurLoc;
-
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
unsigned BinaryPrecedence = 30;
@@ -805,7 +644,7 @@
if (Kind && ArgNames.size() != Kind)
return LogErrorP("Invalid number of operands for operator");
- return llvm::make_unique<PrototypeAST>(FnLoc, FnName, ArgNames, Kind != 0,
+ return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
BinaryPrecedence);
}
@@ -823,10 +662,9 @@
/// toplevelexpr ::= expression
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
- SourceLocation FnLoc = CurLoc;
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>(FnLoc, "__anon_expr",
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
@@ -840,51 +678,13 @@
}
//===----------------------------------------------------------------------===//
-// Debug Info Support
-//===----------------------------------------------------------------------===//
-
-static std::unique_ptr<DIBuilder> DBuilder;
-
-DIType *DebugInfo::getDoubleTy() {
- if (DblTy)
- return DblTy;
-
- DblTy = DBuilder->createBasicType("double", 64, 64, dwarf::DW_ATE_float);
- return DblTy;
-}
-
-void DebugInfo::emitLocation(ExprAST *AST) {
- if (!AST)
- return Builder.SetCurrentDebugLocation(DebugLoc());
- DIScope *Scope;
- if (LexicalBlocks.empty())
- Scope = TheCU;
- else
- Scope = LexicalBlocks.back();
- Builder.SetCurrentDebugLocation(
- DebugLoc::get(AST->getLine(), AST->getCol(), Scope));
-}
-
-static DISubroutineType *CreateFunctionType(unsigned NumArgs, DIFile *Unit) {
- SmallVector<Metadata *, 8> EltTys;
- DIType *DblTy = KSDbgInfo.getDoubleTy();
-
- // Add the result type.
- EltTys.push_back(DblTy);
-
- for (unsigned i = 0, e = NumArgs; i != e; ++i)
- EltTys.push_back(DblTy);
-
- return DBuilder->createSubroutineType(DBuilder->getOrCreateTypeArray(EltTys));
-}
-
-//===----------------------------------------------------------------------===//
// Code Generation
//===----------------------------------------------------------------------===//
+static LLVMContext TheContext;
+static IRBuilder<> Builder(TheContext);
static std::unique_ptr<Module> TheModule;
static std::map<std::string, AllocaInst *> NamedValues;
-static std::unique_ptr<KaleidoscopeJIT> TheJIT;
static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
Value *LogErrorV(const char *Str) {
@@ -917,7 +717,6 @@
}
Value *NumberExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
return ConstantFP::get(TheContext, APFloat(Val));
}
@@ -927,7 +726,6 @@
if (!V)
return LogErrorV("Unknown variable name");
- KSDbgInfo.emitLocation(this);
// Load the value.
return Builder.CreateLoad(V, Name.c_str());
}
@@ -941,13 +739,10 @@
if (!F)
return LogErrorV("Unknown unary operator");
- KSDbgInfo.emitLocation(this);
return Builder.CreateCall(F, OperandV, "unop");
}
Value *BinaryExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
-
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
@@ -1001,8 +796,6 @@
}
Value *CallExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
-
// Look up the name in the global module table.
Function *CalleeF = getFunction(Callee);
if (!CalleeF)
@@ -1023,8 +816,6 @@
}
Value *IfExprAST::codegen() {
- KSDbgInfo.emitLocation(this);
-
Value *CondV = Cond->codegen();
if (!CondV)
return nullptr;
@@ -1101,8 +892,6 @@
// Create an alloca for the variable in the entry block.
AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
- KSDbgInfo.emitLocation(this);
-
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->codegen();
if (!StartVal)
@@ -1213,8 +1002,6 @@
NamedValues[VarName] = Alloca;
}
- KSDbgInfo.emitLocation(this);
-
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->codegen();
if (!BodyVal)
@@ -1262,43 +1049,12 @@
BasicBlock *BB = BasicBlock::Create(TheContext, "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 = P.getLine();
- unsigned ScopeLine = LineNo;
- DISubprogram *SP = DBuilder->createFunction(
- FContext, P.getName(), StringRef(), Unit, LineNo,
- CreateFunctionType(TheFunction->arg_size(), Unit),
- false /* internal linkage */, true /* definition */, ScopeLine,
- DINode::FlagPrototyped, false);
- TheFunction->setSubprogram(SP);
-
- // 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);
-
// 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(TheFunction, Arg.getName());
- // Create a debug descriptor for the variable.
- DILocalVariable *D = DBuilder->createParameterVariable(
- SP, Arg.getName(), ++ArgIdx, Unit, LineNo, KSDbgInfo.getDoubleTy(),
- true);
-
- DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(),
- DebugLoc::get(LineNo, 0, SP),
- Builder.GetInsertBlock());
-
// Store the initial value into the alloca.
Builder.CreateStore(&Arg, Alloca);
@@ -1306,15 +1062,10 @@
NamedValues[Arg.getName()] = Alloca;
}
- KSDbgInfo.emitLocation(Body.get());
-
if (Value *RetVal = Body->codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
- // Pop off the lexical block for the function.
- KSDbgInfo.LexicalBlocks.pop_back();
-
// Validate the generated code, checking for consistency.
verifyFunction(*TheFunction);
@@ -1326,11 +1077,6 @@
if (P.isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
-
- // Pop off the lexical block for the function since we added it
- // unconditionally.
- KSDbgInfo.LexicalBlocks.pop_back();
-
return nullptr;
}
@@ -1338,16 +1084,17 @@
// Top-Level parsing and JIT Driver
//===----------------------------------------------------------------------===//
-static void InitializeModule() {
+static void InitializeModuleAndPassManager() {
// Open a new module.
TheModule = llvm::make_unique<Module>("my cool jit", TheContext);
- TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout());
}
static void HandleDefinition() {
if (auto FnAST = ParseDefinition()) {
- if (!FnAST->codegen())
- fprintf(stderr, "Error reading function definition:");
+ if (auto *FnIR = FnAST->codegen()) {
+ fprintf(stderr, "Read function definition:");
+ FnIR->dump();
+ }
} else {
// Skip token for error recovery.
getNextToken();
@@ -1356,10 +1103,11 @@
static void HandleExtern() {
if (auto ProtoAST = ParseExtern()) {
- if (!ProtoAST->codegen())
- fprintf(stderr, "Error reading extern");
- else
+ if (auto *FnIR = ProtoAST->codegen()) {
+ fprintf(stderr, "Read extern: ");
+ FnIR->dump();
FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
+ }
} else {
// Skip token for error recovery.
getNextToken();
@@ -1369,9 +1117,7 @@
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
- if (!FnAST->codegen()) {
- fprintf(stderr, "Error generating code for top level expr");
- }
+ FnAST->codegen();
} else {
// Skip token for error recovery.
getNextToken();
@@ -1421,50 +1167,74 @@
//===----------------------------------------------------------------------===//
int main() {
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
- InitializeNativeTargetAsmParser();
-
// Install standard binary operators.
// 1 is lowest precedence.
- BinopPrecedence['='] = 2;
BinopPrecedence['<'] = 10;
BinopPrecedence['+'] = 20;
BinopPrecedence['-'] = 20;
BinopPrecedence['*'] = 40; // highest.
// Prime the first token.
+ fprintf(stderr, "ready> ");
getNextToken();
- TheJIT = llvm::make_unique<KaleidoscopeJIT>();
-
- InitializeModule();
-
- // Add the current debug info version into the module.
- TheModule->addModuleFlag(Module::Warning, "Debug Info Version",
- DEBUG_METADATA_VERSION);
-
- // Darwin only supports dwarf2.
- if (Triple(sys::getProcessTriple()).isOSDarwin())
- TheModule->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 2);
-
- // Construct the DIBuilder, we do this here because we need the module.
- 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
- // but we'd like actual source locations.
- KSDbgInfo.TheCU = DBuilder->createCompileUnit(
- dwarf::DW_LANG_C, "fib.ks", ".", "Kaleidoscope Compiler", false, "", 0);
+ InitializeModuleAndPassManager();
// Run the main "interpreter loop" now.
MainLoop();
- // Finalize the debug info.
- DBuilder->finalize();
+ // Initialize the target registry etc.
+ InitializeAllTargetInfos();
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmParsers();
+ InitializeAllAsmPrinters();
- // Print out all of the generated code.
- TheModule->dump();
+ auto TargetTriple = sys::getDefaultTargetTriple();
+ TheModule->setTargetTriple(TargetTriple);
+
+ std::string Error;
+ auto Target = TargetRegistry::lookupTarget(TargetTriple, Error);
+
+ // Print an error and exit if we couldn't find the requested target.
+ // This generally occurs if we've forgotten to initialise the
+ // TargetRegistry or we have a bogus target triple.
+ if (!Target) {
+ errs() << Error;
+ return 1;
+ }
+
+ auto CPU = "generic";
+ auto Features = "";
+
+ TargetOptions opt;
+ auto RM = Optional<Reloc::Model>();
+ auto TheTargetMachine =
+ Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
+
+ TheModule->setDataLayout(TheTargetMachine->createDataLayout());
+
+ auto Filename = "output.o";
+ std::error_code EC;
+ raw_fd_ostream dest(Filename, EC, sys::fs::F_None);
+
+ if (EC) {
+ errs() << "Could not open file: " << EC.message();
+ return 1;
+ }
+
+ legacy::PassManager pass;
+ auto FileType = TargetMachine::CGFT_ObjectFile;
+
+ if (TheTargetMachine->addPassesToEmitFile(pass, dest, FileType)) {
+ errs() << "TheTargetMachine can't emit a file of this type";
+ return 1;
+ }
+
+ pass.run(*TheModule);
+ dest.flush();
+
+ outs() << "Wrote " << Filename << "\n";
return 0;
}