Reapply 68847.
authorDevang Patel <dpatel@apple.com>
Mon, 13 Apr 2009 17:02:03 +0000 (17:02 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 13 Apr 2009 17:02:03 +0000 (17:02 +0000)
Now debug_inlined section is covered by TAI->doesDwarfUsesInlineInfoSection(), which is false by default.

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

include/llvm/CodeGen/DwarfWriter.h
include/llvm/Target/TargetAsmInfo.h
lib/CodeGen/AsmPrinter/DwarfWriter.cpp
lib/CodeGen/SelectionDAG/FastISel.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
lib/Target/TargetAsmInfo.cpp
lib/Target/X86/X86TargetAsmInfo.cpp

index 8e82718e6c2a8b256e4c8c28ade5b6546d16e76d..e7d9266510f50f67468c54ffa602be11765e6046 100644 (file)
@@ -94,6 +94,9 @@ public:
   /// RecordRegionStart - Indicate the start of a region.
   unsigned RecordRegionStart(GlobalVariable *V);
 
+  /// RecordRegionStart - Indicate the start of a region.
+  unsigned RecordRegionStart(GlobalVariable *V, unsigned ID);
+
   /// RecordRegionEnd - Indicate the end of a region.
   unsigned RecordRegionEnd(GlobalVariable *V);
 
@@ -107,6 +110,10 @@ public:
   /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
   /// be emitted.
   bool ShouldEmitDwarfDebug() const;
+
+  //// RecordInlineInfo - Global variable GV is inlined at the location marked
+  //// by LabelID label.
+  void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID);
 };
 
 
