Fixed the comment. No functionality change.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfWriter.cpp
index 5c4957aba113f198b0a4a75ea50ca6a98292582e..4120d9f917105721e3490c31557a796218456ff1 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Mangler.h"
+#include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
 #include "llvm/Target/TargetAsmInfo.h"
@@ -47,6 +48,11 @@ static RegisterPass<DwarfWriter>
 X("dwarfwriter", "DWARF Information Writer");
 char DwarfWriter::ID = 0;
 
+static TimerGroup &getDwarfTimerGroup() {
+  static TimerGroup DwarfTimerGroup("Dwarf Exception and Debugging");
+  return DwarfTimerGroup;
+}
+
 namespace llvm {
 
 //===----------------------------------------------------------------------===//
@@ -122,7 +128,6 @@ public:
 /// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
 /// Dwarf abbreviation.
 class DIEAbbrevData {
-private:
   /// Attribute - Dwarf attribute code.
   ///
   unsigned Attribute;
@@ -130,12 +135,8 @@ private:
   /// Form - Dwarf form code.
   ///
   unsigned Form;
-
 public:
-  DIEAbbrevData(unsigned A, unsigned F)
-  : Attribute(A)
-  , Form(F)
-  {}
+  DIEAbbrevData(unsigned A, unsigned F) : Attribute(A), Form(F) {}
 
   // Accessors.
   unsigned getAttribute() const { return Attribute; }
@@ -169,15 +170,9 @@ private:
   /// Data - Raw data bytes for abbreviation.
   ///
   SmallVector<DIEAbbrevData, 8> Data;
-
 public:
-
-  DIEAbbrev(unsigned T, unsigned C)
-  : Tag(T)
-  , ChildrenFlag(C)
-  , Data()
-  {}
-  ~DIEAbbrev() {}
+  DIEAbbrev(unsigned T, unsigned C) : Tag(T), ChildrenFlag(C), Data() {}
+  virtual ~DIEAbbrev() {}
 
   // Accessors.
   unsigned getTag()                           const { return Tag; }
@@ -251,12 +246,7 @@ protected:
 
 public:
   explicit DIE(unsigned Tag)
-  : Abbrev(Tag, DW_CHILDREN_no)
-  , Offset(0)
-  , Size(0)
-  , Children()
-  , Values()
-  {}
+    : Abbrev(Tag, DW_CHILDREN_no), Offset(0), Size(0), Children(), Values() {}
   virtual ~DIE();
 
   // Accessors.
@@ -334,9 +324,7 @@ public:
   ///
   unsigned Type;
 
-  explicit DIEValue(unsigned T)
-  : Type(T)
-  {}
+  explicit DIEValue(unsigned T) : Type(T) {}
   virtual ~DIEValue() {}
 
   // Accessors
@@ -423,10 +411,9 @@ public:
 /// DIEString - A string value DIE.
 ///
 class DIEString : public DIEValue {
+  const std::string Str;
 public:
-  const std::string String;
-
-  explicit DIEString(const std::string &S) : DIEValue(isString), String(S) {}
+  explicit DIEString(const std::string &S) : DIEValue(isString), Str(S) {}
 
   // Implement isa/cast/dyncast.
   static bool classof(const DIEString *) { return true; }
@@ -439,20 +426,20 @@ public:
   /// SizeOf - Determine size of string value in bytes.
   ///
   virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const {
-    return String.size() + sizeof(char); // sizeof('\0');
+    return Str.size() + sizeof(char); // sizeof('\0');
   }
 
   /// Profile - Used to gather unique data for the value folding set.
   ///
-  static void Profile(FoldingSetNodeID &ID, const std::string &String) {
+  static void Profile(FoldingSetNodeID &ID, const std::string &Str) {
     ID.AddInteger(isString);
-    ID.AddString(String);
+    ID.AddString(Str);
   }
-  virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, String); }
+  virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Str); }
 
 #ifndef NDEBUG
   virtual void print(std::ostream &O) {
-    O << "Str: \"" << String << "\"";
+    O << "Str: \"" << Str << "\"";
   }
 #endif
 };
@@ -461,10 +448,8 @@ public:
 /// DIEDwarfLabel - A Dwarf internal label expression DIE.
 //
 class DIEDwarfLabel : public DIEValue {
-public:
-
   const DWLabel Label;
-
+public:
   explicit DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
 
   // Implement isa/cast/dyncast.
@@ -495,14 +480,12 @@ public:
 #endif
 };
 
