[llvm-branch-commits] [llvm-branch] r69323 - in /llvm/branches/Apple/Dib: include/llvm/Analysis/ include/llvm/CodeGen/ include/llvm/Target/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/X86/ lib/Transforms/Utils/ test/Transforms/Inline/

Devang Patel dpatel at apple.com
Thu Apr 16 16:28:27 PDT 2009


Author: dpatel
Date: Thu Apr 16 18:28:27 2009
New Revision: 69323

URL: http://llvm.org/viewvc/llvm-project?rev=69323&view=rev
Log:
Merge patches from mainline to support debugging of inlined functions.

Following svn revisions from mainline are merged in to Dib branch:
68647 68727 68735 68813 68964 68973 69113 69116 69118 
69202 69210 69216 69252 69253 69254 69286 69300


Removed:
    llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll
Modified:
    llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h
    llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h
    llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h
    llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h
    llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h
    llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp
    llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp
    llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp
    llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp

Modified: llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h Thu Apr 16 18:28:27 2009
@@ -309,6 +309,10 @@
 
     /// dump - print subprogram.
     void dump() const;
+
+    /// describes - Return true if this subprogram provides debugging
+    /// information for the function F.
+    bool describes(const Function *F);
   };
 
   /// DIGlobalVariable - This is a wrapper for a global variable.

Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h Thu Apr 16 18:28:27 2009
@@ -29,11 +29,15 @@
 class DwarfException;
 class MachineModuleInfo;
 class MachineFunction;
+class MachineInstr;
 class Value;
 class Module;
 class GlobalVariable;
 class TargetAsmInfo;
 class raw_ostream;
+class Instruction;
+class DISubprogram;
+class DIVariable;
 
 //===----------------------------------------------------------------------===//
 // DwarfWriter - Emits Dwarf debug and exception handling directives.
@@ -77,7 +81,7 @@
   void EndFunction(MachineFunction *MF);
 
   /// ValidDebugInfo - Return true if V represents valid debug info value.
-  bool ValidDebugInfo(Value *V);
+  bool ValidDebugInfo(Value *V, bool FastISel);
 
   /// RecordSourceLine - Register a source line with debug info. Returns a
   /// unique label ID used to generate a label and provide correspondence to
@@ -102,11 +106,23 @@
 
   /// RecordVariable - Indicate the declaration of  a local variable.
   ///
-  void RecordVariable(GlobalVariable *GV, unsigned FrameIndex);
+  void RecordVariable(GlobalVariable *GV, unsigned FrameIndex, 
+                      const MachineInstr *MI);
 
   /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
   /// be emitted.
   bool ShouldEmitDwarfDebug() const;
+
+  //// RecordInlinedFnStart - Indicate the start of a inlined function.
+  void RecordInlinedFnStart(Instruction *I, DISubprogram &SP, unsigned LabelID,
+                            unsigned Src, unsigned Line, unsigned Col);
+
+  /// RecordInlinedFnEnd - Indicate the end of inlined subroutine.
+  unsigned RecordInlinedFnEnd(DISubprogram &SP);
+
+  /// RecordVariableScope - Record scope for the variable declared by
+  /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE.
+  void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI);
 };
 
 

Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h Thu Apr 16 18:28:27 2009
@@ -83,6 +83,9 @@
   ///
   void setCurDebugLoc(DebugLoc dl) { DL = dl; }
 
+  /// getCurDebugLoc() - Return current debug location information.
+  DebugLoc getCurDebugLoc() const { return DL; }
+
   /// SelectInstruction - Do "fast" instruction selection for the given
   /// LLVM IR instruction, and append generated machine instructions to
   /// the current block. Return true if selection was successful.

Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h Thu Apr 16 18:28:27 2009
@@ -37,6 +37,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/UniqueVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/CodeGen/MachineLocation.h"
 #include "llvm/GlobalValue.h"
@@ -115,6 +116,9 @@
   // searchable format.
   SmallPtrSet<const Function *, 32> UsedFunctions;
 
+  /// UsedDbgLabels - labels are used by debug info entries.
+  SmallSet<unsigned, 8> UsedDbgLabels;
+
   bool CallsEHReturn;
   bool CallsUnwindInit;
  
@@ -195,6 +199,19 @@
     return LabelID ? LabelIDList[LabelID - 1] : 0;
   }
 
+  /// isDbgLabelUsed - Return true if label with LabelID is used by
+  /// DwarfWriter.
+  bool isDbgLabelUsed(unsigned LabelID) {
+    return UsedDbgLabels.count(LabelID);
+  }
+  
+  /// RecordUsedDbgLabel - Mark label with LabelID as used. This is used
+  /// by DwarfWriter to inform DebugLabelFolder that certain labels are
+  /// not to be deleted.
+  void RecordUsedDbgLabel(unsigned LabelID) {
+    UsedDbgLabels.insert(LabelID);
+  }
+
   /// getFrameMoves - Returns a reference to a list of moves done in the current
   /// function's prologue.  Used to construct frame maps for debug and exception
   /// handling comsumers.

Modified: llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h Thu Apr 16 18:28:27 2009
@@ -459,6 +459,10 @@
     ///
     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
@@ -502,7 +506,11 @@
     /// 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".
@@ -837,6 +845,9 @@
     bool doesDwarfRequireFrameSection() const {
       return DwarfRequiresFrameSection;
     }
+    bool doesDwarfUsesInlineInfoSection() const {
+      return DwarfUsesInlineInfoSection;
+    }
     bool doesSupportMacInfoSection() const {
       return SupportsMacInfoSection;
     }
@@ -870,6 +881,9 @@
     const char *getDwarfPubTypesSection() const {
       return DwarfPubTypesSection;
     }
+    const char *getDwarfDebugInlineSection() const {
+      return DwarfDebugInlineSection;
+    }
     const char *getDwarfStrSection() const {
       return DwarfStrSection;
     }

Modified: llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp Thu Apr 16 18:28:27 2009
@@ -290,6 +290,19 @@
   return BT.getSizeInBits();
 }
 
