[llvm-branch-commits] [llvm-branch] r104854 - in /llvm/branches/Apple/Morbo: ./ include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DIE.h lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/ARM/ARMInstrFormats.td test/CodeGen/X86/2010-05-26-DotDebugLoc.ll test/DebugInfo/2010-05-25-DotDebugLoc.ll test/DebugInfo/2010-05-28-Crash.ll

Devang Patel dpatel at apple.com
Thu May 27 10:28:49 PDT 2010


Author: dpatel
Date: Thu May 27 12:28:49 2010
New Revision: 104854

URL: http://llvm.org/viewvc/llvm-project?rev=104854&view=rev
Log:
merge .debug_loc support from trunk.
Radar 7975461.

r104233,104265,104274,104302,104338,104412,104524,104649,104705-104706,104720,104732,104740,104785,104848


Added:
    llvm/branches/Apple/Morbo/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll
      - copied, changed from r104732, llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll
    llvm/branches/Apple/Morbo/test/DebugInfo/2010-05-25-DotDebugLoc.ll
      - copied, changed from r104649, llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll
    llvm/branches/Apple/Morbo/test/DebugInfo/2010-05-28-Crash.ll
      - copied unchanged from r104848, llvm/trunk/test/DebugInfo/2010-05-28-Crash.ll
Modified:
    llvm/branches/Apple/Morbo/   (props changed)
    llvm/branches/Apple/Morbo/include/llvm/Analysis/DebugInfo.h
    llvm/branches/Apple/Morbo/lib/Analysis/DebugInfo.cpp
    llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DIE.h
    llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.h
    llvm/branches/Apple/Morbo/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/branches/Apple/Morbo/lib/Target/ARM/ARMInstrFormats.td   (props changed)

Propchange: llvm/branches/Apple/Morbo/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu May 27 12:28:49 2010
@@ -1,3 +1,3 @@
 /llvm/branches/Apple/Hermes:96832,96835,96858,96870,96876,96879,104427
-/llvm/trunk:98602,98604,98612,98615-98616,98675,98686,98743-98744,98768,98773,98778,98780,98810,98835,98839,98845,98855,98862,98881,98920,98977,98980,99032-99033,99043,99196,99223,99263,99282-99284,99306,99319-99321,99324,99336,99378,99418,99423,99429,99440,99455,99463,99465,99469,99484,99490,99492-99494,99507,99524,99537,99539-99540,99544,99570,99575,99598,99620,99629-99630,99636,99671,99692,99695,99697,99699,99722,99816,99835-99836,99845-99846,99848,99850,99855,99879,99881-99883,99895,99899,99910,99916,99919,99952-99954,99957,99959,99974-99975,99982,99984-99986,99988-99989,99992-99993,99995,99997-99999,100016,100035,100037-100038,100042,100044,100056,100072,100074,100078,100081-100090,100092,100094-100095,100116,100134,100184,100209,100214-100218,100220-100221,100223-100225,100231,100250,100252,100257,100261,100304,100332,100353,100384,100454-100455,100457,100466,100478,100480,100487,100494,100497,100505,100521,100553,100568,100584,100592,100609-100610,100636,100710,100736
 ,100742,100751,100768-100769,100771,100781,100797,100804,100837,100867,100892,100936-100937,101011,101023,101075,101077,101079,101081,101085,101154,101158,101162,101165,101181,101190,101202,101282,101294,101303,101314-101315,101317,101331,101343,101383,101392,101420,101453,101604,101615,101629,101684-101686,101805,101845,101847,101851,101855,101870,101879,101897,101925,101930,101965,101971,101979,102111,102120,102192,102202,102225,102236-102237,102358,102366,102394,102396,102405,102421,102454-102456,102463,102467-102468,102470,102481,102486-102488,102492-102493,102504-102505,102508-102510,102513,102519,102524,102526,102531,102558,102646,102653,102655,102661-102662,102672,102743,102760,102770,102791,102948,102970,102980,103001,103133,103233,103314,103356,103415,103419,103439,103451,103455,103459,103798,103801-103802,103804,103808,103813,103824,103829,103990,103995,104066,104182,104236,104419,104531,104640,104646,104655-104656,104661,104664,104722,104737
+/llvm/trunk:98602,98604,98612,98615-98616,98675,98686,98743-98744,98768,98773,98778,98780,98810,98835,98839,98845,98855,98862,98881,98920,98977,98980,99032-99033,99043,99196,99223,99263,99282-99284,99306,99319-99321,99324,99336,99378,99418,99423,99429,99440,99455,99463,99465,99469,99484,99490,99492-99494,99507,99524,99537,99539-99540,99544,99570,99575,99598,99620,99629-99630,99636,99671,99692,99695,99697,99699,99722,99816,99835-99836,99845-99846,99848,99850,99855,99879,99881-99883,99895,99899,99910,99916,99919,99952-99954,99957,99959,99974-99975,99982,99984-99986,99988-99989,99992-99993,99995,99997-99999,100016,100035,100037-100038,100042,100044,100056,100072,100074,100078,100081-100090,100092,100094-100095,100116,100134,100184,100209,100214-100218,100220-100221,100223-100225,100231,100250,100252,100257,100261,100304,100332,100353,100384,100454-100455,100457,100466,100478,100480,100487,100494,100497,100505,100521,100553,100568,100584,100592,100609-100610,100636,100710,100736
 ,100742,100751,100768-100769,100771,100781,100797,100804,100837,100867,100892,100936-100937,101011,101023,101075,101077,101079,101081,101085,101154,101158,101162,101165,101181,101190,101202,101282,101294,101303,101314-101315,101317,101331,101343,101383,101392,101420,101453,101604,101615,101629,101684-101686,101805,101845,101847,101851,101855,101870,101879,101897,101925,101930,101965,101971,101979,102111,102120,102192,102202,102225,102236-102237,102358,102366,102394,102396,102405,102421,102454-102456,102463,102467-102468,102470,102481,102486-102488,102492-102493,102504-102505,102508-102510,102513,102519,102524,102526,102531,102558,102646,102653,102655,102661-102662,102672,102743,102760,102770,102791,102948,102970,102980,103001,103133,103233,103314,103356,103415,103419,103439,103451,103455,103459,103798,103801-103802,103804,103808,103813,103824,103829,103990,103995,104066,104182,104233,104236,104265,104274,104302,104338,104412,104419,104524,104531,104640,104646,104649,104655-1
 04656,104661,104664,104705-104706,104720,104722,104732,104737,104740,104785,104848
 /llvm-gcc-4.2/trunk:104182

Modified: llvm/branches/Apple/Morbo/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/include/llvm/Analysis/DebugInfo.h?rev=104854&r1=104853&r2=104854&view=diff
==============================================================================
--- llvm/branches/Apple/Morbo/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/branches/Apple/Morbo/include/llvm/Analysis/DebugInfo.h Thu May 27 12:28:49 2010
@@ -663,7 +663,7 @@
     DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
                               StringRef Name,
                               DIFile F, unsigned LineNo,
