diff options
Diffstat (limited to 'examples/Kaleidoscope/Chapter8/toy.cpp')
-rw-r--r-- | examples/Kaleidoscope/Chapter8/toy.cpp | 416 |
1 files changed, 93 insertions, 323 deletions
diff --git a/examples/Kaleidoscope/Chapter8/toy.cpp b/examples/Kaleidoscope/Chapter8/toy.cpp index 99ff52bc1b4..f880bb8ea0f 100644 --- a/examples/Kaleidoscope/Chapter8/toy.cpp +++ b/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 @@ enum Token { 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 @@ static int gettok() { // 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 @@ static int gettok() { std::string NumStr; do { NumStr += LastChar; - LastChar = advance(); + LastChar = getchar(); } while (isdigit(LastChar) || LastChar == '.'); NumVal = strtod(NumStr.c_str(), nullptr); @@ -187,7 +112,7 @@ static int gettok() { 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 @@ static int gettok() { // Otherwise, just return the character as its ascii value. int ThisChar = LastChar; - LastChar = advance(); + LastChar = getchar(); return ThisChar; } @@ -208,25 +133,11 @@ static int gettok() { // 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 @@ class NumberExprAST : public ExprAST { 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 @@ class VariableExprAST : public ExprAST { 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 @@ 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; - } }; /// BinaryExprAST - Expression class for a binary operator. @@ -280,17 +176,10 @@ class BinaryExprAST : public ExprAST { 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 @@ class CallExprAST : public ExprAST { 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 @@ class IfExprAST : public ExprAST { 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 @@ public: : 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 @@ public: 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 @@ class PrototypeAST { 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 @@ public: } unsigned getBinaryPrecedence() const { return Precedence; } - int getLine() const { return Line; } }; /// FunctionAST - This class represents a function definition itself. @@ -417,13 +270,6 @@ public: 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> ParseParenExpr() { 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 @@ static std::unique_ptr<ExprAST> ParseIdentifierExpr() { // 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 @@ static std::unique_ptr<ExprAST> ParseIfExpr() { 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 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, // 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 @@ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, } // 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<ExprAST> ParseExpression() { 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 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() { 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 @@ static std::unique_ptr<FunctionAST> ParseDefinition() { /// 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 @@ static std::unique_ptr<PrototypeAST> ParseExtern() { } //===----------------------------------------------------------------------===// -// 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 @@ static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction, } Value *NumberExprAST::codegen() { - KSDbgInfo.emitLocation(this); return ConstantFP::get(TheContext, APFloat(Val)); } @@ -927,7 +726,6 @@ Value *VariableExprAST::codegen() { if (!V) return LogErrorV("Unknown variable name"); - KSDbgInfo.emitLocation(this); // Load the value. return Builder.CreateLoad(V, Name.c_str()); } @@ -941,13 +739,10 @@ Value *UnaryExprAST::codegen() { 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 *BinaryExprAST::codegen() { } 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 *CallExprAST::codegen() { } Value *IfExprAST::codegen() { - KSDbgInfo.emitLocation(this); - Value *CondV = Cond->codegen(); if (!CondV) return nullptr; @@ -1101,8 +892,6 @@ Value *ForExprAST::codegen() { // 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 @@ Value *VarExprAST::codegen() { 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 @@ Function *FunctionAST::codegen() { 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 @@ Function *FunctionAST::codegen() { 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 @@ Function *FunctionAST::codegen() { 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 @@ Function *FunctionAST::codegen() { // 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 HandleDefinition() { 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 HandleExtern() { 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 @@ extern "C" double printd(double X) { //===----------------------------------------------------------------------===// 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>(); + InitializeModuleAndPassManager(); - InitializeModule(); + // Run the main "interpreter loop" now. + MainLoop(); - // Add the current debug info version into the module. - TheModule->addModuleFlag(Module::Warning, "Debug Info Version", - DEBUG_METADATA_VERSION); + // Initialize the target registry etc. + InitializeAllTargetInfos(); + InitializeAllTargets(); + InitializeAllTargetMCs(); + InitializeAllAsmParsers(); + InitializeAllAsmPrinters(); + + 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; + } - // Darwin only supports dwarf2. - if (Triple(sys::getProcessTriple()).isOSDarwin()) - TheModule->addModuleFlag(llvm::Module::Warning, "Dwarf Version", 2); + auto CPU = "generic"; + auto Features = ""; - // Construct the DIBuilder, we do this here because we need the module. - DBuilder = llvm::make_unique<DIBuilder>(*TheModule); + TargetOptions opt; + auto RM = Optional<Reloc::Model>(); + auto TheTargetMachine = + Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM); - // 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); + TheModule->setDataLayout(TheTargetMachine->createDataLayout()); - // Run the main "interpreter loop" now. - MainLoop(); + 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; + } - // Finalize the debug info. - DBuilder->finalize(); + pass.run(*TheModule); + dest.flush(); - // Print out all of the generated code. - TheModule->dump(); + outs() << "Wrote " << Filename << "\n"; return 0; } |