index b871009dda8ddef8c191a76fd30700db9f9f122c..e493538c5c503b6299073eff873a0f7fec855ec5 100644 (file)
@@ -463,6 +463,10 @@ namespace llvm {
     ///
     bool DwarfRequiresFrameSection; // Defaults to true.
 
+    /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to
+    /// encode inline subroutine information.
+    bool DwarfUsesInlineInfoSection; // Defaults to false.
+
     /// SupportsMacInfo - true if the Dwarf output supports macro information
     ///
     bool SupportsMacInfoSection;            // Defaults to true
@@ -506,7 +510,11 @@ namespace llvm {
     /// DwarfPubTypesSection - Section directive for Dwarf info.
     ///
     const char *DwarfPubTypesSection; // Defaults to ".debug_pubtypes".
-    
+
+    /// DwarfDebugInlineSection - Section directive for inline info.
+    ///
+    const char *DwarfDebugInlineSection; // Defaults to ".debug_inlined"
+
     /// DwarfStrSection - Section directive for Dwarf info.
     ///
     const char *DwarfStrSection; // Defaults to ".debug_str".
@@ -847,6 +855,9 @@ namespace llvm {
     bool doesDwarfRequireFrameSection() const {
       return DwarfRequiresFrameSection;
     }
+    bool doesDwarfUsesInlineInfoSection() const {
+      return DwarfUsesInlineInfoSection;
+    }
     bool doesSupportMacInfoSection() const {
       return SupportsMacInfoSection;
     }
@@ -880,6 +891,9 @@ namespace llvm {
     const char *getDwarfPubTypesSection() const {
       return DwarfPubTypesSection;
     }
+    const char *getDwarfDebugInlineSection() const {
+      return DwarfDebugInlineSection;
+    }
     const char *getDwarfStrSection() const {
       return DwarfStrSection;
     }
index 4582f4a447f9bcd860146dd59f41da3c59783cd7..c619bc57482d60370d9be8bdf5d01a674840b061 100644 (file)
@@ -1252,6 +1252,10 @@ class DwarfDebug : public Dwarf {
   /// DbgScopeMap - Tracks the scopes in the current function.
   DenseMap<GlobalVariable *, DbgScope *> DbgScopeMap;
 
+  /// InlineInfo - Keep track of inlined functions and their location.
+  /// This information is used to populate debug_inlined section.
+  DenseMap<GlobalVariable *, SmallVector<unsigned, 4> > InlineInfo;
+
   /// DebugTimer - Timer for the Dwarf debug writer.
   Timer *DebugTimer;
   
@@ -2027,15 +2031,18 @@ private:
     for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
       // Define the Scope debug information entry.
       DbgScope *Scope = Scopes[j];
-      // FIXME - Ignore inlined functions for the time being.
-      if (!Scope->getParent()) continue;
 
       unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
       unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
 
       // Ignore empty scopes.
       if (StartID == EndID && StartID != 0) continue;
-      if (Scope->getScopes().empty() && Scope->getVariables().empty()) continue;
+
+      // Do not ignore inlined scope even if it is empty. Inlined scope 
+      // does not have any parent.
+      if (Scope->getParent() 
+          && Scope->getScopes().empty() && Scope->getVariables().empty()) 
+        continue;
 
       if (StartID == ParentStartID && EndID == ParentEndID) {
         // Just add stuff to the parent scope.
@@ -2781,6 +2788,77 @@ private:
     }
   }
 
+  /// EmitDebugInlineInfo - Emit inline info using following format.
+  /// Section Header:
+  /// 1. length of section
+  /// 2. Dwarf version number
+  /// 3. address size.
+  ///
+  /// Entries (one "entry" for each function that was inlined):
+  ///
+  /// 1. offset into __debug_str section for MIPS linkage name, if exists; 
+  ///   otherwise offset into __debug_str for regular function name.
+  /// 2. offset into __debug_str section for regular function name.
+  /// 3. an unsigned LEB128 number indicating the number of distinct inlining 
+  /// instances for the function.
+  /// 
+  /// The rest of the entry consists of a {die_offset, low_pc}  pair for each 
+  /// inlined instance; the die_offset points to the inlined_subroutine die in
+  /// the __debug_info section, and the low_pc is the starting address  for the
+  ///  inlining instance.
+  void EmitDebugInlineInfo() {
+    if (!TAI->doesDwarfUsesInlineInfoSection())
+      return;
+
+    if (!MainCU)
+      return;
+
+    Asm->SwitchToDataSection(TAI->getDwarfDebugInlineSection());
+    Asm->EOL();
+    EmitDifference("debug_inlined_end", 1,
+                   "debug_inlined_begin", 1, true);
+    Asm->EOL("Length of Debug Inlined Information Entry");
+
+    EmitLabel("debug_inlined_begin", 1);
+
+    Asm->EmitInt16(DWARF_VERSION); Asm->EOL("Dwarf Version");
+    Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
+
+    for (DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator 
+           I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) {
+      GlobalVariable *GV = I->first;
+      SmallVector<unsigned, 4> &Labels = I->second;
+      DISubprogram SP(GV);
+      std::string Name;
+      std::string LName;
+
+      SP.getLinkageName(LName);
+      SP.getName(Name);
+
+      Asm->EmitString(LName.empty() ? Name : LName);
+      Asm->EOL("MIPS linkage name");
+
+      Asm->EmitString(Name); Asm->EOL("Function name");
+
+      Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count");
+
+      for (SmallVector<unsigned, 4>::iterator LI = Labels.begin(),
+             LE = Labels.end(); LI != LE; ++LI) {
+        DIE *SP = MainCU->getDieMapSlotFor(GV);
+        Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset");
+
+        if (TD->getPointerSize() == sizeof(int32_t))
+          O << TAI->getData32bitsDirective();
+        else
+          O << TAI->getData64bitsDirective();
+        PrintLabelName("label", *LI); Asm->EOL("low_pc");
+      }
+    }
+
+    EmitLabel("debug_inlined_end", 1);
+    Asm->EOL();
+  }
+
   /// 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
@@ -3131,6 +3209,9 @@ public:
     // Emit info into a debug macinfo section.
     EmitDebugMacInfo();
 
+    // Emit inline info.
+    EmitDebugInlineInfo();
+
     if (TimePassesIsEnabled)
       DebugTimer->stopTimer();
   }
@@ -3337,6 +3418,20 @@ public:
     return ID;
   }
 
+  /// RecordRegionStart - Indicate the start of a region.
+  unsigned RecordRegionStart(GlobalVariable *V, unsigned ID) {
+    if (TimePassesIsEnabled)
+      DebugTimer->startTimer();
+
+    DbgScope *Scope = getOrCreateScope(V);
+    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)
@@ -3377,6 +3472,23 @@ public:
     if (TimePassesIsEnabled)
       DebugTimer->stopTimer();
   }
+
+  //// RecordInlineInfo - Global variable GV is inlined at the location marked
+  //// by LabelID label.
+  void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) {
+    MMI->RecordUsedDbgLabel(LabelID);
+    DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator
+      I = InlineInfo.find(GV);
+    if (I == InlineInfo.end()) {
+      SmallVector<unsigned, 4> Labels;
+      Labels.push_back(LabelID);
+      InlineInfo[GV] = Labels;
+      return;
+    }
+
+    SmallVector<unsigned, 4> &Labels = I->second;
+    Labels.push_back(LabelID);
+  }
 };
 
 //===----------------------------------------------------------------------===//
@@ -4535,6 +4647,11 @@ unsigned DwarfWriter::RecordRegionStart(GlobalVariable *V) {
   return DD->RecordRegionStart(V);
 }
 