-                              DIType Ty, bool OptimizedBuild = false);
+                              DIType Ty, bool AlwaysPreserve = false);
 
     /// CreateComplexVariable - Create a new descriptor for the specified
     /// variable which has a complex address expression for its address.

Modified: llvm/branches/Apple/Morbo/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/lib/Analysis/DebugInfo.cpp?rev=104854&r1=104853&r2=104854&view=diff
==============================================================================
--- llvm/branches/Apple/Morbo/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/branches/Apple/Morbo/lib/Analysis/DebugInfo.cpp Thu May 27 12:28:49 2010
@@ -1010,7 +1010,7 @@
                                      StringRef Name,
                                      DIFile F,
                                      unsigned LineNo,
-                                     DIType Ty, bool OptimizedBuild) {
+                                     DIType Ty, bool AlwaysPreserve) {
   Value *Elts[] = {
     GetTagConstant(Tag),
     Context.getNode(),
@@ -1020,7 +1020,10 @@
     Ty.getNode(),
   };
   MDNode *Node = MDNode::get(VMContext, &Elts[0], 6);
-  if (OptimizedBuild) {
+  if (AlwaysPreserve) {
+    // The optimizer may remove local variable. If there is an interest
+    // to preserve variable info in such situation then stash it in a
+    // named mdnode.
     NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.lv");
     NMD->addOperand(Node);
   }

Modified: llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DIE.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DIE.h?rev=104854&r1=104853&r2=104854&view=diff
==============================================================================
--- llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DIE.h (original)
+++ llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DIE.h Thu May 27 12:28:49 2010
@@ -316,6 +316,10 @@
     ///
     virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
 
+    /// getValue - Get MCSymbol.
+    ///
+    const MCSymbol *getValue()       const { return Label; }
+
     /// SizeOf - Determine size of label value in bytes.
     ///
     virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;

Modified: llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=104854&r1=104853&r2=104854&view=diff
==============================================================================
--- llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Thu May 27 12:28:49 2010
@@ -156,34 +156,18 @@
 ///
 class DbgVariable {
   DIVariable Var;                    // Variable Descriptor.
-  unsigned FrameIndex;               // Variable frame index.
-  const MachineInstr *DbgValueMInsn; // DBG_VALUE
-  // DbgValueLabel - DBG_VALUE is effective from this label.
-  MCSymbol *DbgValueLabel;
-  DbgVariable *const AbstractVar;    // Abstract variable for this variable.
-  DIE *TheDIE;
+  DIE *TheDIE;                       // Variable DIE.
+  unsigned DotDebugLocOffset;        // Offset in DotDebugLocEntries.
 public:
   // AbsVar may be NULL.
-  DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
-    : Var(V), FrameIndex(I), DbgValueMInsn(0), 
-      DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
-  DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
-    : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
-      AbstractVar(AbsVar), TheDIE(0)
-    {}
+  DbgVariable(DIVariable V) : Var(V), TheDIE(0), DotDebugLocOffset(~0U) {}
 
   // Accessors.
   DIVariable getVariable()           const { return Var; }
-  unsigned getFrameIndex()           const { return FrameIndex; }
-  const MachineInstr *getDbgValue()  const { return DbgValueMInsn; }
-  MCSymbol *getDbgValueLabel()       const { return DbgValueLabel; }
-  void setDbgValueLabel(MCSymbol *L)       { DbgValueLabel = L; }
-  DbgVariable *getAbstractVariable() const { return AbstractVar; }
   void setDIE(DIE *D)                      { TheDIE = D; }
   DIE *getDIE()                      const { return TheDIE; }
-  bool hasLocation()                       { 
-    return DbgValueMInsn || FrameIndex != ~0U; 
-  }
+  void setDotDebugLocOffset(unsigned O)    { DotDebugLocOffset = O; }
+  unsigned getDotDebugLocOffset()    const { return DotDebugLocOffset; }
 };
 
 //===----------------------------------------------------------------------===//
@@ -320,7 +304,8 @@
   : DwarfPrinter(OS, A, T), FirstCU(0),
     AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
     DIEBlocks(), SectionSourceLines(), didInitial(false), shouldEmit(false),
-    CurrentFnDbgScope(0), PrevLabel(NULL), DebugTimer(0) {
+    CurrentFnDbgScope(0), PrevLabel(NULL), DwarfDebugLocSectionSym(NULL),
+    DebugTimer(0) {
   NextStringPoolNumber = 0;
   if (TimePassesIsEnabled)
     DebugTimer = new Timer("Dwarf Debug Writer");
@@ -791,7 +776,7 @@
 }
 
 /// addRegisterAddress - Add register location entry in variable DIE.
-bool DwarfDebug::addRegisterAddress(DIE *Die, DbgVariable *DV,
+bool DwarfDebug::addRegisterAddress(DIE *Die, const MCSymbol *VS,
                                     const MachineOperand &MO) {
   assert (MO.isReg() && "Invalid machine operand!");
   if (!MO.getReg())
@@ -799,26 +784,26 @@
   MachineLocation Location;
   Location.set(MO.getReg());
   addAddress(Die, dwarf::DW_AT_location, Location);
-  if (MCSymbol *VS = DV->getDbgValueLabel())
+  if (VS)
     addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
   return true;
 }
 
 /// addConstantValue - Add constant value entry in variable DIE.
-bool DwarfDebug::addConstantValue(DIE *Die, DbgVariable *DV, 
+bool DwarfDebug::addConstantValue(DIE *Die, const MCSymbol *VS,
                                   const MachineOperand &MO) {
   assert (MO.isImm() && "Invalid machine operand!");
   DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
   unsigned Imm = MO.getImm();
   addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
   addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
-  if (MCSymbol *VS = DV->getDbgValueLabel())
+  if (VS)
     addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
   return true;
 }
 
 /// addConstantFPValue - Add constant value entry in variable DIE.
-bool DwarfDebug::addConstantFPValue(DIE *Die, DbgVariable *DV, 
+bool DwarfDebug::addConstantFPValue(DIE *Die, const MCSymbol *VS,
                                     const MachineOperand &MO) {
   assert (MO.isFPImm() && "Invalid machine operand!");
   DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -840,10 +825,8 @@
             (unsigned char)0xFF & FltPtr[Start]);
   
   addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
-  
-  if (MCSymbol *VS = DV->getDbgValueLabel())
-    addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
-             VS);
+  if (VS)
+    addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
   return true; 
 }
 
@@ -1433,18 +1416,18 @@
             DebugRangeSymbols.size() * TD->getPointerSize());
     for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
          RE = Ranges.end(); RI != RE; ++RI) {
-      DebugRangeSymbols.push_back(LabelsBeforeInsn.lookup(RI->first));
-      DebugRangeSymbols.push_back(LabelsAfterInsn.lookup(RI->second));
+      DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
+      DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
     }
     DebugRangeSymbols.push_back(NULL);
     DebugRangeSymbols.push_back(NULL);
     return ScopeDIE;
   }
 
-  MCSymbol *Start = LabelsBeforeInsn.lookup(RI->first);
-  MCSymbol *End = LabelsAfterInsn.lookup(RI->second);
+  const MCSymbol *Start = getLabelBeforeInsn(RI->first);
+  const MCSymbol *End = getLabelAfterInsn(RI->second);
 
-  if (Start == 0 || End == 0) return 0;
+  if (End == 0) return 0;
 
   assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
   assert(End->isDefined() && "Invalid end label for an inlined scope!");
@@ -1469,8 +1452,8 @@
   // For now, use first instruction range and emit low_pc/high_pc pair and
   // corresponding .debug_inlined section entry for this pair.
   SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
-  MCSymbol *StartLabel = LabelsBeforeInsn.lookup(RI->first);
-  MCSymbol *EndLabel = LabelsAfterInsn.lookup(RI->second);
+  const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
+  const MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
 
   if (StartLabel == 0 || EndLabel == 0) {
     assert (0 && "Unexpected Start and End  labels for a inlined scope!");
@@ -1503,11 +1486,13 @@
     I = InlineInfo.find(InlinedSP.getNode());
 
   if (I == InlineInfo.end()) {
-    InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartLabel,
-                                                             ScopeDIE));
+    InlineInfo[InlinedSP.getNode()]
+      .push_back(std::make_pair(const_cast<MCSymbol *>(StartLabel),
+                                ScopeDIE));
     InlinedSPNodes.push_back(InlinedSP.getNode());
   } else
