[cfe-commits] r50848 - in /cfe/trunk: Driver/Makefile Driver/clang.cpp include/clang/CodeGen/ModuleBuilder.h lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGStmt.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/ModuleBuilder.cpp

Sanjiv Gupta sanjiv.gupta at microchip.com
Thu May 8 01:54:20 PDT 2008


Author: sgupta
Date: Thu May  8 03:54:20 2008
New Revision: 50848

URL: http://llvm.org/viewvc/llvm-project?rev=50848&view=rev
Log:
Added -g command line options to clang for generating source level debug information. This patch currently enables generation of line number debug information (stoppoints) and region begin/end debug information. The new files CGDebugInfo.h and CGDebugInfo.cpp implements the debug info manager class CGDebugInfo.

Added:
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.h
Modified:
    cfe/trunk/Driver/Makefile
    cfe/trunk/Driver/clang.cpp
    cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/ModuleBuilder.cpp

Modified: cfe/trunk/Driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/Makefile?rev=50848&r1=50847&r2=50848&view=diff

==============================================================================
--- cfe/trunk/Driver/Makefile (original)
+++ cfe/trunk/Driver/Makefile Thu May  8 03:54:20 2008
@@ -6,7 +6,7 @@
 USEDLIBS = clangCodeGen.a clangAnalysis.a clangRewrite.a clangSEMA.a \
            clangAST.a clangParse.a clangLex.a clangBasic.a \
            LLVMCore.a LLVMSupport.a LLVMSystem.a \
-           LLVMBitWriter.a LLVMBitReader.a LLVMTarget.a 
+           LLVMBitWriter.a LLVMBitReader.a LLVMCodeGen.a LLVMTarget.a 
 	
 	
 

Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=50848&r1=50847&r2=50848&view=diff

==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Thu May  8 03:54:20 2008
@@ -149,6 +149,13 @@
  llvm::cl::desc("Specify output file (for --serialize, this is a directory)"));
 
 //===----------------------------------------------------------------------===//
+// Code Generator Options
+//===----------------------------------------------------------------------===//
+static llvm::cl::opt<bool>
+GenerateDebugInfo("g",
+                  llvm::cl::desc("Generate source level debug information"));
+
+//===----------------------------------------------------------------------===//
 // Diagnostic Options
 //===----------------------------------------------------------------------===//
 
@@ -1161,7 +1168,7 @@
     case EmitLLVM:
     case EmitBC:
       DestModule = new llvm::Module(InFile);
-      return CreateLLVMCodeGen(Diag, LangOpts, DestModule);
+      return CreateLLVMCodeGen(Diag, LangOpts, DestModule, GenerateDebugInfo);
 
     case SerializeAST:
       // FIXME: Allow user to tailor where the file is written.

Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=50848&r1=50847&r2=50848&view=diff

==============================================================================
--- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
+++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Thu May  8 03:54:20 2008
@@ -24,7 +24,8 @@
   class ASTConsumer;
   
   ASTConsumer *CreateLLVMCodeGen(Diagnostic &Diags, const LangOptions &Features,
-                                 llvm::Module *&DestModule);
+                                 llvm::Module *&DestModule,
+                                 bool GenerateDebugInfo);
 }
 
 #endif