+/// describes - Return true if this subprogram provides debugging
+/// information for the function F.
+bool DISubprogram::describes(const Function *F) {
+  assert (F && "Invalid function");
+  std::string Name;
+  getLinkageName(Name);
+  if (Name.empty())
+    getName(Name);
+  if (!Name.empty() && (strcmp(Name.c_str(), F->getNameStart()) == false))
+    return true;
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // DIFactory: Basic Helpers
 //===----------------------------------------------------------------------===//

Modified: llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Apr 16 18:28:27 2009
@@ -1534,7 +1534,7 @@
 void AsmPrinter::printDeclare(const MachineInstr *MI) const {
   unsigned FI = MI->getOperand(0).getIndex();
   GlobalValue *GV = MI->getOperand(1).getGlobal();
-  DW->RecordVariable(cast<GlobalVariable>(GV), FI);
+  DW->RecordVariable(cast<GlobalVariable>(GV), FI, MI);
 }
 
 /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM

Modified: llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Thu Apr 16 18:28:27 2009
@@ -1140,7 +1140,7 @@
   DbgScope(DbgScope *P, DIDescriptor D)
   : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), Scopes(), Variables()
   {}
-  ~DbgScope() {
+  virtual ~DbgScope() {
     for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i];
     for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j];
   }
@@ -1162,6 +1162,32 @@
   /// AddVariable - Add a variable to the scope.
   ///
   void AddVariable(DbgVariable *V) { Variables.push_back(V); }
+
+  virtual bool isInlinedSubroutine() { return false; }
+  virtual unsigned getLine()   { assert ( 0 && "Unexpected scope!"); }
+  virtual unsigned getColumn() { assert ( 0 && "Unexpected scope!"); }
+  virtual unsigned getFile()   { assert ( 0 && "Unexpected scope!"); }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// DbgInlinedSubroutineScope - This class is used to track inlined subroutine
+/// scope information.
+///
+class DbgInlinedSubroutineScope : public DbgScope {
+  unsigned Src;
+  unsigned Line;
+  unsigned Col;
+public:
+  DbgInlinedSubroutineScope(DbgScope *P, DIDescriptor D, 
+                            unsigned S, unsigned L, unsigned C)
+    : DbgScope(P, D), Src(S), Line(L), Col(C)
+  {}
+
+  unsigned getLine()         { return Line; }
+  unsigned getColumn()       { return Col; }
+  unsigned getFile()         { return Src; }
+  bool isInlinedSubroutine() { return true; }
 };
 
 //===----------------------------------------------------------------------===//
@@ -1245,13 +1271,24 @@
   ///
   bool shouldEmit;
 
-  // RootDbgScope - Top level scope for the current function.
+  // FunctionDbgScope - Top level scope for the current function.
   //
-  DbgScope *RootDbgScope;
+  DbgScope *FunctionDbgScope;
   
   /// DbgScopeMap - Tracks the scopes in the current function.
   DenseMap<GlobalVariable *, DbgScope *> DbgScopeMap;
 
+  /// DbgInlinedScopeMap - Tracks inlined scopes in the current function.
+  DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> > DbgInlinedScopeMap;
+
+  /// InlineInfo - Keep track of inlined functions and their location.
+  /// This information is used to populate debug_inlined section.
+  DenseMap<GlobalVariable *, SmallVector<unsigned, 4> > InlineInfo;
+
+  /// InlinedVariableScopes - Scopes information for the inlined subroutine
+  /// variables.
+  DenseMap<const MachineInstr *, DbgScope *> InlinedVariableScopes;
+
   /// DebugTimer - Timer for the Dwarf debug writer.
   Timer *DebugTimer;
   
@@ -1465,7 +1502,7 @@
   /// AddDelta - Add a label delta attribute data and value.
   ///
   void AddDelta(DIE *Die, unsigned Attribute, unsigned Form,
-                          const DWLabel &Hi, const DWLabel &Lo) {
+                const DWLabel &Hi, const DWLabel &Lo) {
     FoldingSetNodeID ID;
     DIEDelta::Profile(ID, Hi, Lo);
     void *Where;
@@ -1546,7 +1583,7 @@
   /// AddAddress - Add an address attribute to a die based on the location
   /// provided.
   void AddAddress(DIE *Die, unsigned Attribute,
-                            const MachineLocation &Location) {
+                  const MachineLocation &Location) {
     unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
     DIEBlock *Block = new DIEBlock();
 
@@ -1899,8 +1936,9 @@
     DIArray Args = SPTy.getTypeArray();
     
     // Add Return Type.
+    unsigned SPTag = SPTy.getTag();
     if (!IsConstructor) {
-      if (Args.isNull()) 
+      if (Args.isNull() || SPTag != DW_TAG_subroutine_type)
         AddType(DW_Unit, SPDie, SPTy);
       else
         AddType(DW_Unit, SPDie, DIType(Args.getElement(0).getGV()));
@@ -1911,7 +1949,7 @@
       // Add arguments.
       // Do not add arguments for subprogram definition. They will be
       // handled through RecordVariable.
-      if (!Args.isNull())
+      if (SPTag == DW_TAG_subroutine_type)
         for (unsigned i = 1, N =  Args.getNumElements(); i < N; ++i) {
           DIE *Arg = new DIE(DW_TAG_formal_parameter);
           AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV()));
@@ -1927,6 +1965,10 @@
 
     if (!SP.isLocalToUnit())
       AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);
+    
+    // DW_TAG_inlined_subroutine may refer to this DIE.
+    DIE *&Slot = DW_Unit->getDieMapSlotFor(SP.getGV());
+    Slot = SPDie;
     return SPDie;
   }
 
@@ -1981,33 +2023,39 @@
     DbgScope *&Slot = DbgScopeMap[V];
     if (Slot) return Slot;
 