-    I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
+    I->second.push_back(std::make_pair(
+                          const_cast<MCSymbol *>(StartLabel), ScopeDIE));
 
   DILocation DL(Scope->getInlinedAt());
   addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, TheCU->getID());
@@ -1543,23 +1528,15 @@
   // Define variable debug information entry.
   DIE *VariableDie = new DIE(Tag);
 
-
   DIE *AbsDIE = NULL;
-  if (DbgVariable *AV = DV->getAbstractVariable())
-    AbsDIE = AV->getDIE();
+  DenseMap<const DbgVariable *, const DbgVariable *>::iterator
+    V2AVI = VarToAbstractVarMap.find(DV);
+  if (V2AVI != VarToAbstractVarMap.end())
+    AbsDIE = V2AVI->second->getDIE();
 
-  if (AbsDIE) {
-    DIScope DS(Scope->getScopeNode());
-    DISubprogram InlinedSP = getDISubprogram(DS.getNode());
-    DIE *OriginSPDIE = 
-      getCompileUnit(InlinedSP.getNode())->getDIE(InlinedSP.getNode());
-    (void) OriginSPDIE;
-    assert(OriginSPDIE && "Unable to find Origin DIE for the SP!");
-    DIE *AbsDIE = DV->getAbstractVariable()->getDIE();
-    assert(AbsDIE && "Unable to find Origin DIE for the Variable!");
+  if (AbsDIE)
     addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
                 dwarf::DW_FORM_ref4, AbsDIE);
-  }
   else {
     addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
     addSourceLine(VariableDie, &VD);
@@ -1573,56 +1550,76 @@
       addType(VariableDie, VD.getType());
   }
 
+  if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
+    addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
+
+  if (Scope->isAbstractScope()) {
+    DV->setDIE(VariableDie);
+    return VariableDie;
+  }
+
   // Add variable address.
-  if (!Scope->isAbstractScope()) {
-    // Check if variable is described by DBG_VALUE instruction.
-    if (const MachineInstr *DVInsn = DV->getDbgValue()) {
-      bool updated = false;
-      // FIXME : Handle getNumOperands != 3 
-      if (DVInsn->getNumOperands() == 3) {
-        if (DVInsn->getOperand(0).isReg())
-          updated = addRegisterAddress(VariableDie, DV, DVInsn->getOperand(0));
-        else if (DVInsn->getOperand(0).isImm())
-          updated = addConstantValue(VariableDie, DV, DVInsn->getOperand(0));
-        else if (DVInsn->getOperand(0).isFPImm()) 
-          updated = addConstantFPValue(VariableDie, DV, DVInsn->getOperand(0));
-      } else {
-        MachineLocation Location = Asm->getDebugValueLocation(DVInsn);
-        if (Location.getReg()) {
-          addAddress(VariableDie, dwarf::DW_AT_location, Location);
-          if (MCSymbol *VS = DV->getDbgValueLabel())
-            addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
-                     VS);
-          updated = true;
-        }
-      }
-      if (!updated) {
-        // If variableDie is not updated then DBG_VALUE instruction does not
-        // have valid variable info.
-        delete VariableDie;
-        return NULL;
-      }
-    } 
-    else {
-      MachineLocation Location;
-      unsigned FrameReg;
-      if (DV->hasLocation()) {
-        int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(),
-                                                FrameReg);
-        Location.set(FrameReg, Offset);
-      
-        if (VD.hasComplexAddress())
-          addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
-        else if (VD.isBlockByrefVariable())
-          addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
-        else
-          addAddress(VariableDie, dwarf::DW_AT_location, Location);
+
+  unsigned Offset = DV->getDotDebugLocOffset();
+  if (Offset != ~0U) {
+    addLabel(VariableDie, dwarf::DW_AT_location, dwarf::DW_FORM_data4,
+             getDWLabel("debug_loc", Offset));
+    DV->setDIE(VariableDie);
+    UseDotDebugLocEntry.insert(VariableDie);
+    return VariableDie;
+  }
+
+  // Check if variable is described by a  DBG_VALUE instruction.
+  DenseMap<const DbgVariable *, const MachineInstr *>::iterator DVI =
+    DbgVariableToDbgInstMap.find(DV);
+  if (DVI != DbgVariableToDbgInstMap.end()) {
+    const MachineInstr *DVInsn = DVI->second;
+    const MCSymbol *DVLabel = findVariableLabel(DV);
+    bool updated = false;
+    // FIXME : Handle getNumOperands != 3 
+    if (DVInsn->getNumOperands() == 3) {
+      if (DVInsn->getOperand(0).isReg())
+        updated = addRegisterAddress(VariableDie, DVLabel, DVInsn->getOperand(0));
+      else if (DVInsn->getOperand(0).isImm())
+        updated = addConstantValue(VariableDie, DVLabel, DVInsn->getOperand(0));
+      else if (DVInsn->getOperand(0).isFPImm()) 
+        updated = addConstantFPValue(VariableDie, DVLabel, DVInsn->getOperand(0));
+    } else {
+      MachineLocation Location = Asm->getDebugValueLocation(DVInsn);
+      if (Location.getReg()) {
+        addAddress(VariableDie, dwarf::DW_AT_location, Location);
+        if (DVLabel)
+          addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+                   DVLabel);
+        updated = true;
       }
     }
-  }
+    if (!updated) {
+      // If variableDie is not updated then DBG_VALUE instruction does not
+      // have valid variable info.
+      delete VariableDie;
+      return NULL;
+    }
+    DV->setDIE(VariableDie);
+    return VariableDie;
+  } 
 
