X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2Ftutorial%2FLangImpl8.rst;h=3b0f443f08d5439f11a6c9f0c8bfae416b54c459;hb=12d60e9e7c149a7d333e277dfbe25a720c88c585;hp=89344cc82a2d3cdb7296d5d7822af4274e0fdea8;hpb=772e538fb8501640bc2e7aefcec53991ef9ab4c5;p=oota-llvm.git diff --git a/docs/tutorial/LangImpl8.rst b/docs/tutorial/LangImpl8.rst index 89344cc82a2..3b0f443f08d 100644 --- a/docs/tutorial/LangImpl8.rst +++ b/docs/tutorial/LangImpl8.rst @@ -1,6 +1,6 @@ -======================================================= -Kaleidoscope: Extending the Language: Debug Information -======================================================= +====================================== +Kaleidoscope: Adding Debug Information +====================================== .. contents:: :local: @@ -75,8 +75,8 @@ statement be our "main": .. code-block:: udiff - - PrototypeAST *Proto = new PrototypeAST("", std::vector()); - + PrototypeAST *Proto = new PrototypeAST("main", std::vector()); + - auto Proto = llvm::make_unique("", std::vector()); + + auto Proto = llvm::make_unique("main", std::vector()); just with the simple change of giving it a name. @@ -108,19 +108,19 @@ code is that the llvm IR goes to standard error: @@ -1108,17 +1108,8 @@ static void HandleExtern() { static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - - if (Function *LF = F->Codegen()) { + if (auto FnAST = ParseTopLevelExpr()) { + - if (auto *FnIR = FnAST->codegen()) { - // We're just doing this to make sure it executes. - TheExecutionEngine->finalizeObject(); - // JIT the function, returning a function pointer. - - void *FPtr = TheExecutionEngine->getPointerToFunction(LF); + - void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR); - - // Cast it to the right type (takes no arguments, returns a double) so we - // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)FPtr; - // Ignore the return value for this. - (void)FP; - + if (!F->Codegen()) { + + if (!F->codegen()) { + fprintf(stderr, "Error generating code for top level expr"); } } else { @@ -165,13 +165,13 @@ DWARF Emission Setup ==================== Similar to the ``IRBuilder`` class we have a -```DIBuilder`` `_ class +`DIBuilder `_ class that helps in constructing debug metadata for an llvm IR file. It corresponds 1:1 similarly to ``IRBuilder`` and llvm IR, but with nicer names. Using it does require that you be more familiar with DWARF terminology than you needed to be with ``IRBuilder`` and ``Instruction`` names, but if you read through the general documentation on the -```Metadata Format`` `_ it +`Metadata Format `_ it should be a little more clear. We'll be using this class to construct all of our IR level descriptions. Construction for it takes a module so we need to construct it shortly after we construct our module. We've left it @@ -187,13 +187,13 @@ expressions: static DIBuilder *DBuilder; struct DebugInfo { - DICompileUnit TheCU; - DIType DblTy; + DICompileUnit *TheCU; + DIType *DblTy; - DIType getDoubleTy(); + DIType *getDoubleTy(); } KSDbgInfo; - DIType DebugInfo::getDoubleTy() { + DIType *DebugInfo::getDoubleTy() { if (DblTy.isValid()) return DblTy; @@ -237,7 +237,7 @@ Functions ========= Now that we have our ``Compile Unit`` and our source locations, we can add -function definitions to the debug info. So in ``PrototypeAST::Codegen`` we +function definitions to the debug info. So in ``PrototypeAST::codegen()`` we add a few lines of code to describe a context for our subprogram, in this case the "File", and the actual definition of the function itself. @@ -245,26 +245,27 @@ So the context: .. code-block:: c++ - DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(), - KSDbgInfo.TheCU.getDirectory()); + DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(), + KSDbgInfo.TheCU.getDirectory()); -giving us a DIFile and asking the ``Compile Unit`` we created above for the +giving us an DIFile and asking the ``Compile Unit`` we created above for the directory and filename where we are currently. Then, for now, we use some source locations of 0 (since our AST doesn't currently have source location information) and construct our function definition: .. code-block:: c++ - DIDescriptor FContext(Unit); + DIScope *FContext = Unit; unsigned LineNo = 0; unsigned ScopeLine = 0; - DISubprogram SP = DBuilder->createFunction( + DISubprogram *SP = DBuilder->createFunction( FContext, Name, StringRef(), Unit, LineNo, CreateFunctionType(Args.size(), Unit), false /* internal linkage */, - true /* definition */, ScopeLine, DIDescriptor::FlagPrototyped, false, F); + true /* definition */, ScopeLine, DINode::FlagPrototyped, false); + F->setSubprogram(SP); -and we now have a DISubprogram that contains a reference to all of our metadata -for the function. +and we now have an DISubprogram that contains a reference to all of our +metadata for the function. Source Locations ================ @@ -307,10 +308,12 @@ and then we have added to all of our AST classes a source location: 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; } - ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {} - virtual std::ostream &dump(std::ostream &out, int ind) { + virtual raw_ostream &dump(raw_ostream &out, int ind) { return out << ':' << getLine() << ':' << getCol() << '\n'; } @@ -318,7 +321,8 @@ that we pass down through when we create a new expression: .. code-block:: c++ - LHS = new BinaryExprAST(BinLoc, BinOp, LHS, RHS); + LHS = llvm::make_unique(BinLoc, BinOp, std::move(LHS), + std::move(RHS)); giving us locations for each of our expressions and variables. @@ -332,11 +336,11 @@ by constructing another small function: void DebugInfo::emitLocation(ExprAST *AST) { DIScope *Scope; if (LexicalBlocks.empty()) - Scope = &TheCU; + Scope = TheCU; else Scope = LexicalBlocks.back(); Builder.SetCurrentDebugLocation( - DebugLoc::get(AST->getLine(), AST->getCol(), DIScope(*Scope))); + DebugLoc::get(AST->getLine(), AST->getCol(), Scope)); } that both tells the main ``IRBuilder`` where we are, but also what scope @@ -348,10 +352,10 @@ of scopes: .. code-block:: c++ std::vector LexicalBlocks; - std::map FnScopeMap; + std::map FnScopeMap; -and keep a map of each function to the scope that it represents (a DISubprogram -is also a DIScope). +and keep a map of each function to the scope that it represents (an +DISubprogram is also an DIScope). Then we make sure to: @@ -393,15 +397,14 @@ argument allocas in ``PrototypeAST::CreateArgumentAllocas``. .. code-block:: c++ DIScope *Scope = KSDbgInfo.LexicalBlocks.back(); - DIFile Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(), - KSDbgInfo.TheCU.getDirectory()); - DIVariable D = DBuilder->createLocalVariable(dwarf::DW_TAG_arg_variable, - *Scope, Args[Idx], Unit, Line, - KSDbgInfo.getDoubleTy(), Idx); + DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(), + KSDbgInfo.TheCU.getDirectory()); + DILocalVariable D = DBuilder->createParameterVariable( + Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true); - Instruction *Call = DBuilder->insertDeclare( - Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock()); - Call->setDebugLoc(DebugLoc::get(Line, 0, *Scope)); + DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(), + DebugLoc::get(Line, 0, Scope), + Builder.GetInsertBlock()); Here we're doing a few things. First, we're grabbing our current scope for the variable so we can say what range of code our variable is valid @@ -409,7 +412,7 @@ through. Second, we're creating the variable, giving it the scope, the name, source location, type, and since it's an argument, the argument index. Third, we create an ``lvm.dbg.declare`` call to indicate at the IR level that we've got a variable in an alloca (and it gives a starting -location for the variable). Lastly, we set a source location for the +location for the variable), and setting a source location for the beginning of the scope on the declare. One interesting thing to note at this point is that various debuggers have @@ -446,7 +449,7 @@ debug information. To build this example, use: .. code-block:: bash # Compile - clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core jit native` -O3 -o toy + clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core mcjit native` -O3 -o toy # Run ./toy