-    // FIXME - breaks down when the context is an inlined function.
-    DIDescriptor ParentDesc;
-    DIDescriptor Desc(V);
-
-    if (Desc.getTag() == dwarf::DW_TAG_lexical_block) {
-      DIBlock Block(V);
-      ParentDesc = Block.getContext();
+    DbgScope *Parent = NULL;
+    DIBlock Block(V);
+    if (!Block.isNull()) {
+      DIDescriptor ParentDesc = Block.getContext();
+      Parent = 
+        ParentDesc.isNull() ?  NULL : getOrCreateScope(ParentDesc.getGV());
     }
+    Slot = new DbgScope(Parent, DIDescriptor(V));
 
-    DbgScope *Parent = ParentDesc.isNull() ? 
-      NULL : getOrCreateScope(ParentDesc.getGV());
-    Slot = new DbgScope(Parent, Desc);
-
-    if (Parent) {
+    if (Parent)
       Parent->AddScope(Slot);
-    } else if (RootDbgScope) {
-      // FIXME - Add inlined function scopes to the root so we can delete them
-      // later.  Long term, handle inlined functions properly.
-      RootDbgScope->AddScope(Slot);
-    } else {
+    else
       // First function is top level function.
-      RootDbgScope = Slot;
-    }
+      FunctionDbgScope = Slot;
 
     return Slot;
   }
 
+  /// createInlinedSubroutineScope - Returns the scope associated with the 
+  /// inlined subroutine.
+  ///
+  DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src, 
+                                         unsigned Line, unsigned Col) {
+    DbgScope *Scope = 
+      new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col);
+
+    // FIXME - Add inlined function scopes to the root so we can delete them
+    // later.  
+    assert (FunctionDbgScope && "Function scope info missing!");
+    FunctionDbgScope->AddScope(Scope);
+    return Scope;
+  }
+
   /// ConstructDbgScope - Construct the components of a scope.
   ///
   void ConstructDbgScope(DbgScope *ParentScope,
@@ -2025,48 +2073,61 @@
     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.
+      // Ignore empty scopes. 
+      // Do not ignore inlined scope even if it does not have any
+      // variables or scopes.
       if (StartID == EndID && StartID != 0) continue;
-      if (Scope->getScopes().empty() && Scope->getVariables().empty()) continue;
+      if (!Scope->isInlinedSubroutine()
+          && Scope->getScopes().empty() && Scope->getVariables().empty()) 
+        continue;
 
       if (StartID == ParentStartID && EndID == ParentEndID) {
         // Just add stuff to the parent scope.
         ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit);
       } else {
-        DIE *ScopeDie = new DIE(DW_TAG_lexical_block);
-
-        // Add the scope bounds.
-        if (StartID) {
-          AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
-                             DWLabel("label", StartID));
-        } else {
-          AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
-                             DWLabel("func_begin", SubprogramCount));
-        }
-        if (EndID) {
-          AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
-                             DWLabel("label", EndID));
-        } else {
-          AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
-                             DWLabel("func_end", SubprogramCount));
+        DIE *ScopeDie = NULL;
+        if (MainCU && TAI->doesDwarfUsesInlineInfoSection()
+            && Scope->isInlinedSubroutine()) {
+          ScopeDie = new DIE(DW_TAG_inlined_subroutine);
+          DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV());
+          AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin);
+          AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile());
+          AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine());
+          AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn());
         }
-
-        // Add the scope contents.
-        ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit);
-        ParentDie->AddChild(ScopeDie);
+        else
+          ScopeDie = new DIE(DW_TAG_lexical_block);
+          
+          // Add the scope bounds.
+          if (StartID) {
+            AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
+                     DWLabel("label", StartID));
+          } else {
+            AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
+                     DWLabel("func_begin", SubprogramCount));
+          }
+          if (EndID) {
+            AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
+                     DWLabel("label", EndID));
+          } else {
+            AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
+                     DWLabel("func_end", SubprogramCount));
+          }
+          
+          // Add the scope contents.
+          ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit);
+          ParentDie->AddChild(ScopeDie);
       }
     }
   }
 
-  /// ConstructRootDbgScope - Construct the scope for the subprogram.
+  /// ConstructFunctionDbgScope - Construct the scope for the subprogram.
   ///
-  void ConstructRootDbgScope(DbgScope *RootScope) {
+  void ConstructFunctionDbgScope(DbgScope *RootScope) {
     // Exit if there is no root scope.
     if (!RootScope) return;
     DIDescriptor Desc = RootScope->getDesc();
@@ -2779,6 +2840,77 @@
     }
   }
 
+  /// 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
@@ -2987,7 +3119,7 @@
       AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
       ValuesSet(InitValuesSetSize), Values(), StringPool(), SectionMap(),
       SectionSourceLines(), didInitial(false), shouldEmit(false),
-      RootDbgScope(0), DebugTimer(0) {
+      FunctionDbgScope(0), DebugTimer(0) {
     if (TimePassesIsEnabled)
       DebugTimer = new Timer("Dwarf Debug Writer",
                              getDwarfTimerGroup());
@@ -3129,6 +3261,9 @@
     // Emit info into a debug macinfo section.
     EmitDebugMacInfo();
 
+    // Emit inline info.
+    EmitDebugInlineInfo();
+
     if (TimePassesIsEnabled)
       DebugTimer->stopTimer();
   }
@@ -3183,8 +3318,8 @@
     }
 
     // Construct scopes for subprogram.
-    if (RootDbgScope)
-      ConstructRootDbgScope(RootDbgScope);
+    if (FunctionDbgScope)
+      ConstructFunctionDbgScope(FunctionDbgScope);
     else
       // FIXME: This is wrong. We are essentially getting past a problem with
       // debug information not being able to handle unreachable blocks that have
@@ -3200,10 +3335,12 @@
                                                  MMI->getFrameMoves()));
 
     // Clear debug info
-    if (RootDbgScope) {
-      delete RootDbgScope;
+    if (FunctionDbgScope) {
+      delete FunctionDbgScope;
       DbgScopeMap.clear();
-      RootDbgScope = NULL;
+      DbgInlinedScopeMap.clear();
+      InlinedVariableScopes.clear();
+      FunctionDbgScope = NULL;
     }
 
     Lines.clear();
@@ -3213,7 +3350,7 @@
   }
 
   /// ValidDebugInfo - Return true if V represents valid debug info value.