-  if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
-    addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
+  // .. else use frame index, if available.
+  MachineLocation Location;
+  unsigned FrameReg;
+  const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+  int FI = 0;
+  if (findVariableFrameIndex(DV, &FI)) {
+    int Offset = RI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
+    Location.set(FrameReg, Offset);
+    
+    if (VD.hasComplexAddress())
+      addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
+    else if (VD.isBlockByrefVariable())
+      addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
+    else
+      addAddress(VariableDie, dwarf::DW_AT_location, Location);
+  }
   DV->setDIE(VariableDie);
   return VariableDie;
 
@@ -2060,8 +2057,7 @@
 }
 
 /// findAbstractVariable - Find abstract variable, if any, associated with Var.
-DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
-                                              unsigned FrameIdx,
+DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var, 
                                               DebugLoc ScopeLoc) {
 
   DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
@@ -2073,40 +2069,18 @@
   if (!Scope)
     return NULL;
 
-  AbsDbgVariable = new DbgVariable(Var, FrameIdx,
-                                   NULL /* No more-abstract variable*/);
+  AbsDbgVariable = new DbgVariable(Var);
   Scope->addVariable(AbsDbgVariable);
   AbstractVariables[Var.getNode()] = AbsDbgVariable;
   return AbsDbgVariable;
 }
 
-/// findAbstractVariable - Find abstract variable, if any, associated with Var.
-/// FIXME : Refactor findAbstractVariable.
-DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
-                                              const MachineInstr *MI,
-                                              DebugLoc ScopeLoc) {
-
-  DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
-  if (AbsDbgVariable)
-    return AbsDbgVariable;
-
-  LLVMContext &Ctx = Var.getNode()->getContext();
-  DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
-  if (!Scope)
-    return NULL;
-
-  AbsDbgVariable = new DbgVariable(Var, MI,
-                                   NULL /* No more-abstract variable*/);
-  Scope->addVariable(AbsDbgVariable);
-  AbstractVariables[Var.getNode()] = AbsDbgVariable;
-  DbgValueStartMap[MI] = AbsDbgVariable;
-  return AbsDbgVariable;
-}
-
-/// collectVariableInfo - Populate DbgScope entries with variables' info.
-void DwarfDebug::collectVariableInfo(const MachineFunction *MF) {
+/// collectVariableInfoFromMMITable - Collect variable information from
+/// side table maintained by MMI.
+void 
+DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction * MF,
+                                   SmallPtrSet<const MDNode *, 16> &Processed) {
   if (!MMI) return;
-  SmallPtrSet<const MDNode *, 16> Processed;
   const LLVMContext &Ctx = MF->getFunction()->getContext();
 
   MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
@@ -2128,53 +2102,128 @@
     if (Scope == 0)
       continue;
 
-    DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, VP.second);
-    DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable);
+    DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second);
+    DbgVariable *RegVar = new DbgVariable(DV);
+    recordVariableFrameIndex(RegVar, VP.first);
     Scope->addVariable(RegVar);
+    if (AbsDbgVariable) {
+      recordVariableFrameIndex(AbsDbgVariable, VP.first);
+      VarToAbstractVarMap[RegVar] = AbsDbgVariable;
+    }
   }
+}
+
+/// isDbgValueInUndefinedReg - Return true if debug value, encoded by 
+/// DBG_VALUE instruction, is in undefined reg.
+static bool isDbgValueInUndefinedReg(const MachineInstr *MI) {
+  assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!");
+  if (MI->getOperand(0).isReg() && !MI->getOperand(0).getReg())
+    return true;
+  return false;
+}
+
+/// isDbgValueInDefinedReg - Return true if debug value, encoded by 
+/// DBG_VALUE instruction, is in a defined reg.
+static bool isDbgValueInDefinedReg(const MachineInstr *MI) {
+  assert (MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!");
+  if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg())
+    return true;
+  return false;
+}
 
+/// collectVariableInfo - Populate DbgScope entries with variables' info.
+void DwarfDebug::collectVariableInfo(const MachineFunction *MF) {
+  SmallPtrSet<const MDNode *, 16> Processed;
+  
+  /// collection info from MMI table.
+  collectVariableInfoFromMMITable(MF, Processed);
+
+  SmallVector<const MachineInstr *, 8> DbgValues;
   // Collect variable information from DBG_VALUE machine instructions;
   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
-       I != E; ++I) {
+       I != E; ++I)
     for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
          II != IE; ++II) {
       const MachineInstr *MInsn = II;
-      if (!MInsn->isDebugValue())
+      if (!MInsn->isDebugValue() || isDbgValueInUndefinedReg(MInsn))
         continue;
+      DbgValues.push_back(MInsn);
+    }
 