-
 //===----------------------------------------------------------------------===//
 /// DIEObjectLabel - A label to an object in code or data.
 //
 class DIEObjectLabel : public DIEValue {
-public:
   const std::string Label;
-
+public:
   explicit DIEObjectLabel(const std::string &L)
   : DIEValue(isAsIsLabel), Label(L) {}
 
@@ -537,16 +520,15 @@ public:
 /// DIESectionOffset - A section offset DIE.
 //
 class DIESectionOffset : public DIEValue {
-public:
   const DWLabel Label;
   const DWLabel Section;
   bool IsEH : 1;
   bool UseSet : 1;
-
+public:
   DIESectionOffset(const DWLabel &Lab, const DWLabel &Sec,
                    bool isEH = false, bool useSet = true)
-  : DIEValue(isSectionOffset), Label(Lab), Section(Sec),
-                               IsEH(isEH), UseSet(useSet) {}
+    : DIEValue(isSectionOffset), Label(Lab), Section(Sec),
+      IsEH(isEH), UseSet(useSet) {}
 
   // Implement isa/cast/dyncast.
   static bool classof(const DIESectionOffset *)  { return true; }
@@ -587,12 +569,11 @@ public:
 /// DIEDelta - A simple label difference DIE.
 ///
 class DIEDelta : public DIEValue {
-public:
   const DWLabel LabelHi;
   const DWLabel LabelLo;
-
+public:
   DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
-  : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
+    : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
 
   // Implement isa/cast/dyncast.
   static bool classof(const DIEDelta *)  { return true; }
@@ -631,11 +612,12 @@ public:
 /// class can also be used as a proxy for a debug information entry not yet
 /// defined (ie. types.)
 class DIEntry : public DIEValue {
-public:
   DIE *Entry;
-
+public:
   explicit DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
 
+  void setEntry(DIE *E) { Entry = E; }
+
   // Implement isa/cast/dyncast.
   static bool classof(const DIEntry *)   { return true; }
   static bool classof(const DIEValue *E) { return E->Type == isEntry; }
@@ -677,16 +659,11 @@ public:
 /// DIEBlock - A block of values.  Primarily used for location expressions.
 //
 class DIEBlock : public DIEValue, public DIE {
+  unsigned Size;                // Size in bytes excluding size header.
 public:
-  unsigned Size;                        // Size in bytes excluding size header.
-
   DIEBlock()
-  : DIEValue(isBlock)
-  , DIE(0)
-  , Size(0)
-  {}
-  ~DIEBlock()  {
-  }
+    : DIEValue(isBlock), DIE(0), Size(0) {}
+  virtual ~DIEBlock() {}
 
   // Implement isa/cast/dyncast.
   static bool classof(const DIEBlock *)  { return true; }
@@ -713,7 +690,6 @@ public:
   ///
   virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const;
 
-
   /// Profile - Used to gather unique data for the value folding set.
   ///
   virtual void Profile(FoldingSetNodeID &ID) {
@@ -733,7 +709,6 @@ public:
 /// CompileUnit - This dwarf writer support class manages information associate
 /// with a source file.
 class CompileUnit {
-private:
   /// ID - File identifier for source.
   ///
   unsigned ID;
@@ -757,7 +732,6 @@ private:
   /// DiesSet - Used to uniquely define dies within the compile unit.
   ///
   FoldingSet<DIE> DiesSet;
-
 public:
   CompileUnit(unsigned I, DIE *D)
     : ID(I), Die(D), GVToDieMap(),
@@ -1275,8 +1249,11 @@ class DwarfDebug : public Dwarf {
   //
   DbgScope *RootDbgScope;
   
-  // DbgScopeMap - Tracks the scopes in the current function.
+  /// DbgScopeMap - Tracks the scopes in the current function.
   DenseMap<GlobalVariable *, DbgScope *> DbgScopeMap;
+
+  /// DebugTimer - Timer for the Dwarf debug writer.
+  Timer *DebugTimer;
   
   struct FunctionDebugFrameInfo {
     unsigned Number;
@@ -1288,12 +1265,36 @@ class DwarfDebug : public Dwarf {
 
   std::vector<FunctionDebugFrameInfo> DebugFrames;
 
-public:
+private:
+  /// getSourceDirectoryAndFileIds - Return the directory and file ids that
+  /// maps to the source id. Source id starts at 1.
+  std::pair<unsigned, unsigned>
+  getSourceDirectoryAndFileIds(unsigned SId) const {
+    return SourceIds[SId-1];
+  }
 
-  /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
-  /// be emitted.
-  ///
-  bool ShouldEmitDwarfDebug() const { return shouldEmit; }
+  /// getNumSourceDirectories - Return the number of source directories in the
+  /// debug info.
+  unsigned getNumSourceDirectories() const {
+    return DirectoryNames.size();
+  }
+
+  /// getSourceDirectoryName - Return the name of the directory corresponding
+  /// to the id.
+  const std::string &getSourceDirectoryName(unsigned Id) const {
+    return DirectoryNames[Id - 1];
+  }
+
+  /// getSourceFileName - Return the name of the source file corresponding
+  /// to the id.
+  const std::string &getSourceFileName(unsigned Id) const {
+    return SourceFileNames[Id - 1];
+  }
+
+  /// getNumSourceIds - Return the number of unique source ids.
+  unsigned getNumSourceIds() const {
+    return SourceIds.size();
+  }
 
   /// AssignAbbrevNumber - Define a unique number for the abbreviation.
   ///
@@ -1350,7 +1351,7 @@ public:
   /// SetDIEntry - Set a DIEntry once the debug information entry is defined.
   ///
   void SetDIEntry(DIEntry *Value, DIE *Entry) {
-    Value->Entry = Entry;
+    Value->setEntry(Entry);
     // Add to values set if not already there.  If it is, we merely have a
     // duplicate in the values list (no harm.)
     ValuesSet.GetOrInsertNode(Value);
@@ -1505,8 +1506,6 @@ public:
     Die->AddValue(Attribute, Block->BestForm(), Value);
   }
 
-private:
-
   /// AddSourceLine - Add location information to specified debug information
   /// entry.
   void AddSourceLine(DIE *Die, const DIVariable *V) {
@@ -1622,7 +1621,8 @@ private:
                         DIBasicType BTy) {
     
     // Get core information.
-    const std::string &Name = BTy.getName();
+    std::string Name;
+    BTy.getName(Name);
     Buffer.setTag(DW_TAG_base_type);
     AddUInt(&Buffer, DW_AT_encoding,  DW_FORM_data1, BTy.getEncoding());
     // Add name if not anonymous or intermediate type.
@@ -1637,13 +1637,16 @@ private:
                         DIDerivedType DTy) {
 
     // Get core information.
-    const std::string &Name = DTy.getName();
+    std::string Name;
+    DTy.getName(Name);
     uint64_t Size = DTy.getSizeInBits() >> 3;
     unsigned Tag = DTy.getTag();
+
     // FIXME - Workaround for templates.
     if (Tag == DW_TAG_inheritance) Tag = DW_TAG_reference_type;
 
     Buffer.setTag(Tag);
+
     // Map to main type, void will not have a type.
     DIType FromTy = DTy.getTypeDerivedFrom();
     AddType(DW_Unit, &Buffer, FromTy);
@@ -1665,12 +1668,14 @@ private:
   /// ConstructTypeDIE - Construct type DIE from DICompositeType.
   void ConstructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
                         DICompositeType CTy) {
-
     // Get core information.
-    const std::string &Name = CTy.getName();
+    std::string Name;
+    CTy.getName(Name);
+
     uint64_t Size = CTy.getSizeInBits() >> 3;
     unsigned Tag = CTy.getTag();
     Buffer.setTag(Tag);
+
     switch (Tag) {
     case DW_TAG_vector_type:
     case DW_TAG_array_type:
@@ -1806,7 +1811,8 @@ private:
   DIE *ConstructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
 
     DIE *Enumerator = new DIE(DW_TAG_enumerator);
-    const std::string &Name = ETy->getName();
+    std::string Name;
+    ETy->getName(Name);
     AddString(Enumerator, DW_AT_name, DW_FORM_string, Name);
     int64_t Value = ETy->getEnumValue();                             
     AddSInt(Enumerator, DW_AT_const_value, DW_FORM_sdata, Value);
@@ -1817,9 +1823,11 @@ private:
   DIE *CreateGlobalVariableDIE(CompileUnit *DW_Unit, const DIGlobalVariable &GV)
   {
     DIE *GVDie = new DIE(DW_TAG_variable);
-    const std::string &Name = GV.getDisplayName();
+    std::string Name;
+    GV.getDisplayName(Name);
     AddString(GVDie, DW_AT_name, DW_FORM_string, Name);
-    const std::string &LinkageName = GV.getLinkageName();
+    std::string LinkageName;
+    GV.getLinkageName(LinkageName);
     if (!LinkageName.empty())
       AddString(GVDie, DW_AT_MIPS_linkage_name, DW_FORM_string, LinkageName);
     AddType(DW_Unit, GVDie, GV.getType());
@@ -1832,7 +1840,8 @@ private:
   /// CreateMemberDIE - Create new member DIE.
   DIE *CreateMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT) {
     DIE *MemberDie = new DIE(DT.getTag());
-    const std::string &Name = DT.getName();
+    std::string Name;
+    DT.getName(Name);
     if (!Name.empty())
       AddString(MemberDie, DW_AT_name, DW_FORM_string, Name);
 
@@ -1876,9 +1885,11 @@ private:
                            const  DISubprogram &SP,
                            bool IsConstructor = false) {
     DIE *SPDie = new DIE(DW_TAG_subprogram);
-    const std::string &Name = SP.getName();
+    std::string Name;
+    SP.getName(Name);
     AddString(SPDie, DW_AT_name, DW_FORM_string, Name);
-    const std::string &LinkageName = SP.getLinkageName();
+    std::string LinkageName;
+    SP.getLinkageName(LinkageName);
     if (!LinkageName.empty())
       AddString(SPDie, DW_AT_MIPS_linkage_name, DW_FORM_string, 
                 LinkageName);
@@ -1945,7 +1956,8 @@ private:
 
     // Define variable debug information entry.
     DIE *VariableDie = new DIE(Tag);
-    const std::string &Name = VD.getName();
+    std::string Name;
+    VD.getName(Name);
     AddString(VariableDie, DW_AT_name, DW_FORM_string, Name);
 
     // Add source line info if available.
@@ -2453,7 +2465,7 @@ private:
     // Emit files.
     for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
       // Remember source id starts at 1.
-      std::pair<unsigned, unsigned> Id = getSourceDirsectoryAndFileIds(SI);
+      std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
       Asm->EmitString(getSourceFileName(Id.second));
       Asm->EOL("Source");
       Asm->EmitULEB128Bytes(Id.first);
@@ -2495,7 +2507,7 @@ private:
           Asm->EOL();
         else {
           std::pair<unsigned, unsigned> SourceID =
-            getSourceDirsectoryAndFileIds(LineInfo.getSourceID());
+            getSourceDirectoryAndFileIds(LineInfo.getSourceID());
           O << '\t' << TAI->getCommentString() << ' '
             << getSourceDirectoryName(SourceID.first) << ' '
             << getSourceFileName(SourceID.second)
@@ -2767,23 +2779,63 @@ private:
     }
   }
 
+  /// GetOrCreateSourceID - Look up the source id with the given directory and
+  /// source file names. If none currently exists, create a new id and insert it
+  /// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
+  /// as well.
+  unsigned GetOrCreateSourceID(const std::string &DirName,
+                               const std::string &FileName) {
+    unsigned DId;
+    StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
+    if (DI != DirectoryIdMap.end()) {
+      DId = DI->getValue();
+    } else {
+      DId = DirectoryNames.size() + 1;
+      DirectoryIdMap[DirName] = DId;
+      DirectoryNames.push_back(DirName);
+    }
+  
+    unsigned FId;
+    StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
+    if (FI != SourceFileIdMap.end()) {
+      FId = FI->getValue();
+    } else {
+      FId = SourceFileNames.size() + 1;
+      SourceFileIdMap[FileName] = FId;
+      SourceFileNames.push_back(FileName);
+    }
+
+    DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
+      SourceIdMap.find(std::make_pair(DId, FId));
+    if (SI != SourceIdMap.end())
+      return SI->second;
+
+    unsigned SrcId = SourceIds.size() + 1;  // DW_AT_decl_file cannot be 0.
+    SourceIdMap[std::make_pair(DId, FId)] = SrcId;
+    SourceIds.push_back(std::make_pair(DId, FId));
+
+    return SrcId;
+  }
+
   void ConstructCompileUnit(GlobalVariable *GV) {
     DICompileUnit DIUnit(GV);
-    unsigned ID = getOrCreateSourceID(DIUnit.getDirectory(),
-                                      DIUnit.getFilename());
+    std::string Dir, FN, Prod;
+    unsigned ID = GetOrCreateSourceID(DIUnit.getDirectory(Dir),
+                                      DIUnit.getFilename(FN));
 
     DIE *Die = new DIE(DW_TAG_compile_unit);
     AddSectionOffset(Die, DW_AT_stmt_list, DW_FORM_data4,
                      DWLabel("section_line", 0), DWLabel("section_line", 0),
                      false);
-    AddString(Die, DW_AT_producer, DW_FORM_string, DIUnit.getProducer());
+    AddString(Die, DW_AT_producer, DW_FORM_string, DIUnit.getProducer(Prod));
     AddUInt(Die, DW_AT_language, DW_FORM_data1, DIUnit.getLanguage());
-    AddString(Die, DW_AT_name, DW_FORM_string, DIUnit.getFilename());
-    if (!DIUnit.getDirectory().empty())
-      AddString(Die, DW_AT_comp_dir, DW_FORM_string, DIUnit.getDirectory());
+    AddString(Die, DW_AT_name, DW_FORM_string, FN);
+    if (!Dir.empty())
+      AddString(Die, DW_AT_comp_dir, DW_FORM_string, Dir);
     if (DIUnit.isOptimized())
       AddUInt(Die, DW_AT_APPLE_optimized, DW_FORM_flag, 1);
-    const std::string &Flags = DIUnit.getFlags();
+    std::string Flags;
+    DIUnit.getFlags(Flags);
     if (!Flags.empty())
       AddString(Die, DW_AT_APPLE_flags, DW_FORM_string, Flags);
     unsigned RVer = DIUnit.getRunTimeVersion();
@@ -2843,7 +2895,8 @@ private:
     // Add to context owner.
     DW_Unit->getDie()->AddChild(VariableDie);
     // Expose as global. FIXME - need to check external flag.
-    DW_Unit->AddGlobal(DI_GV.getName(), VariableDie);
+    std::string Name;
+    DW_Unit->AddGlobal(DI_GV.getName(Name), VariableDie);
     return true;
   }
 
@@ -2895,7 +2948,8 @@ private:
     // Add to context owner.
     Unit->getDie()->AddChild(SubprogramDie);
     // Expose as global.
-    Unit->AddGlobal(SP.getName(), SubprogramDie);
+    std::string Name;
+    Unit->AddGlobal(SP.getName(Name), SubprogramDie);
     return true;
   }
 
@@ -2928,33 +2982,41 @@ public:
   // Main entry points.
   //
   DwarfDebug(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
-  : Dwarf(OS, A, T, "dbg")
-  , MainCU(NULL)
-  , AbbreviationsSet(InitAbbreviationsSetSize)
-  , Abbreviations()
-  , ValuesSet(InitValuesSetSize)
-  , Values()
-  , StringPool()
-  , SectionMap()
-  , SectionSourceLines()
-  , didInitial(false)
-  , shouldEmit(false)
-  , RootDbgScope(NULL)
-  {
+    : Dwarf(OS, A, T, "dbg"), MainCU(0),
+      AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
+      ValuesSet(InitValuesSetSize), Values(), StringPool(), SectionMap(),
+      SectionSourceLines(), didInitial(false), shouldEmit(false),
+      RootDbgScope(0), DebugTimer(0) {
+    if (TimePassesIsEnabled)
+      DebugTimer = new Timer("Dwarf Debug Writer",
+                             getDwarfTimerGroup());
   }
   virtual ~DwarfDebug() {
     for (unsigned j = 0, M = Values.size(); j < M; ++j)
       delete Values[j];
+
+    delete DebugTimer;
   }
 
+  /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
+  /// be emitted.
+  bool ShouldEmitDwarfDebug() const { return shouldEmit; }
+
   /// SetDebugInfo - Create global DIEs and emit initial debug info sections.
   /// This is inovked by the target AsmPrinter.
   void SetDebugInfo(MachineModuleInfo *mmi) {
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     // Create all the compile unit DIEs.
     ConstructCompileUnits();
       
-    if (CompileUnits.empty())
+    if (CompileUnits.empty()) {
+      if (TimePassesIsEnabled)
+        DebugTimer->stopTimer();
+
       return;
+    }
 
     // Create DIEs for each of the externally visible global variables.
     bool globalDIEs = ConstructGlobalVariableDIEs();
@@ -2964,8 +3026,12 @@ public:
 
     // If there is not any debug info available for any global variables
     // and any subprograms then there is not any debug info to emit.
-    if (!globalDIEs && !subprogramDIEs)
+    if (!globalDIEs && !subprogramDIEs) {
+      if (TimePassesIsEnabled)
+        DebugTimer->stopTimer();
+
       return;
+    }
 
     MMI = mmi;
     shouldEmit = true;
@@ -2979,7 +3045,7 @@ public:
     if (TAI->hasDotLocAndDotFile()) {
       for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
         // Remember source id starts at 1.
-        std::pair<unsigned, unsigned> Id = getSourceDirsectoryAndFileIds(i);
+        std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
         sys::Path FullPath(getSourceDirectoryName(Id.first));
         bool AppendOk =
           FullPath.appendComponent(getSourceFileName(Id.second));
@@ -2992,6 +3058,9 @@ public:
 
     // Emit initial sections
     EmitInitial();
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
   }
 
   /// BeginModule - Emit all Dwarf sections that should come prior to the
@@ -3003,7 +3072,11 @@ public:
   /// EndModule - Emit all Dwarf sections that should come after the content.
   ///
   void EndModule() {
-    if (!ShouldEmitDwarfDebug()) return;
+    if (!ShouldEmitDwarfDebug())
+      return;
+
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
 
     // Standard sections final addresses.
     Asm->SwitchToSection(TAI->getTextSection());
@@ -3054,6 +3127,9 @@ public:
 
     // Emit info into a debug macinfo section.
     EmitDebugMacInfo();
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
   }
 
   /// BeginFunction - Gather pre-function debug information.  Assumes being
@@ -3063,6 +3139,9 @@ public:
 
     if (!ShouldEmitDwarfDebug()) return;
 
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     // Begin accumulating function debug information.
     MMI->BeginFunction(MF);
 
@@ -3075,6 +3154,9 @@ public:
       const SrcLineInfo &LineInfo = Lines[0];
       Asm->printLabel(LineInfo.getLabelID());
     }
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
   }
 
   /// EndFunction - Gather and emit post-function debug information.
@@ -3082,6 +3164,9 @@ public:
   void EndFunction(MachineFunction *MF) {
     if (!ShouldEmitDwarfDebug()) return;
 
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     // Define end label for subprogram.
     EmitLabel("func_end", SubprogramCount);
 
@@ -3119,10 +3204,12 @@ public:
       DbgScopeMap.clear();
       RootDbgScope = NULL;
     }
+
     Lines.clear();
-  }
 
-public:
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
+  }
 
   /// ValidDebugInfo - Return true if V represents valid debug info value.
   bool ValidDebugInfo(Value *V) {
@@ -3135,16 +3222,23 @@ public:
     GlobalVariable *GV = getGlobalVariable(V);
     if (!GV)
       return false;
-    
-    if (GV->getLinkage() != GlobalValue::InternalLinkage
-        && GV->getLinkage() != GlobalValue::LinkOnceLinkage)
+
+    if (!GV->hasInternalLinkage () && !GV->hasLinkOnceLinkage())
       return false;
 
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     DIDescriptor DI(GV);
+
     // Check current version. Allow Version6 for now.
     unsigned Version = DI.getVersion();
-    if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6)
+    if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6) {
+      if (TimePassesIsEnabled)
+        DebugTimer->stopTimer();
+
       return false;
+    }
 
     unsigned Tag = DI.getTag();
     switch (Tag) {
@@ -3161,6 +3255,9 @@ public:
       break;
     }
 
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
+
     return true;
   }
 
@@ -3168,10 +3265,17 @@ public:
   /// label. Returns a unique label ID used to generate a label and provide
   /// correspondence to the source line list.
   unsigned RecordSourceLine(Value *V, unsigned Line, unsigned Col) {
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     CompileUnit *Unit = CompileUnitMap[V];
     assert(Unit && "Unable to find CompileUnit");
     unsigned ID = MMI->NextLabelID();
     Lines.push_back(SrcLineInfo(Line, Col, Unit->getID(), ID));
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
+
     return ID;
   }
   
@@ -3179,111 +3283,80 @@ public:
   /// label. Returns a unique label ID used to generate a label and provide
   /// correspondence to the source line list.
   unsigned RecordSourceLine(unsigned Line, unsigned Col, unsigned Src) {
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     unsigned ID = MMI->NextLabelID();
     Lines.push_back(SrcLineInfo(Line, Col, Src, ID));
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
+
     return ID;
   }
 
-  unsigned getRecordSourceLineCount() {
+  /// getRecordSourceLineCount - Return the number of source lines in the debug
+  /// info.
+  unsigned getRecordSourceLineCount() const {
     return Lines.size();
   }
                             
-  /// getNumSourceDirectories - Return the number of source directories in the
-  /// debug info.
-  unsigned getNumSourceDirectories() const {
-    return DirectoryNames.size();
-  }
-
-  /// getSourceDirectoryName - Return the name of the directory corresponding
-  /// to the id.
-  const std::string &getSourceDirectoryName(unsigned Id) const {
-    return DirectoryNames[Id - 1];
-  }
-
-  /// getNumSourceFiles - Return the number of source files in the debug info.
-  ///
-  unsigned getNumSourceFiles() const {
-    return SourceFileNames.size();
-  }
-
-  /// getSourceFileName - Return the name of the source file corresponding
-  /// to the id.
-  const std::string &getSourceFileName(unsigned Id) const {
-    return SourceFileNames[Id - 1];
-  }
-
-  /// getNumSourceIds - Return the number of unique source ids.
-  ///
-  unsigned getNumSourceIds() const {
-    return SourceIds.size();
-  }
-
-  /// getSourceDirsectoryAndFileIds - Return the directory and file ids that
-  /// maps to the source id. Source id starts at 1.
-  std::pair<unsigned, unsigned>
-  getSourceDirsectoryAndFileIds(unsigned SId) const {
-    return SourceIds[SId-1];
-  }
-
-  /// getOrCreateSourceID - Look up the source id with the given directory and
-  /// source file names. If none currently exists, create a new id and insert it
-  /// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
-  /// as well.
+  /// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be
+  /// timed. Look up the source id with the given directory and source file
+  /// names. If none currently exists, create a new id and insert it in the
+  /// SourceIds map. This can update DirectoryNames and SourceFileNames maps as
+  /// well.
   unsigned getOrCreateSourceID(const std::string &DirName,
                                const std::string &FileName) {
-    unsigned DId;
-    StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
-    if (DI != DirectoryIdMap.end())
-      DId = DI->getValue();
-    else {
-      DId = DirectoryNames.size() + 1;
-      DirectoryIdMap[DirName] = DId;
-      DirectoryNames.push_back(DirName);
-    }
-  
-    unsigned FId;
-    StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
-    if (FI != SourceFileIdMap.end())
-      FId = FI->getValue();
-    else {
-      FId = SourceFileNames.size() + 1;
-      SourceFileIdMap[FileName] = FId;
-      SourceFileNames.push_back(FileName);
-    }
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
+    unsigned SrcId = GetOrCreateSourceID(DirName, FileName);
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
 
-    DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
-      SourceIdMap.find(std::make_pair(DId, FId));
-    if (SI != SourceIdMap.end())
-      return SI->second;
-    unsigned SrcId = SourceIds.size() + 1;  // DW_AT_decl_file cannot be 0.
-    SourceIdMap[std::make_pair(DId, FId)] = SrcId;
-    SourceIds.push_back(std::make_pair(DId, FId));
     return SrcId;
   }
 
   /// RecordRegionStart - Indicate the start of a region.
-  ///
   unsigned RecordRegionStart(GlobalVariable *V) {
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     DbgScope *Scope = getOrCreateScope(V);
     unsigned ID = MMI->NextLabelID();
     if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID);
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
+
     return ID;
   }
 
   /// RecordRegionEnd - Indicate the end of a region.
-  ///
   unsigned RecordRegionEnd(GlobalVariable *V) {
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     DbgScope *Scope = getOrCreateScope(V);
     unsigned ID = MMI->NextLabelID();
     Scope->setEndLabelID(ID);
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
+
     return ID;
   }
 
   /// RecordVariable - Indicate the declaration of  a local variable.
-  ///
   void RecordVariable(GlobalVariable *GV, unsigned FrameIndex) {
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
     DIDescriptor Desc(GV);
     DbgScope *Scope = NULL;
+
     if (Desc.getTag() == DW_TAG_variable) {
       // GV is a global variable.
       DIGlobalVariable DG(GV);
@@ -3293,9 +3366,13 @@ public:
       DIVariable DV(GV);
       Scope = getOrCreateScope(DV.getContext().getGV());
     }
+
     assert(Scope && "Unable to find variable' scope");
     DbgVariable *DV = new DbgVariable(DIVariable(GV), FrameIndex);
     Scope->AddVariable(DV);
+
+    if (TimePassesIsEnabled)
+      DebugTimer->stopTimer();
   }
 };
 
@@ -3338,6 +3415,9 @@ class DwarfException : public Dwarf  {
   /// should be emitted.
   bool shouldEmitMovesModule;
 
+  /// ExceptionTimer - Timer for the Dwarf exception writer.
+  Timer *ExceptionTimer;
+
   /// EmitCommonEHFrame - Emit the common eh unwind frame.
   ///
   void EmitCommonEHFrame(const Function *Personality, unsigned Index) {
@@ -3449,8 +3529,10 @@ class DwarfException : public Dwarf  {
     }
 
     // If corresponding function is weak definition, this should be too.
-    if ((linkage == Function::WeakLinkage ||
-         linkage == Function::LinkOnceLinkage) &&
+    if ((linkage == Function::WeakAnyLinkage ||
+         linkage == Function::WeakODRLinkage ||
+         linkage == Function::LinkOnceAnyLinkage ||
+         linkage == Function::LinkOnceODRLinkage) &&
         TAI->getWeakDefDirective())
       O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n";
 
@@ -3461,8 +3543,10 @@ class DwarfException : public Dwarf  {
     // unwind info is to be available for non-EH uses.
     if (!EHFrameInfo.hasCalls &&
         !UnwindTablesMandatory &&
-        ((linkage != Function::WeakLinkage &&
-          linkage != Function::LinkOnceLinkage) ||
+        ((linkage != Function::WeakAnyLinkage &&
+          linkage != Function::WeakODRLinkage &&
+          linkage != Function::LinkOnceAnyLinkage &&
+          linkage != Function::LinkOnceODRLinkage) ||
          !TAI->getWeakDefDirective() ||
          TAI->getSupportsWeakOmittedEHFrame()))
     {
@@ -3946,14 +4030,17 @@ public:
   // Main entry points.
   //
   DwarfException(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
-  : Dwarf(OS, A, T, "eh")
-  , shouldEmitTable(false)
-  , shouldEmitMoves(false)
-  , shouldEmitTableModule(false)
-  , shouldEmitMovesModule(false)
-  {}
+  : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false),
+    shouldEmitTableModule(false), shouldEmitMovesModule(false),
+    ExceptionTimer(0) {
+    if (TimePassesIsEnabled) 
+      ExceptionTimer = new Timer("Dwarf Exception Writer",
+                                 getDwarfTimerGroup());
+  }
 
-  virtual ~DwarfException() {}
+  virtual ~DwarfException() {
+    delete ExceptionTimer;
+  }
 
   /// SetModuleInfo - Set machine module information when it's known that pass
   /// manager has created it.  Set by the target AsmPrinter.
@@ -3970,6 +4057,9 @@ public:
   /// EndModule - Emit all exception information that should come after the
   /// content.
   void EndModule() {
+    if (TimePassesIsEnabled)
+      ExceptionTimer->startTimer();
+
     if (shouldEmitMovesModule || shouldEmitTableModule) {
       const std::vector<Function *> Personalities = MMI->getPersonalities();
       for (unsigned i = 0; i < Personalities.size(); ++i)
@@ -3979,17 +4069,24 @@ public:
              E = EHFrames.end(); I != E; ++I)
         EmitEHFrame(*I);
     }
+
+    if (TimePassesIsEnabled)
+      ExceptionTimer->stopTimer();
   }
 
   /// BeginFunction - Gather pre-function exception information.  Assumes being
   /// emitted immediately after the function entry point.
   void BeginFunction(MachineFunction *MF) {
+    if (TimePassesIsEnabled)
+      ExceptionTimer->startTimer();
+
     this->MF = MF;
     shouldEmitTable = shouldEmitMoves = false;
-    if (MMI && TAI->doesSupportExceptionHandling()) {
 
+    if (MMI && TAI->doesSupportExceptionHandling()) {
       // Map all labels and get rid of any dead landing pads.
       MMI->TidyLandingPads();
+
       // If any landing pads survive, we need an EH table.
       if (MMI->getLandingPads().size())
         shouldEmitTable = true;
@@ -4002,13 +4099,20 @@ public:
         // Assumes in correct section after the entry point.
         EmitLabel("eh_func_begin", ++SubprogramCount);
     }
+
     shouldEmitTableModule |= shouldEmitTable;
     shouldEmitMovesModule |= shouldEmitMoves;
+
+    if (TimePassesIsEnabled)
+      ExceptionTimer->stopTimer();
   }
 
   /// EndFunction - Gather and emit post-function exception information.
   ///
   void EndFunction() {
+    if (TimePassesIsEnabled) 
+      ExceptionTimer->startTimer();
+
     if (shouldEmitMoves || shouldEmitTable) {
       EmitLabel("eh_func_end", SubprogramCount);
       EmitExceptionTable();
@@ -4016,13 +4120,16 @@ public:
       // Save EH frame information
       EHFrames.
         push_back(FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF),
-                                    SubprogramCount,
-                                    MMI->getPersonalityIndex(),
-                                    MF->getFrameInfo()->hasCalls(),
-                                    !MMI->getLandingPads().empty(),
-                                    MMI->getFrameMoves(),
-                                    MF->getFunction()));
-      }
+                                      SubprogramCount,
+                                      MMI->getPersonalityIndex(),
+                                      MF->getFrameInfo()->hasCalls(),
+                                      !MMI->getLandingPads().empty(),
+                                      MMI->getFrameMoves(),
+                                      MF->getFunction()));
+    }
+
+    if (TimePassesIsEnabled) 
+      ExceptionTimer->stopTimer();
   }
 };
 
@@ -4134,7 +4241,7 @@ unsigned DIEInteger::SizeOf(const DwarfDebug &DD, unsigned Form) const {
 /// EmitValue - Emit string value.
 ///
 void DIEString::EmitValue(DwarfDebug &DD, unsigned Form) {
-  DD.getAsm()->EmitString(String);
+  DD.getAsm()->EmitString(Str);
 }
 
 //===----------------------------------------------------------------------===//
@@ -4345,8 +4452,8 @@ void DIE::dump() {
 /// DwarfWriter Implementation
 ///
 
-DwarfWriter::DwarfWriter() : ImmutablePass(&ID), DD(NULL), DE(NULL) {
-}
+DwarfWriter::DwarfWriter()
+  : ImmutablePass(&ID), DD(0), DE(0) {}
 
 DwarfWriter::~DwarfWriter() {
   delete DE;