-  bool ValidDebugInfo(Value *V) {
+  bool ValidDebugInfo(Value *V, bool FastISel) {
     if (!V)
       return false;
 
@@ -3252,6 +3389,11 @@
     case DW_TAG_subprogram:
       assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value");
       break;
+    case DW_TAG_lexical_block:
+      /// FIXME. This interfers with the qualitfy of generated code when 
+      /// during optimization.
+      if (FastISel == false)
+        return false;
     default:
       break;
     }
@@ -3351,7 +3493,8 @@
   }
 
   /// RecordVariable - Indicate the declaration of  a local variable.
-  void RecordVariable(GlobalVariable *GV, unsigned FrameIndex) {
+  void RecordVariable(GlobalVariable *GV, unsigned FrameIndex,
+                      const MachineInstr *MI) {
     if (TimePassesIsEnabled)
       DebugTimer->startTimer();
 
@@ -3363,9 +3506,16 @@
       DIGlobalVariable DG(GV);
       Scope = getOrCreateScope(DG.getContext().getGV());
     } else {
+      DenseMap<const MachineInstr *, DbgScope *>::iterator 
+        SI = InlinedVariableScopes.find(MI);
+      if (SI != InlinedVariableScopes.end())  {
+        // or GV is an inlined local variable.
+        Scope = SI->second;
+      } else {
       // or GV is a local variable.
-      DIVariable DV(GV);
-      Scope = getOrCreateScope(DV.getContext().getGV());
+        DIVariable DV(GV);
+        Scope = getOrCreateScope(DV.getContext().getGV());
+      }
     }
 
     assert(Scope && "Unable to find variable' scope");
@@ -3375,6 +3525,78 @@
     if (TimePassesIsEnabled)
       DebugTimer->stopTimer();
   }
+
+  //// RecordInlinedFnStart - Indicate the start of inlined subroutine.
+  void RecordInlinedFnStart(Instruction *FSI, DISubprogram &SP, unsigned LabelID,
+                            unsigned Src, unsigned Line, unsigned Col) {
+    if (!TAI->doesDwarfUsesInlineInfoSection())
+      return;
+
+    DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col);
+    Scope->setStartLabelID(LabelID);
+    MMI->RecordUsedDbgLabel(LabelID);
+    GlobalVariable *GV = SP.getGV();
+
+    DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> >::iterator
+      SI = DbgInlinedScopeMap.find(GV);
+    if (SI == DbgInlinedScopeMap.end()) {
+      SmallVector<DbgScope *, 2> Scopes;
+      Scopes.push_back(Scope);
+      DbgInlinedScopeMap[GV] = Scopes;
+    } else {
+      SmallVector<DbgScope *, 2> &Scopes = SI->second;
+      Scopes.push_back(Scope);
+    }
+
+    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);
+  }
+
+  /// RecordInlinedFnEnd - Indicate the end of inlined subroutine.
+  unsigned RecordInlinedFnEnd(DISubprogram &SP) {
+    if (!TAI->doesDwarfUsesInlineInfoSection())
+      return 0;
+
+    GlobalVariable *GV = SP.getGV();
+    DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> >::iterator
+      I = DbgInlinedScopeMap.find(GV);
+    if (I == DbgInlinedScopeMap.end()) 
+      return 0;
+
+    SmallVector<DbgScope *, 2> &Scopes = I->second;
+    DbgScope *Scope = Scopes.back(); Scopes.pop_back();
+    unsigned ID = MMI->NextLabelID();
+    MMI->RecordUsedDbgLabel(ID);
+    Scope->setEndLabelID(ID);
+    return ID;
+  }
+
+  /// RecordVariableScope - Record scope for the variable declared by
+  /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE.
+  /// Record scopes for only inlined subroutine variables. Other
+  /// variables' scopes are determined during RecordVariable().
+  void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI) {
+    DISubprogram SP(DV.getContext().getGV());
+    if (SP.isNull())
+      return;
+    DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> >::iterator
+      I = DbgInlinedScopeMap.find(SP.getGV());
+    if (I == DbgInlinedScopeMap.end())
+      return;
+
+    SmallVector<DbgScope *, 2> &Scopes = I->second;
+    InlinedVariableScopes[DeclareMI] = Scopes.back();
+  }
+
 };
 
 //===----------------------------------------------------------------------===//
@@ -4504,8 +4726,8 @@
 }
 
 /// ValidDebugInfo - Return true if V represents valid debug info value.
-bool DwarfWriter::ValidDebugInfo(Value *V) {
-  return DD && DD->ValidDebugInfo(V);
+bool DwarfWriter::ValidDebugInfo(Value *V, bool FastISel) {
+  return DD && DD->ValidDebugInfo(V, FastISel);
 }
 
 /// RecordSourceLine - Records location information and associates it with a 
@@ -4542,8 +4764,9 @@
 
 /// RecordVariable - Indicate the declaration of  a local variable.
 ///
-void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex) {
-  DD->RecordVariable(GV, FrameIndex);
+void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex,
+                                 const MachineInstr *MI) {
+  DD->RecordVariable(GV, FrameIndex, MI);
 }
 
 /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
@@ -4551,3 +4774,23 @@
 bool DwarfWriter::ShouldEmitDwarfDebug() const {
   return DD->ShouldEmitDwarfDebug();
 }
+
+//// RecordInlinedFnStart - Global variable GV is inlined at the location marked
+//// by LabelID label.
+void DwarfWriter::RecordInlinedFnStart(Instruction *I, DISubprogram &SP, 
+                                       unsigned LabelID, unsigned Src, 
+                                       unsigned Line, unsigned Col) {
+  DD->RecordInlinedFnStart(I, SP, LabelID, Src, Line, Col);
+}
+
+/// RecordInlinedFnEnd - Indicate the end of inlined subroutine.
+unsigned DwarfWriter::RecordInlinedFnEnd(DISubprogram &SP) {
+  return DD->RecordInlinedFnEnd(SP);
+}
+
+/// RecordVariableScope - Record scope for the variable declared by
+/// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE.
+void DwarfWriter::RecordVariableScope(DIVariable &DV,
+                                      const MachineInstr *DeclareMI) {
+  DD->RecordVariableScope(DV, DeclareMI);
+}