-      // Ignore Undef values.
-      if (MInsn->getOperand(0).isReg() && !MInsn->getOperand(0).getReg())
-        continue;
+  // This is a collection of DBV_VALUE instructions describing same variable.
+  SmallVector<const MachineInstr *, 4> MultipleValues;
+  for(SmallVector<const MachineInstr *, 8>::iterator I = DbgValues.begin(),
+        E = DbgValues.end(); I != E; ++I) {
+    const MachineInstr *MInsn = *I;
+    MultipleValues.clear();
+    if (isDbgValueInDefinedReg(MInsn))
+      MultipleValues.push_back(MInsn);
+    const MDNode *DVNode = 
+      MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata();
+    DIVariable DV(const_cast<MDNode *>(DVNode));
+    if (Processed.count(DVNode) != 0)
+      continue;
 
-      DIVariable DV(
-        const_cast<MDNode *>(MInsn->getOperand(MInsn->getNumOperands() - 1)
-                               .getMetadata()));
-      if (DV.getTag() == dwarf::DW_TAG_arg_variable)  {
-        // FIXME Handle inlined subroutine arguments.
-        DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
-        CurrentFnDbgScope->addVariable(ArgVar);
-        DbgValueStartMap[MInsn] = ArgVar;
-        continue;
-      }
+    for (SmallVector<const MachineInstr *, 8>::iterator MI = I+1, 
+           ME = DbgValues.end(); MI != ME; ++MI) {
+      const MDNode *Var = 
+        (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
+      if (Var == DV.getNode() && isDbgValueInDefinedReg(*MI))
+        MultipleValues.push_back(*MI);
+    }
 
-      DebugLoc DL = MInsn->getDebugLoc();
-      if (DL.isUnknown()) continue;
-      DbgScope *Scope = 0;
-      if (MDNode *IA = DL.getInlinedAt(Ctx))
-        Scope = ConcreteScopes.lookup(IA);
-      if (Scope == 0)
-        Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
-      
-      // If variable scope is not found then skip this variable.
-      if (Scope == 0)
-        continue;
+    DbgScope *Scope = findDbgScope(MInsn);
+    if (!Scope && DV.getTag() == dwarf::DW_TAG_arg_variable)
+      Scope = CurrentFnDbgScope;
+    // If variable scope is not found then skip this variable.
+    if (!Scope)
+      continue;
+
+    Processed.insert(DVNode);
+    DbgVariable *RegVar = new DbgVariable(DV);
+    Scope->addVariable(RegVar);
+    if (DV.getTag() != dwarf::DW_TAG_arg_variable)
+      DbgVariableLabelsMap[RegVar] = getLabelBeforeInsn(MInsn); 
+    if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) {
+      DbgVariableToDbgInstMap[AbsVar] = MInsn;
+      VarToAbstractVarMap[RegVar] = AbsVar;
+    }
+    if (MultipleValues.size() <= 1) {
+      DbgVariableToDbgInstMap[RegVar] = MInsn;
+      continue;
+    }
 
-      Processed.insert(DV.getNode());
-      DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, DL);
-      DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
-      DbgValueStartMap[MInsn] = RegVar;
-      Scope->addVariable(RegVar);
+    // handle multiple DBG_VALUE instructions describing one variable.
+    if (DotDebugLocEntries.empty())
+      RegVar->setDotDebugLocOffset(0);
+    else
+      RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
+    const MachineInstr *Begin = NULL;
+    const MachineInstr *End = NULL;
+    for (SmallVector<const MachineInstr *, 4>::iterator 
+           MVI = MultipleValues.begin(), MVE = MultipleValues.end(); MVI != MVE; ++MVI) {
+      if (!Begin) {
+        Begin = *MVI;
+        continue;
+      } 
+      End = *MVI;
+      MachineLocation MLoc;
+      MLoc.set(Begin->getOperand(0).getReg(), 0);
+      const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
+      const MCSymbol *SLabel = getLabelBeforeInsn(End);
+      DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
+      Begin = End;
+      if (MVI + 1 == MVE) {
+        // If End is the last instruction then its value is valid
+        // until the end of the funtion.
+        MLoc.set(End->getOperand(0).getReg(), 0);
+        DotDebugLocEntries.
+          push_back(DotDebugLocEntry(SLabel, 
+                                     getDWLabel("func_end", SubprogramCount),
+                                     MLoc));
+      }
     }
+    DotDebugLocEntries.push_back(DotDebugLocEntry());
   }
 
   // Collect info for variables that were optimized out.
@@ -2182,61 +2231,59 @@
       MF->getFunction()->getParent()->getNamedMetadata("llvm.dbg.lv")) {
     for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
       DIVariable DV(cast_or_null<MDNode>(NMD->getOperand(i)));
-      if (!Processed.insert(DV.getNode()))
+      if (!DV.getNode() || !Processed.insert(DV.getNode()))
         continue;
       DbgScope *Scope = DbgScopeMap.lookup(DV.getContext().getNode());
       if (Scope)
-        Scope->addVariable(new DbgVariable(DV, ~0U, NULL));
+        Scope->addVariable(new DbgVariable(DV));
     }
   }
+}
 
+/// getLabelBeforeInsn - Return Label preceding the instruction.
+const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
+  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
+    LabelsBeforeInsn.find(MI);
+  if (I == LabelsBeforeInsn.end())
+    return NULL;
+  return I->second;
+}
+
+/// getLabelAfterInsn - Return Label immediately following the instruction.
+const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
+  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
+    LabelsAfterInsn.find(MI);
+  if (I == LabelsAfterInsn.end())
+    return NULL;
+  return I->second;
 }
 
 /// beginScope - Process beginning of a scope.
 void DwarfDebug::beginScope(const MachineInstr *MI) {
-  // Check location.
-  DebugLoc DL = MI->getDebugLoc();
-  if (DL.isUnknown())
+  if (InsnNeedsLabel.count(MI) == 0) {
+    LabelsBeforeInsn[MI] = PrevLabel;
     return;
+  }
 
-  MDNode *Scope = DL.getScope(MF->getFunction()->getContext());
-  
-  // FIXME: Should only verify each scope once!
-  if (!DIScope(Scope).Verify())
+  // Check location.
+  DebugLoc DL = MI->getDebugLoc();
+  if (!DL.isUnknown()) {
+    MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
+    PrevLabel = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
+    PrevInstLoc = DL;
+    LabelsBeforeInsn[MI] = PrevLabel;
     return;
+  }
 
-  // DBG_VALUE instruction establishes new value.
+  // If location is unknown then use temp label for this DBG_VALUE 
+  // instruction.
   if (MI->isDebugValue()) {
-    DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
-      = DbgValueStartMap.find(MI);
-    if (DI != DbgValueStartMap.end()) {
-      MCSymbol *Label = NULL;
-      if (DL == PrevInstLoc)
-        Label = PrevLabel;
-      else {
-        Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
-        PrevInstLoc = DL;
-        PrevLabel = Label;
-      }
-      DI->second->setDbgValueLabel(Label);
-    }
+    PrevLabel = MMI->getContext().CreateTempSymbol();
+    Asm->OutStreamer.EmitLabel(PrevLabel);
+    LabelsBeforeInsn[MI] = PrevLabel;
     return;
   }
-
-  // Emit a label to indicate location change. This is used for line 
-  // table even if this instruction does not start a new scope.
-  MCSymbol *Label = NULL;
-  if (DL == PrevInstLoc)
-    Label = PrevLabel;
-  else {
-    Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
-    PrevInstLoc = DL;
-    PrevLabel = Label;
-  }
-
-  // If this instruction begins a scope then note down corresponding label.
-  if (InsnsBeginScopeSet.count(MI) != 0)
-    LabelsBeforeInsn[MI] = Label;
+  assert (0 && "Instruction is not processed!");
 }
 
 /// endScope - Process end of a scope.
@@ -2380,7 +2427,7 @@
 }
 /// extractScopeInformation - Scan machine instructions in this function
 /// and collect DbgScopes. Return true, if at least one scope was found.
