]> granicus.if.org Git - clang/commitdiff
Introduce -flimit-debug-info.
authorDevang Patel <dpatel@apple.com>
Thu, 30 Sep 2010 19:05:55 +0000 (19:05 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 30 Sep 2010 19:05:55 +0000 (19:05 +0000)
In this experimental mode try avoiding debug info emission for classes as much as possible. The goal is to reduce size of produced debuginfo without reducing quality of debug info in general. This is a work in progress.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115188 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/Driver/Options.td
include/clang/Frontend/CodeGenOptions.h
lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGDebugInfo.h
lib/CodeGen/CGExprCXX.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp

index 6de5bf14fd45a9cf7be06d962ebfed1844804350..363ea7bb542b69bfc62115bbc5e709ba2c9553e7 100644 (file)
@@ -131,6 +131,8 @@ def dwarf_debug_flags : Separate<"-dwarf-debug-flags">,
 def g : Flag<"-g">, HelpText<"Generate source level debug information">;
 def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
     HelpText<"Generate runtime checks for undefined behavior.">;
+def flimit_debug_info : Flag<"-flimit-debug-info">,
+  HelpText<"Limit debug information produced to reduce size of debug binary">;
 def fno_common : Flag<"-fno-common">,
   HelpText<"Compile common globals like normal definitions">;
 def no_implicit_float : Flag<"-no-implicit-float">,
index 95b84d3f708f42666fde722a916efc4f3014427c..fed03f755a693f61d75a22631b202b432805bdfb 100644 (file)
@@ -288,6 +288,8 @@ def finstrument_functions : Flag<"-finstrument-functions">, Group<f_Group>;
 def fkeep_inline_functions : Flag<"-fkeep-inline-functions">, Group<clang_ignored_f_Group>;
 def flat__namespace : Flag<"-flat_namespace">;
 def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group<f_Group>;
+def flimit_debug_info : Flag<"-flimit-debug-info">, Group<f_Group>, 
+  HelpText<"Limit debug information produced to reduce size of debug binary">;
 def flimited_precision_EQ : Joined<"-flimited-precision=">, Group<f_Group>;
 def flto : Flag<"-flto">, Group<f_Group>;
 def fmacro_backtrace_limit_EQ : Joined<"-fmacro-backtrace-limit=">, 
index b3f57094b4afba1fb42871236ae17f517f0a9f24..ffaaedc30e645d444a73da3cfb8260d9cbb4bb65 100644 (file)
@@ -40,6 +40,7 @@ public:
                                   /// aliases to base ctors when possible.
   unsigned DataSections      : 1; /// Set when -fdata-sections is enabled
   unsigned DebugInfo         : 1; /// Should generate debug info (-g).
+  unsigned LimitDebugInfo    : 1; /// Limit generated debug info to reduce size.
   unsigned DisableFPElim     : 1; /// Set when -fomit-frame-pointer is enabled.
   unsigned DisableLLVMOpts   : 1; /// Don't run any optimizations, for use in
                                   /// getting .bc files that correspond to the
@@ -109,6 +110,7 @@ public:
     CXXCtorDtorAliases = 0;
     DataSections = 0;
     DebugInfo = 0;
+    LimitDebugInfo = 0;
     DisableFPElim = 0;
     DisableLLVMOpts = 0;
     DisableRedZone = 0;
index 45a887b1bbb80770c35908ef288b4b1b76521c95..29a4377dd1344669e99d6850a9c1f2be6bbf8ed3 100644 (file)
@@ -413,12 +413,44 @@ llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
                                Ty->getPointeeType(), Unit);
 }
 