Modified: llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp Thu Apr 16 18:28:27 2009
@@ -333,7 +333,7 @@
     // Iterate through instructions.
     for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
       // Is it a label.
-      if (I->isDebugLabel()) {
+      if (I->isDebugLabel() && !MMI->isDbgLabelUsed(I->getOperand(0).getImm())){
         // The label ID # is always operand #0, an immediate.
         unsigned NextLabel = I->getOperand(0).getImm();
         

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Apr 16 18:28:27 2009
@@ -47,6 +47,7 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/DebugLoc.h"
 #include "llvm/CodeGen/DwarfWriter.h"
 #include "llvm/Analysis/DebugInfo.h"
 #include "llvm/Target/TargetData.h"
@@ -322,7 +323,7 @@
   default: break;
   case Intrinsic::dbg_stoppoint: {
     DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
-    if (DW && DW->ValidDebugInfo(SPI->getContext())) {
+    if (DW && DW->ValidDebugInfo(SPI->getContext(), true)) {
       DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
       std::string Dir, FN;
       unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(Dir),
@@ -339,7 +340,7 @@
   }
   case Intrinsic::dbg_region_start: {
     DbgRegionStartInst *RSI = cast<DbgRegionStartInst>(I);
-    if (DW && DW->ValidDebugInfo(RSI->getContext())) {
+    if (DW && DW->ValidDebugInfo(RSI->getContext(), true)) {
       unsigned ID = 
         DW->RecordRegionStart(cast<GlobalVariable>(RSI->getContext()));
       const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
@@ -349,11 +350,24 @@
   }
   case Intrinsic::dbg_region_end: {
     DbgRegionEndInst *REI = cast<DbgRegionEndInst>(I);
-    if (DW && DW->ValidDebugInfo(REI->getContext())) {
-      unsigned ID = 
-        DW->RecordRegionEnd(cast<GlobalVariable>(REI->getContext()));
-      const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
-      BuildMI(MBB, DL, II).addImm(ID);
+    if (DW && DW->ValidDebugInfo(REI->getContext(), true)) {
+     unsigned ID = 0;
+     DISubprogram Subprogram(cast<GlobalVariable>(REI->getContext()));
+     if (!Subprogram.isNull() && !Subprogram.describes(MF.getFunction())) {
+        // This is end of an inlined function.
+        const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
+        ID = DW->RecordInlinedFnEnd(Subprogram);
+        if (ID)
+          // Returned ID is 0 if this is unbalanced "end of inlined
+          // scope". This could happen if optimizer eats dbg intrinsics
+          // or "beginning of inlined scope" is not recoginized due to
+          // missing location info. In such cases, do ignore this region.end.
+          BuildMI(MBB, DL, II).addImm(ID);
+      } else {
+        const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
+        ID =  DW->RecordRegionEnd(cast<GlobalVariable>(REI->getContext()));
+        BuildMI(MBB, DL, II).addImm(ID);
+      }
     }
     return true;
   }
@@ -362,25 +376,43 @@
     DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
     Value *SP = FSI->getSubprogram();
 
-    if (DW->ValidDebugInfo(SP)) {
+    if (DW->ValidDebugInfo(SP, true)) {
       // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
       // (most?) gdb expects.
+      DebugLoc PrevLoc = DL;
       DISubprogram Subprogram(cast<GlobalVariable>(SP));
       DICompileUnit CompileUnit = Subprogram.getCompileUnit();
       std::string Dir, FN;
       unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
                                                  CompileUnit.getFilename(FN));
 
-      // Record the source line but does not create a label for the normal
-      // function start. It will be emitted at asm emission time. However,
-      // create a label if this is a beginning of inlined function.
-      unsigned Line = Subprogram.getLineNumber();
-      unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
-      setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+      if (!Subprogram.describes(MF.getFunction())) {
+        // This is a beginning of an inlined function.
+        
+        // If llvm.dbg.func.start is seen in a new block before any
+        // llvm.dbg.stoppoint intrinsic then the location info is unknown.
+        // FIXME : Why DebugLoc is reset at the beginning of each block ?
+        if (PrevLoc.isUnknown())
+          return true;
+        // Record the source line.
+        unsigned Line = Subprogram.getLineNumber();
+        unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
+        setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
 
-      if (DW->getRecordSourceLineCount() != 1) {
         const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
         BuildMI(MBB, DL, II).addImm(LabelID);
+        DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
+        DW->RecordInlinedFnStart(FSI, Subprogram, LabelID, 
+                                 PrevLocTpl.Src,
+                                 PrevLocTpl.Line,
+                                 PrevLocTpl.Col);
+      } else {
+        // Record the source line.
+        unsigned Line = Subprogram.getLineNumber();
+        setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+        DW->RecordSourceLine(Line, 0, SrcFile);
+        // llvm.dbg.func_start also defines beginning of function scope.
+        DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
       }
     }
 
@@ -389,7 +421,7 @@
   case Intrinsic::dbg_declare: {
     DbgDeclareInst *DI = cast<DbgDeclareInst>(I);
     Value *Variable = DI->getVariable();
-    if (DW && DW->ValidDebugInfo(Variable)) {
+    if (DW && DW->ValidDebugInfo(Variable, true)) {
       // Determine the address of the declared object.
       Value *Address = DI->getAddress();
       if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
@@ -407,7 +439,13 @@
 
       // Build the DECLARE instruction.
       const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE);
-      BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV);
+      MachineInstr *DeclareMI 
+        = BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV);
+      DIVariable DV(cast<GlobalVariable>(GV));
+      if (!DV.isNull()) {
+        // This is a local variable
+        DW->RecordVariableScope(DV, DeclareMI);
+      }
     }
     return true;
   }

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Apr 16 18:28:27 2009
@@ -332,7 +332,7 @@
             DwarfWriter *DW = DAG.getDwarfWriter();
             DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
 
-            if (DW && DW->ValidDebugInfo(SPI->getContext())) {
+            if (DW && DW->ValidDebugInfo(SPI->getContext(), false)) {
               DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
               std::string Dir, FN;
               unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(Dir),
@@ -351,7 +351,7 @@
               DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
               Value *SP = FSI->getSubprogram();
 
-              if (DW->ValidDebugInfo(SP)) {
+              if (DW->ValidDebugInfo(SP, false)) {
                 DISubprogram Subprogram(cast<GlobalVariable>(SP));
                 DICompileUnit CU(Subprogram.getCompileUnit());
                 std::string Dir, FN;
@@ -3929,7 +3929,7 @@
   case Intrinsic::dbg_stoppoint: {
     DwarfWriter *DW = DAG.getDwarfWriter();
     DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
-    if (DW && DW->ValidDebugInfo(SPI.getContext())) {
+    if (DW && DW->ValidDebugInfo(SPI.getContext(), Fast)) {
       MachineFunction &MF = DAG.getMachineFunction();
       if (Fast)
         DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
@@ -3949,12 +3949,11 @@
   case Intrinsic::dbg_region_start: {
     DwarfWriter *DW = DAG.getDwarfWriter();
     DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
-    if (DW && DW->ValidDebugInfo(RSI.getContext())) {
+    if (DW && DW->ValidDebugInfo(RSI.getContext(), Fast)) {
       unsigned LabelID =
         DW->RecordRegionStart(cast<GlobalVariable>(RSI.getContext()));
-      if (Fast)
-        DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
-                                 getRoot(), LabelID));
+      DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
+                               getRoot(), LabelID));
     }
 
     return 0;
@@ -3962,12 +3961,33 @@
   case Intrinsic::dbg_region_end: {
     DwarfWriter *DW = DAG.getDwarfWriter();
     DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
-    if (DW && DW->ValidDebugInfo(REI.getContext())) {
+    if (DW && DW->ValidDebugInfo(REI.getContext(), Fast)) {
+
+      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).
+        if (Fast) {
+          unsigned ID = DW->RecordInlinedFnEnd(Subprogram);
+          if (ID != 0)
+            // Returned ID is 0 if this is unbalanced "end of inlined
+            // scope". This could happen if optimizer eats dbg intrinsics
+            // or "beginning of inlined scope" is not recoginized due to
+            // missing location info. In such cases, do ignore this region.end.
+            DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(), 
+                                     getRoot(), ID));
+        }
+        return 0;
+      }
+
       unsigned LabelID =
         DW->RecordRegionEnd(cast<GlobalVariable>(REI.getContext()));
-      if (Fast)
-        DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
-                                 getRoot(), LabelID));
+      DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
+                               getRoot(), LabelID));
     }
 
     return 0;
@@ -3977,29 +3997,74 @@
     if (!DW) return 0;
     DbgFuncStartInst &FSI = cast<DbgFuncStartInst>(I);
     Value *SP = FSI.getSubprogram();
-    if (SP && DW->ValidDebugInfo(SP)) {
-      // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
-      // what (most?) gdb expects.
-      MachineFunction &MF = DAG.getMachineFunction();
-      DISubprogram Subprogram(cast<GlobalVariable>(SP));
-      DICompileUnit CompileUnit = Subprogram.getCompileUnit();
-      std::string Dir, FN;
-      unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
-                                                 CompileUnit.getFilename(FN));
-
-      // Record the source line but does not create a label for the normal
-      // function start. It will be emitted at asm emission time. However,
-      // create a label if this is a beginning of inlined function.
-      unsigned Line = Subprogram.getLineNumber();
-
+    if (SP && DW->ValidDebugInfo(SP, Fast)) {
+        MachineFunction &MF = DAG.getMachineFunction();
       if (Fast) {
-        unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
-        if (DW->getRecordSourceLineCount() != 1)
+        // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
+        // (most?) gdb expects.
+        DebugLoc PrevLoc = CurDebugLoc;
+        DISubprogram Subprogram(cast<GlobalVariable>(SP));
+        DICompileUnit CompileUnit = Subprogram.getCompileUnit();
+        std::string Dir, FN;
+        unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
+                                                   CompileUnit.getFilename(FN));
+        
+        if (!Subprogram.describes(MF.getFunction())) {
+          // This is a beginning of an inlined function.
+
+          // If llvm.dbg.func.start is seen in a new block before any
+          // llvm.dbg.stoppoint intrinsic then the location info is unknown.
+          // FIXME : Why DebugLoc is reset at the beginning of each block ?
+          if (PrevLoc.isUnknown())
+            return 0;
+
+          // Record the source line.
+          unsigned Line = Subprogram.getLineNumber();
+          unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
+          setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+
           DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
                                    getRoot(), LabelID));
-      }
+          DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
+          DW->RecordInlinedFnStart(&FSI, Subprogram, LabelID, 
+                                   PrevLocTpl.Src,
+                                   PrevLocTpl.Line,
+                                   PrevLocTpl.Col);
+        } else {
+          // Record the source line.
+          unsigned Line = Subprogram.getLineNumber();
+          setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+          DW->RecordSourceLine(Line, 0, SrcFile);
+          // llvm.dbg.func_start also defines beginning of function scope.
+          DW->RecordRegionStart(cast<GlobalVariable>(FSI.getSubprogram()));
+        }
+      } else {
+        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;
+        }
 
-      setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+        // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
+        // what (most?) gdb expects.
+        DICompileUnit CompileUnit = Subprogram.getCompileUnit();
+        std::string Dir, FN;
+        unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
+                                                   CompileUnit.getFilename(FN));
+        
+        // Record the source line but does not create a label for the normal
+        // function start. It will be emitted at asm emission time. However,
+        // create a label if this is a beginning of inlined function.
+        unsigned Line = Subprogram.getLineNumber();
+        setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+        // FIXME -  Start new region because llvm.dbg.func_start also defines 
+        // beginning of function scope.
+      }
     }
 
     return 0;