-bool DwarfDebug::extractScopeInformation() {
+bool DwarfDebug::extractScopeInformation(const MachineFunction *MF) {
   // If scope information was extracted using .dbg intrinsics then there is not
   // any need to extract these information by scanning each instruction.
   if (!DbgScopeMap.empty())
@@ -2506,19 +2553,12 @@
 /// emitted immediately after the function entry point.
 void DwarfDebug::beginFunction(const MachineFunction *MF) {
   this->MF = MF;
-
   if (!ShouldEmitDwarfDebug()) return;
-
-  if (TimePassesIsEnabled)
-    DebugTimer->startTimer();
-
-  if (!extractScopeInformation())
-    return;
-
-  collectVariableInfo(MF);
+  if (!extractScopeInformation(MF)) return;
 
   // Assumes in correct section after the entry point.
-  Asm->OutStreamer.EmitLabel(getDWLabel("func_begin", ++SubprogramCount));
+  MCSymbol *FunctionBeginSym = getDWLabel("func_begin", ++SubprogramCount);
+  Asm->OutStreamer.EmitLabel(FunctionBeginSym);
 
   // Emit label for the implicitly defined dbg.stoppoint at the start of the
   // function.
@@ -2538,6 +2578,36 @@
   }
   
   recordSourceLine(Line, Col, Scope);
+
+  DebugLoc PrevLoc;
+  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+       I != E; ++I)
+    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
+         II != IE; ++II) {
+      const MachineInstr *MI = II;
+      DebugLoc DL = MI->getDebugLoc();
+      if (MI->isDebugValue()) {
+        assert (MI->getNumOperands() > 1 && "Invalid machine instruction!");
+        DIVariable DV(const_cast<MDNode*>(MI->getOperand(MI->getNumOperands() - 1).getMetadata()));
+        if (!DV.Verify()) continue;
+        // If DBG_VALUE is for a local variable then it needs a label.
+        if (DV.getTag() != dwarf::DW_TAG_arg_variable)
+          InsnNeedsLabel.insert(MI);
+        // DBG_VALUE for inlined functions argument needs a label.
+        else if (!DISubprogram(DV.getContext().getNode()).describes(MF->getFunction()))
+          InsnNeedsLabel.insert(MI);
+        // DBG_VALUE indicating argument location change needs a label.
+        else if (!ProcessedArgs.insert(DV.getNode()))
+          InsnNeedsLabel.insert(MI);
+      } else if (DL != PrevLoc && !DL.isUnknown())
+        // Otherwise, instruction needs a location only if it is new location.
+        InsnNeedsLabel.insert(MI);
+
+      if (!DL.isUnknown())
+        PrevLoc = DL;
+    }
+
+  PrevLabel = FunctionBeginSym;
 }
 
 /// endFunction - Gather and emit post-function debug information.
@@ -2552,9 +2622,12 @@
     return;
 
   if (CurrentFnDbgScope) {
+
     // Define end label for subprogram.
     Asm->OutStreamer.EmitLabel(getDWLabel("func_end", SubprogramCount));
     
+    collectVariableInfo(MF);
+
     // Get function line info.
     if (!Lines.empty()) {
       // Get section line info.
@@ -2583,10 +2656,15 @@
 
   // Clear debug info
   CurrentFnDbgScope = NULL;
+  InsnNeedsLabel.clear();
+  ProcessedArgs.clear();
+  DbgVariableToFrameIndexMap.clear();
+  VarToAbstractVarMap.clear();
+  DbgVariableToDbgInstMap.clear();
+  DbgVariableLabelsMap.clear();
   DeleteContainerSeconds(DbgScopeMap);
   InsnsBeginScopeSet.clear();
   InsnsEndScopeSet.clear();
-  DbgValueStartMap.clear();
   ConcreteScopes.clear();
   DeleteContainerSeconds(AbstractScopes);
   AbstractScopesList.clear();
@@ -2599,6 +2677,53 @@
     DebugTimer->stopTimer();
 }
 
+/// recordVariableFrameIndex - Record a variable's index.
+void DwarfDebug::recordVariableFrameIndex(const DbgVariable *V, int Index) {
+  assert (V && "Invalid DbgVariable!");
+  DbgVariableToFrameIndexMap[V] = Index;
+}
+
+/// findVariableFrameIndex - Return true if frame index for the variable
+/// is found. Update FI to hold value of the index.
+bool DwarfDebug::findVariableFrameIndex(const DbgVariable *V, int *FI) {
+  assert (V && "Invalid DbgVariable!");
+  DenseMap<const DbgVariable *, int>::iterator I =
+    DbgVariableToFrameIndexMap.find(V);
+  if (I == DbgVariableToFrameIndexMap.end())
+    return false;
+  *FI = I->second;
+  return true;
+}
+
+/// findVariableLabel - Find MCSymbol for the variable.
+const MCSymbol *DwarfDebug::findVariableLabel(const DbgVariable *V) {
+  DenseMap<const DbgVariable *, const MCSymbol *>::iterator I
+    = DbgVariableLabelsMap.find(V);
+  if (I == DbgVariableLabelsMap.end())
+    return NULL;
+  else return I->second;
+}
+
+/// findDbgScope - Find DbgScope for the debug loc attached with an 
+/// instruction.
+DbgScope *DwarfDebug::findDbgScope(const MachineInstr *MInsn) {
+  DbgScope *Scope = NULL;
+  LLVMContext &Ctx = 
+    MInsn->getParent()->getParent()->getFunction()->getContext();
+  DebugLoc DL = MInsn->getDebugLoc();
+
+  if (DL.isUnknown()) 
+    return Scope;
+
+  if (MDNode *IA = DL.getInlinedAt(Ctx))
+    Scope = ConcreteScopes.lookup(IA);
+  if (Scope == 0)
+    Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
+    
+  return Scope;
+}
+
+
 /// recordSourceLine - Register a source line with debug info. Returns the
 /// unique label that was emitted and which provides correspondence to
 /// the source line list.
@@ -2735,10 +2860,10 @@
     Asm->OutStreamer.EmitLabel(getTempLabel("section_macinfo"));
   }
 
-  Asm->OutStreamer.SwitchSection(TLOF.getDwarfLineSection());
   Asm->OutStreamer.EmitLabel(getTempLabel("section_line"));
+  DwarfDebugLocSectionSym = getTempLabel("section_loc");
   Asm->OutStreamer.SwitchSection(TLOF.getDwarfLocSection());
-  Asm->OutStreamer.EmitLabel(getTempLabel("section_loc"));
+  Asm->OutStreamer.EmitLabel(DwarfDebugLocSectionSym);
   Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubNamesSection());
   Asm->OutStreamer.EmitLabel(getTempLabel("section_pubnames"));
   Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubTypesSection());
@@ -2792,6 +2917,14 @@
       Asm->EmitInt32(Addr);
       break;
     }
+    case dwarf::DW_AT_location: {
+      if (UseDotDebugLocEntry.count(Die) != 0) {
+        DIELabel *L = cast<DIELabel>(Values[i]);
+        Asm->EmitLabelDifference(L->getValue(), DwarfDebugLocSectionSym, 4);
+      } else
+        Values[i]->EmitValue(this, Form);
+      break;
+    }
     default:
       // Emit an attribute using the defined form.
       Values[i]->EmitValue(this, Form);