Added: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=50848&view=auto

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (added)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu May  8 03:54:20 2008
@@ -0,0 +1,171 @@
+//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This coordinates the debug information generation while generating code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGDebugInfo.h"
+#include "CodeGenModule.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/AST/ASTContext.h"
+using namespace clang;
+using namespace clang::CodeGen;
+
+CGDebugInfo::CGDebugInfo(CodeGenModule *m)
+: M(m)
+, CurLoc()
+, PrevLoc()
+, CompileUnitCache()
+, StopPointFn(NULL)
+, RegionStartFn(NULL)
+, RegionEndFn(NULL)
+, RegionStack()
+{
+  SR = new llvm::DISerializer();
+  SR->setModule (&M->getModule());
+}
+
+CGDebugInfo::~CGDebugInfo()
+{
+  delete SR;
+}
+
+
+/// getCastValueFor - Return a llvm representation for a given debug information
+/// descriptor cast to an empty struct pointer.
+llvm::Value *CGDebugInfo::getCastValueFor(llvm::DebugInfoDesc *DD) {
+  return llvm::ConstantExpr::getBitCast(SR->Serialize(DD), 
+					SR->getEmptyStructPtrType());
+}
+
+/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
+/// one if necessary.
+llvm::CompileUnitDesc 
+*CGDebugInfo::getOrCreateCompileUnit(const SourceLocation Loc) {
+
+  // See if this compile unit has been used before.
+  llvm::CompileUnitDesc *&Slot = CompileUnitCache[Loc.getFileID()];
+  if (Slot) return Slot;
+
+  // Create new compile unit.
+  // FIXME: Where to free these?
+  // One way is to iterate over the CompileUnitCache in ~CGDebugInfo.
+  llvm::CompileUnitDesc *Unit = new llvm::CompileUnitDesc();
+
+  // Make sure we have an anchor.
+  if (!CompileUnitAnchor) {
+    CompileUnitAnchor = new llvm::AnchorDesc(Unit);
+  }
+
+  // Get source file information.
+  SourceManager &SM = M->getContext().getSourceManager();
+  const FileEntry *FE = SM.getFileEntryForLoc(Loc);
+  const char *FileName = FE->getName();
+  const char *DirName = FE->getDir()->getName();
+
+  Unit->setAnchor(CompileUnitAnchor);
+  Unit->setFileName(FileName);
+  Unit->setDirectory(DirName);
+
+  // Set up producer name.
+  // FIXME: Do not know how to get clang version yet.
+  Unit->setProducer("clang");
+
+  // Set up Language number.
+  // FIXME: Handle other languages as well.
+  Unit->setLanguage(llvm::dwarf::DW_LANG_C89);
+
+  // Update cache.
+  Slot = Unit;
+
+  return Unit;
+}
+
+
+void 
+CGDebugInfo::EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder) {
+
+  // Don't bother if things are the same as last time.
+  SourceManager &SM = M->getContext().getSourceManager();
+  if (CurLoc == PrevLoc 
+       || (SM.getLineNumber(CurLoc) == SM.getLineNumber(PrevLoc)
+           && SM.isFromSameFile(CurLoc, PrevLoc)))
+    return;
+  if (CurLoc.isInvalid()) return;
+
+  // Update last state.
+  PrevLoc = CurLoc;
+
+  // Get the appropriate compile unit.
+  llvm::CompileUnitDesc *Unit = getOrCreateCompileUnit(CurLoc);
+
+  // Lazily construct llvm.dbg.stoppoint function.
+  if (!StopPointFn)
+    StopPointFn = llvm::Intrinsic::getDeclaration(&M->getModule(), 
+					llvm::Intrinsic::dbg_stoppoint);
+
+  uint64_t CurLineNo = SM.getLogicalLineNumber(CurLoc);
+  uint64_t ColumnNo = SM.getLogicalColumnNumber(CurLoc);
+
+  // Invoke llvm.dbg.stoppoint
+  Builder.CreateCall3(StopPointFn, 
+		       llvm::ConstantInt::get(llvm::Type::Int32Ty, CurLineNo),
+		       llvm::ConstantInt::get(llvm::Type::Int32Ty, ColumnNo),
+		       getCastValueFor(Unit), "");
+}
+
+/// EmitRegionStart- Constructs the debug code for entering a declarative
+/// region - "llvm.dbg.region.start.".
+void CGDebugInfo::EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder) 
+{
+  llvm::BlockDesc *Block = new llvm::BlockDesc();
+  if (RegionStack.size() > 0)
+    Block->setContext(RegionStack.back());
+  RegionStack.push_back(Block);
+
+  // Lazily construct llvm.dbg.region.start function.
+  if (!RegionStartFn)
+    RegionStartFn = llvm::Intrinsic::getDeclaration(&M->getModule(), 
+				llvm::Intrinsic::dbg_region_start);
+
+  // Call llvm.dbg.func.start.
+  Builder.CreateCall(RegionStartFn, getCastValueFor(Block), "");
+}
+
+/// EmitRegionEnd - Constructs the debug code for exiting a declarative
+/// region - "llvm.dbg.region.end."
+void CGDebugInfo::EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder) 
+{
+  // Lazily construct llvm.dbg.region.end function.
+  if (!RegionEndFn)
+    RegionEndFn =llvm::Intrinsic::getDeclaration(&M->getModule(), 
+				llvm::Intrinsic::dbg_region_end);
+
+  // Provide an region stop point.
+  EmitStopPoint(Fn, Builder);
+  
+  // Call llvm.dbg.func.end.
+  Builder.CreateCall(RegionEndFn, getCastValueFor(RegionStack.back()), "");
+  RegionStack.pop_back();
+  // FIXME: Free here the memory created for BlockDesc in RegionStart?
+}
+