@@ -4009,7 +4074,7 @@
       DwarfWriter *DW = DAG.getDwarfWriter();
       DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
       Value *Variable = DI.getVariable();
-      if (DW && DW->ValidDebugInfo(Variable))
+      if (DW && DW->ValidDebugInfo(Variable, Fast))
         DAG.setRoot(DAG.getNode(ISD::DECLARE, dl, MVT::Other, getRoot(),
                                 getValue(DI.getAddress()), getValue(Variable)));
     } else {

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Thu Apr 16 18:28:27 2009
@@ -392,6 +392,7 @@
   SDValue getControlRoot();
 
   DebugLoc getCurDebugLoc() const { return CurDebugLoc; }
+  void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; }
 
   void CopyValueToVirtualRegister(Value *V, unsigned Reg);
 
@@ -542,8 +543,6 @@
   
   const char *implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op);
   const char *implVisitAluOverflow(CallInst &I, ISD::NodeType Op);
-
-  void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; }
 };
 
 /// AddCatchInfo - Extract the personality and type infos from an eh.selector

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Apr 16 18:28:27 2009
@@ -824,6 +824,7 @@
               R = FuncInfo->CreateRegForValue(BI);
           }
 
+          SDL->setCurDebugLoc(FastIS->getCurDebugLoc());
           SelectBasicBlock(LLVMBB, BI, next(BI));
           // If the instruction was codegen'd with multiple blocks,
           // inform the FastISel object where to resume inserting.