@@ -3294,9 +3427,39 @@
 /// emitDebugLoc - Emit visible names into a debug loc section.
 ///
 void DwarfDebug::emitDebugLoc() {
+  if (DotDebugLocEntries.empty())
+    return;
+
   // Start the dwarf loc section.
   Asm->OutStreamer.SwitchSection(
-                              Asm->getObjFileLowering().getDwarfLocSection());
+    Asm->getObjFileLowering().getDwarfLocSection());
+  unsigned char Size = TD->getPointerSize();
+  Asm->OutStreamer.EmitLabel(getDWLabel("debug_loc", 0));
+  unsigned index = 1;
+  for (SmallVector<DotDebugLocEntry, 4>::iterator I = DotDebugLocEntries.begin(),
+         E = DotDebugLocEntries.end(); I != E; ++I, ++index) {
+    DotDebugLocEntry Entry = *I;
+    if (Entry.isEmpty()) {
+      Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
+      Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
+      Asm->OutStreamer.EmitLabel(getDWLabel("debug_loc", index));
+    } else {
+      Asm->OutStreamer.EmitSymbolValue(Entry.Begin, Size, 0);
+      Asm->OutStreamer.EmitSymbolValue(Entry.End, Size, 0);
+      const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+      unsigned Reg = RI->getDwarfRegNum(Entry.Loc.getReg(), false);
+      if (Reg < 32) {
+        Asm->OutStreamer.AddComment("Loc expr size");
+        Asm->EmitInt16(1);
+        Asm->EmitInt8(dwarf::DW_OP_reg0 + Reg);
+      } else {
+        Asm->OutStreamer.AddComment("Loc expr size");
+        Asm->EmitInt16(1+MCAsmInfo::getULEB128Size(Reg));
+        Asm->EmitInt8(dwarf::DW_OP_regx);
+        EmitULEB128(Reg);
+      }
+    }
+  }
 }
 
 /// EmitDebugARanges - Emit visible names into a debug aranges section.

Modified: llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=104854&r1=104853&r2=104854&view=diff
==============================================================================
--- llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/branches/Apple/Morbo/lib/CodeGen/AsmPrinter/DwarfDebug.h Thu May 27 12:28:49 2010
@@ -14,6 +14,7 @@
 #ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__
 #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
 
+#include "llvm/CodeGen/MachineLocation.h"
 #include "DIE.h"
 #include "DwarfPrinter.h"
 #include "llvm/CodeGen/AsmPrinter.h"
@@ -154,11 +155,41 @@
   /// DbgScopes in AbstractScopes.
   DenseMap<MDNode *, DbgVariable *> AbstractVariables;
 
-  /// DbgValueStartMap - Tracks starting scope of variable DIEs.
-  /// If the scope of an object begins sometime after the low pc value for the 
-  /// scope most closely enclosing the object, the object entry may have a 
-  /// DW_AT_start_scope attribute.
-  DenseMap<const MachineInstr *, DbgVariable *> DbgValueStartMap;
+  /// DbgVariableToFrameIndexMap - Tracks frame index used to find 
+  /// variable's value.
+  DenseMap<const DbgVariable *, int> DbgVariableToFrameIndexMap;
+
+  /// DbgVariableToDbgInstMap - Maps DbgVariable to corresponding DBG_VALUE
+  /// machine instruction.
+  DenseMap<const DbgVariable *, const MachineInstr *> DbgVariableToDbgInstMap;
+
+  /// DbgVariableLabelsMap - Maps DbgVariable to corresponding MCSymbol.
+  DenseMap<const DbgVariable *, const MCSymbol *> DbgVariableLabelsMap;
+
+  /// DotDebugLocEntry - This struct describes location entries emitted in
+  /// .debug_loc section.
+  typedef struct DotDebugLocEntry {
+    const MCSymbol *Begin;
+    const MCSymbol *End;
+    MachineLocation Loc;
+    DotDebugLocEntry() : Begin(0), End(0) {}
+    DotDebugLocEntry(const MCSymbol *B, const MCSymbol *E, 
+                  MachineLocation &L) : Begin(B), End(E), Loc(L) {}
+    /// Empty entries are also used as a trigger to emit temp label. Such
+    /// labels are referenced is used to find debug_loc offset for a given DIE.
+    bool isEmpty() { return Begin == 0 && End == 0; }
+  } DotDebugLocEntry;
+
+  /// DotDebugLocEntries - Collection of DotDebugLocEntry.
+  SmallVector<DotDebugLocEntry, 4> DotDebugLocEntries;
+
+  /// UseDotDebugLocEntry - DW_AT_location attributes for the DIEs in this set
+  /// idetifies corresponding .debug_loc entry offset.
+  SmallPtrSet<const DIE *, 4> UseDotDebugLocEntry;
+
+  /// VarToAbstractVarMap - Maps DbgVariable with corresponding Abstract
+  /// DbgVariable, if any.
+  DenseMap<const DbgVariable *, const DbgVariable *> VarToAbstractVarMap;
 
   /// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked
   /// (at the end of the module) as DW_AT_inline.
@@ -187,12 +218,20 @@
   /// instruction.
   DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
 
+  /// insnNeedsLabel - Collection of instructions that need a label to mark
+  /// a debuggging information entity.
+  SmallPtrSet<const MachineInstr *, 8> InsnNeedsLabel;
+
+  /// ProcessedArgs - Collection of arguments already processed.
+  SmallPtrSet<const MDNode *, 8> ProcessedArgs;
+
   SmallVector<const MCSymbol *, 8> DebugRangeSymbols;
 
   /// Previous instruction's location information. This is used to determine
   /// label location to indicate scope boundries in dwarf debug info.
   DebugLoc PrevInstLoc;
   MCSymbol *PrevLabel;
+  MCSymbol *DwarfDebugLocSectionSym;
 
   /// DebugTimer - Timer for the Dwarf debug writer.
   Timer *DebugTimer;
@@ -292,13 +331,13 @@
                   const MachineLocation &Location);
 
   /// addRegisterAddress - Add register location entry in variable DIE.
-  bool addRegisterAddress(DIE *Die, DbgVariable *DV, const MachineOperand &MO);
+  bool addRegisterAddress(DIE *Die, const MCSymbol *VS, const MachineOperand &MO);
 
   /// addConstantValue - Add constant value entry in variable DIE.
-  bool addConstantValue(DIE *Die, DbgVariable *DV, const MachineOperand &MO);
+  bool addConstantValue(DIE *Die, const MCSymbol *VS, const MachineOperand &MO);
 
   /// addConstantFPValue - Add constant value entry in variable DIE.
-  bool addConstantFPValue(DIE *Die, DbgVariable *DV, const MachineOperand &MO);
+  bool addConstantFPValue(DIE *Die, const MCSymbol *VS, const MachineOperand &MO);
 
   /// addComplexAddress - Start with the address based on the location provided,
   /// and generate the DWARF information necessary to find the actual variable
@@ -371,10 +410,7 @@
   DbgScope *getOrCreateAbstractScope(MDNode *N);
 
   /// findAbstractVariable - Find abstract variable associated with Var.
-  DbgVariable *findAbstractVariable(DIVariable &Var, unsigned FrameIdx, 
-                                    DebugLoc Loc);
-  DbgVariable *findAbstractVariable(DIVariable &Var, const MachineInstr *MI,
-                                    DebugLoc Loc);
+  DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc);
 
   /// updateSubprogramScopeDIE - Find DIE for the given subprogram and 
   /// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