Added: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=50848&view=auto

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (added)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Thu May  8 03:54:20 2008
@@ -0,0 +1,84 @@
+//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the source level debug info generator for llvm translation. 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGDEBUGINFO_H
+#define CLANG_CODEGEN_CGDEBUGINFO_H
+
+#include "clang/Basic/SourceLocation.h"
+#include <map>
+#include <vector>
+
+
+namespace llvm {
+  class Function;
+  class IRBuilder;
+  class DISerializer;
+  class CompileUnitDesc;
+  class BasicBlock;
+  class AnchorDesc;
+  class DebugInfoDesc;
+  class Value;
+}
+
+namespace clang {
+namespace CodeGen {
+  class CodeGenModule;
+
+/// DebugInfo - This class gathers all debug information during compilation and
+/// is responsible for emitting to llvm globals or pass directly to the backend.
+class CGDebugInfo {
+private:
+  CodeGenModule *M;
+  llvm::DISerializer *SR;
+  SourceLocation CurLoc;
+  SourceLocation PrevLoc;
+
+  /// CompileUnitCache - Cache of previously constructed CompileUnits.
+  std::map<unsigned, llvm::CompileUnitDesc *> CompileUnitCache;
+  
+  llvm::Function *StopPointFn;
+  llvm::AnchorDesc *CompileUnitAnchor;
+  llvm::Function *RegionStartFn;
+  llvm::Function *RegionEndFn;
+  std::vector<llvm::DebugInfoDesc *> RegionStack;  
+
+public:
+  CGDebugInfo(CodeGenModule *m);
+  ~CGDebugInfo();
+
+  void setLocation(SourceLocation loc) { CurLoc = loc; };
+
+  /// EmitStopPoint - Emit a call to llvm.dbg.stoppoint to indicate a change of
+  /// source line.
+  void EmitStopPoint(llvm::Function *Fn, llvm::IRBuilder &Builder);
+  
+  /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start
+  /// of a new block.  
+  void EmitRegionStart(llvm::Function *Fn, llvm::IRBuilder &Builder);
+  
+  /// EmitRegionEnd - Emit call to llvm.dbg.region.end to indicate end of a 
+  /// block.
+  void EmitRegionEnd(llvm::Function *Fn, llvm::IRBuilder &Builder);
+ 
+  /// getOrCreateCompileUnit - Get the compile unit from the cache or create a
+  /// new one if necessary.
+  llvm::CompileUnitDesc *getOrCreateCompileUnit(SourceLocation loc);
+
+  /// getCastValueFor - Return a llvm representation for a given debug
+  /// information descriptor cast to an empty struct pointer.
+  llvm::Value *getCastValueFor(llvm::DebugInfoDesc *DD);
+};
+} // namespace CodeGen
+} // namespace clang
+
+#endif

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=50848&r1=50847&r2=50848&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu May  8 03:54:20 2008
@@ -11,6 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CGDebugInfo.h"
+#include "CodeGenModule.h"
 #include "CodeGenFunction.h"
 #include "clang/AST/AST.h"
 #include "clang/Basic/TargetInfo.h"