@@ -850,8 +851,12 @@
     // Run SelectionDAG instruction selection on the remainder of the block
     // not handled by FastISel. If FastISel is not run, this is the entire
     // block.
-    if (BI != End)
+    if (BI != End) {
+      // If FastISel is run and it has known DebugLoc then use it.
+      if (FastIS && !FastIS->getCurDebugLoc().isUnknown())
+        SDL->setCurDebugLoc(FastIS->getCurDebugLoc());
       SelectBasicBlock(LLVMBB, BI, End);
+    }
 
     FinishBasicBlock();
   }

Modified: llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp Thu Apr 16 18:28:27 2009
@@ -100,6 +100,7 @@
   SupportsDebugInformation = false;
   SupportsExceptionHandling = false;
   DwarfRequiresFrameSection = true;
+  DwarfUsesInlineInfoSection = false;
   SupportsMacInfoSection = true;
   NonLocalEHFrameLabel = false;
   GlobalEHDirective = 0;
@@ -111,6 +112,7 @@
   DwarfFrameSection = ".debug_frame";
   DwarfPubNamesSection = ".debug_pubnames";
   DwarfPubTypesSection = ".debug_pubtypes";
+  DwarfDebugInlineSection = ".debug_inlined";
   DwarfStrSection = ".debug_str";
   DwarfLocSection = ".debug_loc";
   DwarfARangesSection = ".debug_aranges";

Modified: llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp Thu Apr 16 18:28:27 2009
@@ -112,6 +112,8 @@
   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";

Modified: llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp Thu Apr 16 18:28:27 2009
@@ -24,6 +24,7 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Transforms/Utils/ValueMapper.h"
 #include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Analysis/DebugInfo.h"
 #include "llvm/ADT/SmallVector.h"
 #include <map>
 using namespace llvm;
@@ -233,10 +234,13 @@
       continue;
     }
 
-    // Do not clone llvm.dbg.func.start and corresponding llvm.dbg.region.end.
+    // Do not clone llvm.dbg.region.end. It will be adjusted by the inliner.
     if (const DbgFuncStartInst *DFSI = dyn_cast<DbgFuncStartInst>(II)) {
-      DbgFnStart = DFSI->getSubprogram();
-      continue;
+      if (DbgFnStart == NULL) {
+        DISubprogram SP(cast<GlobalVariable>(DFSI->getSubprogram()));
+        if (SP.describes(BB->getParent()))
+          DbgFnStart = DFSI->getSubprogram();
+      }
     } 
     if (const DbgRegionEndInst *DREIS = dyn_cast<DbgRegionEndInst>(II)) {
       if (DREIS->getContext() == DbgFnStart)

Modified: llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp?rev=69323&r1=69322&r2=69323&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp Thu Apr 16 18:28:27 2009
@@ -17,9 +17,11 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/Attributes.h"
 #include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/DebugInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
@@ -182,6 +184,31 @@
   CallerNode->removeCallEdgeFor(CS);
 }
 
+/// findFnRegionEndMarker - This is a utility routine that is used by
+/// InlineFunction. Return llvm.dbg.region.end intrinsic that corresponds
+/// to the llvm.dbg.func.start of the function F. Otherwise return NULL.
+static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) {
+
+  GlobalVariable *FnStart = NULL;
+  const DbgRegionEndInst *FnEnd = NULL;
+  for (Function::const_iterator FI = F->begin(), FE =F->end(); FI != FE; ++FI) 
+    for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end(); BI != BE;
+         ++BI) {
+      if (FnStart == NULL)  {
+        if (const DbgFuncStartInst *FSI = dyn_cast<DbgFuncStartInst>(BI)) {
+          DISubprogram SP(cast<GlobalVariable>(FSI->getSubprogram()));
+          assert (SP.isNull() == false && "Invalid llvm.dbg.func.start");
+          if (SP.describes(F))
+            FnStart = SP.getGV();
+        }
+      } else {
+        if (const DbgRegionEndInst *REI = dyn_cast<DbgRegionEndInst>(BI))
+          if (REI->getContext() == FnStart)
+            FnEnd = REI;
+      }
+    }
+  return FnEnd;
+}
 
 // InlineFunction - This function inlines the called function into the basic
 // block of the caller.  This returns false if it is not possible to inline this
@@ -303,6 +330,24 @@
       ValueMap[I] = ActualArg;
     }
 