+/// RecordRegionStart - Indicate the start of a region.
+unsigned DwarfWriter::RecordRegionStart(GlobalVariable *V, unsigned ID) {
+  return DD->RecordRegionStart(V, ID);
+}
+
 /// RecordRegionEnd - Indicate the end of a region.
 unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) {
   return DD->RecordRegionEnd(V);
@@ -4556,3 +4673,10 @@ void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex) {
 bool DwarfWriter::ShouldEmitDwarfDebug() const {
   return DD->ShouldEmitDwarfDebug();
 }
+
+//// RecordInlineInfo - Global variable GV is inlined at the location marked
+//// by LabelID label.
+void DwarfWriter::RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) {
+  DD->RecordInlineInfo(GV, LabelID);
+}
+
index 251e96a771c9792c7418c14c4351281363f8e5c8..cc425e511906b0b345df8234f56756d909249c2e 100644 (file)
@@ -377,11 +377,23 @@ bool FastISel::SelectCall(User *I) {
 
       // Record the source line.
       unsigned Line = Subprogram.getLineNumber();
-      DW->RecordSourceLine(Line, 0, SrcFile);
+      unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
       setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
 
-      // llvm.dbg.func_start also defines beginning of function scope.
-      DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
+      std::string SPName;
+      Subprogram.getLinkageName(SPName);
+      if (!SPName.empty() 
+          && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+        // This is a beginning of inlined function.
+        DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()), 
+                              LabelID);
+        const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
+        BuildMI(MBB, DL, II).addImm(LabelID);
+        DW->RecordInlineInfo(Subprogram.getGV(), LabelID);
+      } else {
+        // llvm.dbg.func_start also defines beginning of function scope.
+        DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
+      }
     }
 
     return true;
index effb21514a2350eada3211897f0923f5bdd17b37..b5966431737e5db5b2a2ea53c15fe3b8a4c59643 100644 (file)
@@ -3955,6 +3955,18 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     DwarfWriter *DW = DAG.getDwarfWriter();
     DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
     if (DW && DW->ValidDebugInfo(REI.getContext())) {
+
+      MachineFunction &MF = DAG.getMachineFunction();
+      DISubprogram Subprogram(cast<GlobalVariable>(REI.getContext()));
+      std::string SPName;
+      Subprogram.getLinkageName(SPName);
+      if (!SPName.empty() 
+          && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+        // This is end of inlined function. Debugging information for
+        // inlined function is not handled yet (only supported by FastISel).
+        return 0;
+      }
+
       unsigned LabelID =
         DW->RecordRegionEnd(cast<GlobalVariable>(REI.getContext()));
       if (Fast)
@@ -3974,6 +3986,16 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
       // what (most?) gdb expects.
       MachineFunction &MF = DAG.getMachineFunction();
       DISubprogram Subprogram(cast<GlobalVariable>(SP));
+
+      std::string SPName;
+      Subprogram.getLinkageName(SPName);
+      if (!SPName.empty() 
+          && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+        // This is beginning of inlined function. Debugging information for
+        // inlined function is not handled yet (only supported by FastISel).
+        return 0;
+      }
+
       DICompileUnit CompileUnit = Subprogram.getCompileUnit();
       std::string Dir, FN;
       unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
index 4d9ec334acddaf46b436245476e880753dcabb6b..6a2de6f582a6464fdab056094fa2e19e3f37ef13 100644 (file)
@@ -101,6 +101,7 @@ void TargetAsmInfo::fillDefaultValues() {
   SupportsDebugInformation = false;
   SupportsExceptionHandling = false;
   DwarfRequiresFrameSection = true;
+  DwarfUsesInlineInfoSection = false;
   SupportsMacInfoSection = true;
   NonLocalEHFrameLabel = false;
   GlobalEHDirective = 0;
@@ -112,6 +113,7 @@ void TargetAsmInfo::fillDefaultValues() {
   DwarfFrameSection = ".debug_frame";
   DwarfPubNamesSection = ".debug_pubnames";
   DwarfPubTypesSection = ".debug_pubtypes";
+  DwarfDebugInlineSection = ".debug_inlined";
   DwarfStrSection = ".debug_str";
   DwarfLocSection = ".debug_loc";
   DwarfARangesSection = ".debug_aranges";
index f1d97a3893226dd3d8b0ae1bab1eab6496045864..5dda5f4e49b02a2133e82e63636c01ed7321bd9d 100644 (file)
@@ -112,6 +112,8 @@ X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM):
   DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
   DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
   DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
+  DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug";
+  DwarfUsesInlineInfoSection = true;
   DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
   DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
   DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";