+/// CreatePointeeType - Create PointTee type. If Pointee is a record
+/// then emit record's fwd if debug info size reduction is enabled.
+llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy,
+                                            llvm::DIFile Unit) {
+  if (!CGM.getCodeGenOpts().LimitDebugInfo)
+    return getOrCreateType(PointeeTy, Unit);
+  
+  if (const RecordType *RTy = dyn_cast<RecordType>(PointeeTy)) {
+    RecordDecl *RD = RTy->getDecl();
+    unsigned RTag;
+    if (RD->isStruct())
+      RTag = llvm::dwarf::DW_TAG_structure_type;
+    else if (RD->isUnion())
+      RTag = llvm::dwarf::DW_TAG_union_type;
+    else {
+      assert(RD->isClass() && "Unknown RecordType!");
+      RTag = llvm::dwarf::DW_TAG_class_type;
+    }
+
+    llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
+    unsigned Line = getLineNumber(RD->getLocation());
+    llvm::DIDescriptor FDContext =
+      getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
+  
+    return
+      DebugFactory.CreateCompositeType(RTag, FDContext, RD->getName(),
+                                       DefUnit, Line, 0, 0, 0,
+                                       llvm::DIType::FlagFwdDecl,
+                                       llvm::DIType(), llvm::DIArray());
+  }
+  return getOrCreateType(PointeeTy, Unit);
+
+}
+
 llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
                                                 const Type *Ty, 
                                                 QualType PointeeTy,
                                                 llvm::DIFile Unit) {
-  llvm::DIType EltTy = getOrCreateType(PointeeTy, Unit);
-
   // Bit size, align and offset of the type.
   
   // Size is always the size of a pointer. We can't use getTypeSize here
@@ -427,10 +459,10 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
     CGM.getContext().Target.getPointerWidth(PointeeTy.getAddressSpace());
   uint64_t Align = CGM.getContext().getTypeAlign(Ty);
 
-  return
-    DebugFactory.CreateDerivedType(Tag, Unit, "", Unit,
-                                   0, Size, Align, 0, 0, EltTy);
-  
+  return DebugFactory.CreateDerivedType(Tag, Unit, "", Unit,
+                                        0, Size, Align, 0, 0, 
+                                        CreatePointeeType(PointeeTy, Unit));
+
 }
 
 llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
@@ -877,6 +909,14 @@ CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit,
   EltTys.push_back(VPTR);
 }
 
+/// getOrCreateRecordType - Emit record type's standalone debug info. 
+llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy, 
+                                                SourceLocation Loc) {
+  llvm::DIType T =  getOrCreateType(RTy, getOrCreateFile(Loc));
+  DebugFactory.RecordType(T);
+  return T;
+}
+
 /// CreateType - get structure or union type.
 llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
                                      llvm::DIFile Unit) {
index a1ad012353e5bef102fb97cf57ee7f6b60592c71..6df9a2fcb7579f3eba1daf831bab57f359884948 100644 (file)
@@ -98,7 +98,7 @@ class CGDebugInfo {
   llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);
   llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N, 
                                          llvm::DIDescriptor Unit);
-
+  llvm::DIType CreatePointeeType(QualType PointeeTy, llvm::DIFile F);
   llvm::DIType CreatePointerLikeType(unsigned Tag,
                                      const Type *Ty, QualType PointeeTy,
                                      llvm::DIFile F);
@@ -189,6 +189,8 @@ public:
   void EmitGlobalVariable(const ValueDecl *VD, llvm::ConstantInt *Init, 
                           CGBuilderTy &Builder);
 
+  /// getOrCreateRecordType - Emit record type's standalone debug info. 
+  llvm::DIType getOrCreateRecordType(QualType Ty, SourceLocation L);
 private:
   /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
   void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
index 68f40583892c7fc67096469b3a4976a65cfeaba9..bc4059593f5a14a783df656364b683ba50217fd7 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Frontend/CodeGenOptions.h"
 #include "CodeGenFunction.h"
 #include "CGCXXABI.h"
 #include "CGObjCRuntime.h"
+#include "CGDebugInfo.h"
 #include "llvm/Intrinsics.h"
 using namespace clang;
 using namespace CodeGen;
@@ -87,6 +89,15 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
   const MemberExpr *ME = cast<MemberExpr>(CE->getCallee()->IgnoreParens());
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
 
+  CGDebugInfo *DI = getDebugInfo();
+  if (DI && CGM.getCodeGenOpts().LimitDebugInfo) {
+    QualType PQTy = ME->getBase()->IgnoreParenImpCasts()->getType();
+    if (const PointerType * PTy = dyn_cast<PointerType>(PQTy)) {
+      DI->getOrCreateRecordType(PTy->getPointeeType(), 
+                                MD->getParent()->getLocation());
+    }
+  }
+
   if (MD->isStatic()) {
     // The method is static, emit it as we would a regular call.
     llvm::Value *Callee = CGM.GetAddrOfFunction(MD);
index 83ec814bc08e3e23a5479d43e5b389441459eceb..1662c375e6c3c701bdecb25e3a4d26a5dd0d0302 100644 (file)
@@ -1165,6 +1165,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior);
   Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
   Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
+  Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info);
 
   // -flax-vector-conversions is default.
   if (!Args.hasFlag(options::OPT_flax_vector_conversions,
index 11869a17d6542cd994d9c7004edb64404a15f9bf..132d7d0f8e93e69a499c8b9f073e63bc292ec33f 100644 (file)
@@ -859,6 +859,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
     : CodeGenOptions::OnlyAlwaysInlining;
 
   Opts.DebugInfo = Args.hasArg(OPT_g);
+  Opts.LimitDebugInfo = Args.hasArg(OPT_flimit_debug_info);
   Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
   Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
   Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);