+    // Adjust llvm.dbg.region.end. If the CalledFunc has region end
+    // marker then clone that marker after next stop point at the 
+    // call site. The function body cloner does not clone original
+    // region end marker from the CalledFunc. This will ensure that
+    // inlined function's scope ends at the right place. 
+    const DbgRegionEndInst *DREI = findFnRegionEndMarker(CalledFunc);
+    if (DREI) {
+      for (BasicBlock::iterator BI = TheCall, 
+             BE = TheCall->getParent()->end(); BI != BE; ++BI) {
+        if (DbgStopPointInst *DSPI = dyn_cast<DbgStopPointInst>(BI)) {
+          if (DbgRegionEndInst *NewDREI = 
+              dyn_cast<DbgRegionEndInst>(DREI->clone()))
+            NewDREI->insertAfter(DSPI);
+          break;
+        }
+      }
+    }
+
     // We want the inliner to prune the code as it copies.  We would LOVE to
     // have no dead or constant instructions leftover after inlining occurs
     // (which can happen, e.g., because an argument was constant), but we'll be

Removed: llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll?rev=69322&view=auto

==============================================================================
--- llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll (original)
+++ llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll (removed)
@@ -1,86 +0,0 @@
-; RUN: llvm-as < %s | opt -inline | llvm-dis | grep func.start | count 3
-; RUN: llvm-as < %s | opt -inline | llvm-dis | grep region.end | count 3
-	%llvm.dbg.anchor.type = type { i32, i32 }
-	%llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
-	%llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
-	%llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
-	%llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
-	%llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
-	%llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
- at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"		; <%llvm.dbg.anchor.type*> [#uses=1]
- at .str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata"		; <[4 x i8]*> [#uses=1]
- at .str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata"		; <[6 x i8]*> [#uses=1]
- at .str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata"		; <[55 x i8]*> [#uses=1]
- at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata"		; <%llvm.dbg.compile_unit.type*> [#uses=1]
- at .str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata"		; <[4 x i8]*> [#uses=1]
- at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata"		; <%llvm.dbg.basictype.type*> [#uses=1]
- at .str4 = internal constant [5 x i8] c"char\00", section "llvm.metadata"		; <[5 x i8]*> [#uses=1]
- at llvm.dbg.basictype5 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 6 }, section "llvm.metadata"		; <%llvm.dbg.basictype.type*> [#uses=1]
- at llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to { }*) }, section "llvm.metadata"		; <%llvm.dbg.derivedtype.type*> [#uses=1]
- at llvm.dbg.array = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) ], section "llvm.metadata"		; <[2 x { }*]*> [#uses=1]
- at llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata"		; <%llvm.dbg.composite.type*> [#uses=1]
- at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata"		; <%llvm.dbg.anchor.type*> [#uses=1]
- at .str6 = internal constant [4 x i8] c"bar\00", section "llvm.metadata"		; <[4 x i8]*> [#uses=1]
- at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata"		; <%llvm.dbg.subprogram.type*> [#uses=1]
- at .str7 = internal constant [2 x i8] c"c\00", section "llvm.metadata"		; <[2 x i8]*> [#uses=1]
- at llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str7, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) }, section "llvm.metadata"		; <%llvm.dbg.variable.type*> [#uses=1]
- at llvm.dbg.array8 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata"		; <[1 x { }*]*> [#uses=1]
- at llvm.dbg.composite9 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array8 to { }*) }, section "llvm.metadata"		; <%llvm.dbg.composite.type*> [#uses=1]
- at .str10 = internal constant [5 x i8] c"main\00", section "llvm.metadata"		; <[5 x i8]*> [#uses=1]
- at llvm.dbg.subprogram11 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str10, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite9 to { }*), i1 false, i1 true }, section "llvm.metadata"		; <%llvm.dbg.subprogram.type*> [#uses=1]
-@"\01LC" = internal constant [3 x i8] c"hi\00"		; <[3 x i8]*> [#uses=1]
-
-define i32 @bar(i8* %c) nounwind {
-entry:
-	%c_addr = alloca i8*		; <i8**> [#uses=3]
-	%retval = alloca i32		; <i32*> [#uses=2]
-	%0 = alloca i32		; <i32*> [#uses=2]
-	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
-	call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
-	%1 = bitcast i8** %c_addr to { }*		; <{ }*> [#uses=1]
-	call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*))
-	store i8* %c, i8** %c_addr
-	call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
-	%2 = load i8** %c_addr, align 4		; <i8*> [#uses=1]
-	%3 = load i8* %2, align 1		; <i8> [#uses=1]
-	%4 = sext i8 %3 to i32		; <i32> [#uses=1]
-	%5 = add i32 %4, 42		; <i32> [#uses=1]
-	store i32 %5, i32* %0, align 4
-	%6 = load i32* %0, align 4		; <i32> [#uses=1]
-	store i32 %6, i32* %retval, align 4
-	br label %return
-
-return:		; preds = %entry
-	%retval1 = load i32* %retval		; <i32> [#uses=1]
-	call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
-	call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
-	ret i32 %retval1
-}
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.declare({ }*, { }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @llvm.dbg.region.end({ }*) nounwind
-
-define i32 @main() nounwind {
-entry:
-	%retval = alloca i32		; <i32*> [#uses=2]
-	%0 = alloca i32		; <i32*> [#uses=2]
-	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
-	call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram11 to { }*))
-	call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
-	%1 = call i32 @bar(i8* getelementptr ([3 x i8]* @"\01LC", i32 0, i32 0)) nounwind		; <i32> [#uses=1]
-	store i32 %1, i32* %0, align 4
-	%2 = load i32* %0, align 4		; <i32> [#uses=1]
-	store i32 %2, i32* %retval, align 4
-	br label %return
-
-return:		; preds = %entry
-	%retval1 = load i32* %retval		; <i32> [#uses=1]
-	call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
-	call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram11 to { }*))
-	ret i32 %retval1
-}





More information about the llvm-branch-commits mailing list