@@ -29,6 +31,18 @@
 void CodeGenFunction::EmitStmt(const Stmt *S) {
   assert(S && "Null statement?");
   
+  // Generate stoppoints if we are emitting debug info.
+  // Beginning of a Compound Statement (e.g. an opening '{') does not produce 
+  // executable code. So do not generate a stoppoint for that.
+  CGDebugInfo *DI = CGM.getDebugInfo();
+  if (DI && S->getStmtClass() != Stmt::CompoundStmtClass) {
+    if (S->getLocStart().isValid()) {
+        DI->setLocation(S->getLocStart());
+    }
+
+    DI->EmitStopPoint(CurFn, Builder);
+  }
+
   switch (S->getStmtClass()) {
   default:
     // Must be an expression in a stmt context.  Emit the value (to get
@@ -74,11 +88,25 @@
   // FIXME: handle vla's etc.
   if (S.body_empty() || !isa<Expr>(S.body_back())) GetLast = false;
   
+  CGDebugInfo *DI = CGM.getDebugInfo();
+  if (DI) {
+    if (S.getLBracLoc().isValid()) {
+      DI->setLocation(S.getLBracLoc());
+    }
+    DI->EmitRegionStart(CurFn, Builder);
+  }
+
   for (CompoundStmt::const_body_iterator I = S.body_begin(),
        E = S.body_end()-GetLast; I != E; ++I)
     EmitStmt(*I);
-  
-  
+
+  if (DI) {
+    if (S.getRBracLoc().isValid()) {
+      DI->setLocation(S.getRBracLoc());
+    }
+    DI->EmitRegionEnd(CurFn, Builder);
+  }
+
   if (!GetLast)
     return RValue::get(0);
   

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=50848&r1=50847&r2=50848&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu May  8 03:54:20 2008
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CGDebugInfo.h"
 #include "CodeGenModule.h"
 #include "CodeGenFunction.h"
 #include "clang/AST/ASTContext.h"
@@ -32,13 +33,19 @@
 
 CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
                              llvm::Module &M, const llvm::TargetData &TD,
-                             Diagnostic &diags)
+                             Diagnostic &diags, bool GenerateDebugInfo)
   : Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags),
     Types(C, M, TD), MemCpyFn(0), MemSetFn(0), CFConstantStringClassRef(0) {
   //TODO: Make this selectable at runtime
   Runtime = CreateObjCRuntime(M,
       getTypes().ConvertType(getContext().IntTy),
       getTypes().ConvertType(getContext().LongTy));
+
+  // If debug info generation is enabled, create the CGDebugInfo object.
+  if (GenerateDebugInfo)
+    DebugInfo = new CGDebugInfo(this);
+  else
+    DebugInfo = NULL;
 }
 
 CodeGenModule::~CodeGenModule() {
@@ -49,7 +56,7 @@
   EmitGlobalCtors();
   EmitAnnotations();
   delete Runtime;
-  
+  delete DebugInfo;
   // Run the verifier to check that the generated code is consistent.
   assert(!verifyModule(TheModule));
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=50848&r1=50847&r2=50848&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu May  8 03:54:20 2008
@@ -43,7 +43,8 @@
 namespace CodeGen {
 
   class CodeGenFunction;
-
+  class CGDebugInfo;
+  
 /// CodeGenModule - This class organizes the cross-module state that is used
 /// while generating LLVM code.
 class CodeGenModule {
@@ -54,6 +55,7 @@
   Diagnostic &Diags;
   CodeGenTypes Types;
   CGObjCRuntime *Runtime;
+  CGDebugInfo *DebugInfo;
 
   llvm::Function *MemCpyFn;
   llvm::Function *MemSetFn;
@@ -70,10 +72,12 @@
   std::vector<llvm::Function *> BuiltinFunctions;
 public:
   CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, 
-                const llvm::TargetData &TD, Diagnostic &Diags);
+                const llvm::TargetData &TD, Diagnostic &Diags,
+                bool GenerateDebugInfo);
   ~CodeGenModule();
   
   CGObjCRuntime *getObjCRuntime() { return Runtime; }
+  CGDebugInfo *getDebugInfo() { return DebugInfo; }
   ASTContext &getContext() const { return Context; }
   const LangOptions &getLangOptions() const { return Features; }
   llvm::Module &getModule() const { return TheModule; }

Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=50848&r1=50847&r2=50848&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Thu May  8 03:54:20 2008
@@ -34,13 +34,15 @@
     const llvm::TargetData *TD;
     ASTContext *Ctx;
     const LangOptions &Features;
+    bool GenerateDebugInfo;
   protected:
     llvm::Module *&M;
     CodeGen::CodeGenModule *Builder;
   public:
     CodeGenerator(Diagnostic &diags, const LangOptions &LO,
-                  llvm::Module *&DestModule)
-    : Diags(diags), Features(LO), M(DestModule) {}
+                  llvm::Module *&DestModule, bool DebugInfoFlag)
+    : Diags(diags), Features(LO), GenerateDebugInfo(DebugInfoFlag),
+    M(DestModule) {}
     
     ~CodeGenerator() {
       delete Builder;
@@ -52,7 +54,8 @@
       M->setTargetTriple(Ctx->Target.getTargetTriple());
       M->setDataLayout(Ctx->Target.getTargetDescription());
       TD = new llvm::TargetData(Ctx->Target.getTargetDescription());
-      Builder = new CodeGen::CodeGenModule(Context, Features, *M, *TD, Diags);
+      Builder = new CodeGen::CodeGenModule(Context, Features, *M, *TD, Diags,
+                                           GenerateDebugInfo);
     }
     
     virtual void HandleTopLevelDecl(Decl *D) {
@@ -103,7 +106,8 @@
 
 ASTConsumer *clang::CreateLLVMCodeGen(Diagnostic &Diags, 
                                       const LangOptions &Features,
-                                      llvm::Module *&DestModule) {
-  return new CodeGenerator(Diags, Features, DestModule);
+                                      llvm::Module *&DestModule,
+                                      bool GenerateDebugInfo) {
+  return new CodeGenerator(Diags, Features, DestModule, GenerateDebugInfo);
 }
 





More information about the cfe-commits mailing list