@@ -518,17 +554,35 @@
     return Lines.size();
   }
   
+  /// recordVariableFrameIndex - Record a variable's index.
+  void recordVariableFrameIndex(const DbgVariable *V, int Index);
+
+  /// findVariableFrameIndex - Return true if frame index for the variable
+  /// is found. Update FI to hold value of the index.
+  bool findVariableFrameIndex(const DbgVariable *V, int *FI);
+
+  /// findVariableLabel - Find MCSymbol for the variable.
+  const MCSymbol *findVariableLabel(const DbgVariable *V);
+
+  /// findDbgScope - Find DbgScope for the debug loc attached with an 
+  /// instruction.
+  DbgScope *findDbgScope(const MachineInstr *MI);
+
   /// identifyScopeMarkers() - Indentify instructions that are marking
   /// beginning of or end of a scope.
   void identifyScopeMarkers();
 
   /// extractScopeInformation - Scan machine instructions in this function
   /// and collect DbgScopes. Return true, if atleast one scope was found.
-  bool extractScopeInformation();
+  bool extractScopeInformation(const MachineFunction *MF);
   
   /// collectVariableInfo - Populate DbgScope entries with variables' info.
   void collectVariableInfo(const MachineFunction *);
   
+  /// collectVariableInfoFromMMITable - Collect variable information from
+  /// side table maintained by MMI.
+  void collectVariableInfoFromMMITable(const MachineFunction * MF,
+                                       SmallPtrSet<const MDNode *, 16> &P);
 public:
   //===--------------------------------------------------------------------===//
   // Main entry points.
@@ -556,6 +610,12 @@
   ///
   void endFunction(const MachineFunction *MF);
 
+  /// getLabelBeforeInsn - Return Label preceding the instruction.
+  const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
+
+  /// getLabelAfterInsn - Return Label immediately following the instruction.
+  const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
+
   /// beginScope - Process beginning of a scope.
   void beginScope(const MachineInstr *MI);
 

Modified: llvm/branches/Apple/Morbo/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=104854&r1=104853&r2=104854&view=diff
==============================================================================
--- llvm/branches/Apple/Morbo/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/branches/Apple/Morbo/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu May 27 12:28:49 2010
@@ -392,6 +392,13 @@
          "Not all catch info was assigned to a landing pad!");
 #endif
 
+  DenseMap<unsigned, unsigned> LiveInMap;
+  if (!FuncInfo->ArgDbgValues.empty())
+    for (MachineRegisterInfo::livein_iterator LI = RegInfo->livein_begin(),
+           E = RegInfo->livein_end(); LI != E; ++LI)
+      if (LI->second) 
+        LiveInMap.insert(std::make_pair(LI->first, LI->second));
+
   // Insert DBG_VALUE instructions for function arguments to the entry block.
   for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) {
     MachineInstr *MI = FuncInfo->ArgDbgValues[e-i-1];
@@ -404,6 +411,21 @@
       // FIXME: VR def may not be in entry block.
       Def->getParent()->insert(llvm::next(InsertPos), MI);
     }
+
+    // If Reg is live-in then update debug info to track its copy in a vreg.
+    DenseMap<unsigned, unsigned>::iterator LDI = LiveInMap.find(Reg);
+    if (LDI != LiveInMap.end()) {
+      MachineInstr *Def = RegInfo->getVRegDef(LDI->second);
+      MachineBasicBlock::iterator InsertPos = Def;
+      const MDNode *Variable = 
+        MI->getOperand(MI->getNumOperands()-1).getMetadata();
+      unsigned Offset = MI->getOperand(1).getImm();
+      // Def is never a terminator here, so it is ok to increment InsertPos.
+      BuildMI(*EntryMBB, ++InsertPos, MI->getDebugLoc(), 
+              TII.get(TargetOpcode::DBG_VALUE))
+        .addReg(LDI->second, RegState::Debug)
+        .addImm(Offset).addMetadata(Variable);
+    }
   }
 
   // Determine if there are any calls in this machine function.

Propchange: llvm/branches/Apple/Morbo/lib/Target/ARM/ARMInstrFormats.td
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu May 27 12:28:49 2010
@@ -1 +1 @@
-/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td:98980,104182,104419,104531,104640,104646,104655-104656,104661,104664,104722,104737
+/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td:98980,104182,104233,104236,104265,104274,104302,104338,104412,104419,104524,104531,104640,104646,104649,104655-104656,104661,104664,104705-104706,104720,104722,104732,104737,104740,104785,104848

Copied: llvm/branches/Apple/Morbo/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll (from r104732, llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll?p2=llvm/branches/Apple/Morbo/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll&p1=llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll&r1=104732&r2=104854&rev=104854&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll (original)
+++ llvm/branches/Apple/Morbo/test/CodeGen/X86/2010-05-26-DotDebugLoc.ll Thu May 27 12:28:49 2010
@@ -55,12 +55,12 @@
 !29 = metadata !{i32 524299, metadata !9, i32 17, i32 0} ; [ DW_TAG_lexical_block ]
 !30 = metadata !{i32 19, i32 0, metadata !29, null}
 
-; CHECK: Ldebug_loc1
-; CHECK-NEXT: .quad   Lfunc_begin0
+; CHECK: Ldebug_loc:
 ; CHECK-NEXT: .quad   Ltmp3
+; CHECK-NEXT: .quad   Ltmp4
 ; CHECK-NEXT: .short  1
 ; CHECK-NEXT: .byte   85
-; CHECK-NEXT: .quad   Ltmp3
+; CHECK-NEXT: .quad   Ltmp4
 ; CHECK-NEXT: .quad   Lfunc_end
 ; CHECK-NEXT: .short  1
 ; CHECK-NEXT: .byte   83

Copied: llvm/branches/Apple/Morbo/test/DebugInfo/2010-05-25-DotDebugLoc.ll (from r104649, llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Morbo/test/DebugInfo/2010-05-25-DotDebugLoc.ll?p2=llvm/branches/Apple/Morbo/test/DebugInfo/2010-05-25-DotDebugLoc.ll&p1=llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll&r1=104649&r2=104854&rev=104854&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/2010-05-25-DotDebugLoc.ll (original)
+++ llvm/branches/Apple/Morbo/test/DebugInfo/2010-05-25-DotDebugLoc.ll Thu May 27 12:28:49 2010
@@ -1,5 +1,5 @@
-; RUN: llc -O2 < %s | grep debug_loc13
-; Test to check .debug_loc support. This test case emits 14 debug_loc entries.
+; RUN: llc -O2 < %s | grep debug_loc12
+; Test to check .debug_loc support. This test case emits 13 debug_loc entries.
 
 %0 = type { double }
 





More information about the llvm-branch-commits mailing list