Teach our Dwarf emission to use the string pool.
authorNick Lewycky <nicholas@mxc.ca>
Thu, 27 Oct 2011 06:44:11 +0000 (06:44 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Thu, 27 Oct 2011 06:44:11 +0000 (06:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143097 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/CodeGen/AsmPrinter.h
include/llvm/MC/MCAsmInfo.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DIE.cpp
lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/MC/MCAsmInfo.cpp
lib/MC/MCAsmInfoDarwin.cpp
test/CodeGen/ARM/debug-info-sreg2.ll
test/CodeGen/X86/2010-06-28-DbgEntryPC.ll
test/DebugInfo/2011-09-26-GlobalVarContext.ll
test/DebugInfo/stringpool.ll [new file with mode: 0644]

index 06c5c83c95eca88d7ffacd11596796d88466babc..f0d34236c6adb8afedc3a442b4cf2274750ca194 100644 (file)
@@ -194,6 +194,11 @@ namespace llvm {
 
     bool needsSEHMoves();
 
+    /// needsRelocationsForDwarfStringPool - Specifies whether the object format
+    /// expects to use relocations to refer to debug entries. Alternatively we
+    /// emit section offsets in bytes from the start of the string pool.
+    bool needsRelocationsForDwarfStringPool() const;
+
     /// EmitConstantPool - Print to the current output stream assembly
     /// representations of the constants in the constant pool MCP. This is
     /// used to print out constants which have been "spilled to memory" by
index 56ef4d229a617b0af3e91de3642c64ee6186ad5a..d7402b33974fb8d3d9902cbb96e894d534261c07 100644 (file)
@@ -330,6 +330,10 @@ namespace llvm {
     /// use EmitLabelOffsetDifference.
     bool DwarfUsesLabelOffsetForRanges;
 
+    /// DwarfUsesRelocationsForStringPool - True if this Dwarf output must use
+    /// relocations to refer to entries in the string pool.
+    bool DwarfUsesRelocationsForStringPool;
+
     /// DwarfRegNumForCFI - True if dwarf register numbers are printed
     /// instead of symbolic register names in .cfi_* directives.
     bool DwarfRegNumForCFI;  // Defaults to false;
@@ -566,6 +570,9 @@ namespace llvm {
     bool doesDwarfUsesLabelOffsetForRanges() const {
       return DwarfUsesLabelOffsetForRanges;
     }
+    bool doesDwarfUseRelocationsForStringPool() const {
+      return DwarfUsesRelocationsForStringPool;
+    }
     bool useDwarfRegNumForCFI() const {
       return DwarfRegNumForCFI;
     }
index 1999f360878854b45e85f9e4fe9ca470a4ce4c2a..0c0fdc12682f57e5d555601b66fcc0313b060fad 100644 (file)
@@ -613,6 +613,10 @@ bool AsmPrinter::needsSEHMoves() {
     MF->getFunction()->needsUnwindTableEntry();
 }
 
+bool AsmPrinter::needsRelocationsForDwarfStringPool() const {
+  return MAI->doesDwarfUseRelocationsForStringPool();
+}
+
 void AsmPrinter::emitPrologLabel(const MachineInstr &MI) {
   MCSymbol *Label = MI.getOperand(0).getMCSymbol();
 
@@ -2092,4 +2096,3 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
   report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));
   return 0;
 }
-
index 9c1ce761b0c53ce825aa79c216e96d460ad134d7..fad3d0dc3d07bd0d90823efbacb04c5abf8f3779 100644 (file)
@@ -267,6 +267,7 @@ void DIELabel::EmitValue(AsmPrinter *AP, unsigned Form) const {
 ///
 unsigned DIELabel::SizeOf(AsmPrinter *AP, unsigned Form) const {
   if (Form == dwarf::DW_FORM_data4) return 4;
+  if (Form == dwarf::DW_FORM_strp) return 4;
   return AP->getTargetData().getPointerSize();
 }
 
@@ -290,6 +291,7 @@ void DIEDelta::EmitValue(AsmPrinter *AP, unsigned Form) const {
 ///
 unsigned DIEDelta::SizeOf(AsmPrinter *AP, unsigned Form) const {
   if (Form == dwarf::DW_FORM_data4) return 4;
+  if (Form == dwarf::DW_FORM_strp) return 4;
   return AP->getTargetData().getPointerSize();
 }
 
index 9cabe5570d95a1677d3e9414f439d58727c4ebb6..a6a004d4d9e8454e0761afc2f1cacc671bb4b237 100644 (file)
@@ -69,10 +69,21 @@ void CompileUnit::addSInt(DIE *Die, unsigned Attribute,
 
 /// addString - Add a string attribute data and value. DIEString only
 /// keeps string reference.
-void CompileUnit::addString(DIE *Die, unsigned Attribute, unsigned Form,
-                            StringRef String) {
-  DIEValue *Value = new (DIEValueAllocator) DIEString(String);
-  Die->addValue(Attribute, Form, Value);
+void CompileUnit::addString(DIE *Die, unsigned Attribute, StringRef String) {
+  if (String.size() > 3) {
+    MCSymbol *Symb = DD->getStringPoolEntry(String);
+    DIEValue *Value;
+    if (Asm->needsRelocationsForDwarfStringPool())
+      Value = new (DIEValueAllocator) DIELabel(Symb);
+    else {
+      MCSymbol *StringPool = DD->getStringPool();
+      Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
+    }
+    Die->addValue(Attribute, dwarf::DW_FORM_strp, Value);
+  } else {
+    DIEValue *Value = new (DIEValueAllocator) DIEString(String);
+    Die->addValue(Attribute, dwarf::DW_FORM_string, Value);
+  }
 }
 
 /// addLabel - Add a Dwarf label attribute data and value.
@@ -479,7 +490,7 @@ bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
 
 /// addConstantFPValue - Add constant value entry in variable DIE.
 bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
-  assert(MO.isFPImm() && "Invalid machine operand!");
+  assert (MO.isFPImm() && "Invalid machine operand!");
   DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
   APFloat FPImm = MO.getFPImm()->getValueAPF();
 
@@ -660,7 +671,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
   StringRef Name = BTy.getName();
   // Add name if not anonymous or intermediate type.
   if (!Name.empty())
-    addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
+    addString(&Buffer, dwarf::DW_AT_name, Name);
 
   if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) {
     Buffer.setTag(dwarf::DW_TAG_unspecified_type);
@@ -694,7 +705,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
 
   // Add name if not anonymous or intermediate type.
   if (!Name.empty())
-    addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
+    addString(&Buffer, dwarf::DW_AT_name, Name);
 
   // Add size if non-zero (derived types might be zero-sized.)
   if (Size)
@@ -791,8 +802,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
       else if (Element.isVariable()) {
         DIVariable DV(Element);
         ElemDie = new DIE(dwarf::DW_TAG_variable);
-        addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
-                  DV.getName());
+        addString(ElemDie, dwarf::DW_AT_name, DV.getName());
         addType(ElemDie, DV.getType());
         addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
         addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
@@ -836,7 +846,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
 
   // Add name if not anonymous or intermediate type.
   if (!Name.empty())
-    addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
+    addString(&Buffer, dwarf::DW_AT_name, Name);
 
   if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
       || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
@@ -868,7 +878,7 @@ CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
 
   ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
   addType(ParamDIE, TP.getType());
-  addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TP.getName());
+  addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
   return ParamDIE;
 }
 
@@ -883,7 +893,7 @@ CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV)
   ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
   addType(ParamDIE, TPV.getType());
   if (!TPV.getName().empty())
-    addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TPV.getName());
+    addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
   addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata, 
           TPV.getValue());
   return ParamDIE;
@@ -897,7 +907,7 @@ DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
   NDie = new DIE(dwarf::DW_TAG_namespace);
   insertDIE(NS, NDie);
   if (!NS.getName().empty())
-    addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
+    addString(NDie, dwarf::DW_AT_name, NS.getName());
   addSourceLine(NDie, NS);
   addToContextOwner(NDie, NS.getContext());
   return NDie;
@@ -932,7 +942,7 @@ DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
 
   StringRef LinkageName = SP.getLinkageName();
   if (!LinkageName.empty())
-    addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
+    addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
               getRealLinkageName(LinkageName));
 
   // If this DIE is going to refer declaration info using AT_specification
@@ -942,7 +952,7 @@ DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
 
   // Constructors and operators for anonymous aggregates do not have names.
   if (!SP.getName().empty())
-    addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
+    addString(SPDie, dwarf::DW_AT_name, SP.getName());
 
   addSourceLine(SPDie, SP);
 
@@ -1048,13 +1058,12 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
   insertDIE(N, VariableDIE);
 
   // Add name.
-  addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string,
-            GV.getDisplayName());
+  addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
   StringRef LinkageName = GV.getLinkageName();
   bool isGlobalVariable = GV.getGlobal() != NULL;
   if (!LinkageName.empty() && isGlobalVariable)
     addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
-              dwarf::DW_FORM_string, getRealLinkageName(LinkageName));
+              getRealLinkageName(LinkageName));
   // Add type.
   DIType GTy = GV.getType();
   addType(VariableDIE, GTy);
@@ -1170,7 +1179,7 @@ void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
 DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
   DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
   StringRef Name = ETy.getName();
-  addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
+  addString(Enumerator, dwarf::DW_AT_name, Name);
   int64_t Value = ETy.getEnumValue();
   addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
   return Enumerator;
@@ -1207,8 +1216,7 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
     addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
                             dwarf::DW_FORM_ref4, AbsDIE);
   else {
-    addString(VariableDie, dwarf::DW_AT_name, 
-                          dwarf::DW_FORM_string, Name);
+    addString(VariableDie, dwarf::DW_AT_name, Name);
     addSourceLine(VariableDie, DV->getVariable());
     addType(VariableDie, DV->getType());
   }
@@ -1303,7 +1311,7 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
   DIE *MemberDie = new DIE(DT.getTag());
   StringRef Name = DT.getName();
   if (!Name.empty())
-    addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
+    addString(MemberDie, dwarf::DW_AT_name, Name);
 
   addType(MemberDie, DT.getTypeDerivedFrom());
 
@@ -1377,16 +1385,13 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
   // Objective-C properties.
   StringRef PropertyName = DT.getObjCPropertyName();
   if (!PropertyName.empty()) {
-    addString(MemberDie, dwarf::DW_AT_APPLE_property_name, dwarf::DW_FORM_string,
-              PropertyName);
+    addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
     StringRef GetterName = DT.getObjCPropertyGetterName();
     if (!GetterName.empty())
-      addString(MemberDie, dwarf::DW_AT_APPLE_property_getter,
-                dwarf::DW_FORM_string, GetterName);
+      addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
     StringRef SetterName = DT.getObjCPropertySetterName();
     if (!SetterName.empty())
-      addString(MemberDie, dwarf::DW_AT_APPLE_property_setter,
-                dwarf::DW_FORM_string, SetterName);
+      addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
     unsigned PropertyAttributes = 0;
     if (DT.isReadOnlyObjCProperty())
       PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
index 785926579fa4046a743c617d0b6c08b423588df9..96d7902f06ecfaae483c58e38ebabc6fbb4d23bf 100644 (file)
@@ -150,8 +150,7 @@ public:
 
   /// addString - Add a string attribute data and value.
   ///
-  void addString(DIE *Die, unsigned Attribute, unsigned Form,
-                 const StringRef Str);
+  void addString(DIE *Die, unsigned Attribute, const StringRef Str);
 
   /// addLabel - Add a Dwarf label attribute data and value.
   ///
index 7ce9a06983b3570fb3cbb050b98db3be609097c6..1d5e05d8fdaa8cae58c019548e960988fd4d3a1b 100644 (file)
@@ -136,6 +136,10 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
 DwarfDebug::~DwarfDebug() {
 }
 
+MCSymbol *DwarfDebug::getStringPool() {
+  return Asm->GetTempSymbol("section_str");
+}
+
 MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
   std::pair<MCSymbol*, unsigned> &Entry = StringPool[Str];
   if (Entry.first) return Entry.first;
@@ -467,11 +471,10 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
 
   DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
   CompileUnit *NewCU = new CompileUnit(ID, Die, Asm, this);
-  NewCU->addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
-                   DIUnit.getProducer());
+  NewCU->addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer());
   NewCU->addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
                  DIUnit.getLanguage());
-  NewCU->addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
+  NewCU->addString(Die, dwarf::DW_AT_name, FN);
   // Use DW_AT_entry_pc instead of DW_AT_low_pc/DW_AT_high_pc pair. This
   // simplifies debug range entries.
   NewCU->addUInt(Die, dwarf::DW_AT_entry_pc, dwarf::DW_FORM_addr, 0);
@@ -484,14 +487,13 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
     NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
 
   if (!Dir.empty())
-    NewCU->addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
+    NewCU->addString(Die, dwarf::DW_AT_comp_dir, Dir);
   if (DIUnit.isOptimized())
     NewCU->addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
 
   StringRef Flags = DIUnit.getFlags();
   if (!Flags.empty())
-    NewCU->addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, 
-                     Flags);
+    NewCU->addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
   
   if (unsigned RVer = DIUnit.getRunTimeVersion())
     NewCU->addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
@@ -1796,6 +1798,7 @@ void DwarfDebug::emitDebugStr() {
 
     // Emit the string itself.
     Asm->OutStreamer.EmitBytes(Entries[i].second->getKey(), 0/*addrspace*/);
+    Asm->OutStreamer.EmitZeros(1, 0);
   }
 }
 
index b98ace2b0f3f55f30040a0fb012c2166836935be..b280fbb9303d9a22c3908895b368676c0be5e3ec 100644 (file)
@@ -216,8 +216,6 @@ class DwarfDebug {
   StringMap<std::pair<MCSymbol*, unsigned> > StringPool;
   unsigned NextStringPoolNumber;
   
-  MCSymbol *getStringPoolEntry(StringRef Str);
-
   /// SectionMap - Provides a unique id per text section.
   ///
   UniqueVector<const MCSection*> SectionMap;
@@ -504,6 +502,13 @@ public:
 
   /// createSubprogramDIE - Create new DIE using SP.
   DIE *createSubprogramDIE(DISubprogram SP);
+
+  /// getStringPool - returns the entry into the start of the pool.
+  MCSymbol *getStringPool();
+
+  /// getStringPoolEntry - returns an entry into the string pool with the given
+  /// string text.
+  MCSymbol *getStringPoolEntry(StringRef Str);
 };
 } // End of namespace llvm
 
index 95861bc61c270982d67c4f830db45fd9f8ba83fb..c330e740c2d6fa1fe5080993d76ffcb7c5849984 100644 (file)
@@ -91,6 +91,7 @@ MCAsmInfo::MCAsmInfo() {
   DwarfRequiresRelocationForSectionOffset = true;
   DwarfSectionOffsetDirective = 0;
   DwarfUsesLabelOffsetForRanges = true;
+  DwarfUsesRelocationsForStringPool = true;
   DwarfRegNumForCFI = false;
   HasMicrosoftFastStdCallMangling = false;
 
index b20e338f7904174f3f0e3048ca0274869a55cce8..537d0a35d92a8a73161f4072cea993c42384aeed 100644 (file)
@@ -66,4 +66,5 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
 
   DwarfRequiresRelocationForSectionOffset = false;
   DwarfUsesLabelOffsetForRanges = false;
+  DwarfUsesRelocationsForStringPool = false;
 }
index ee777cec54c8330c2fed6993afb83de7a6f81d4d..3972e680f47e2c9735a9535602de7408d9a2d9f4 100644 (file)
@@ -6,8 +6,8 @@ target triple = "thumbv7-apple-macosx10.6.7"
 ;CHECK: Ldebug_loc0:
 ;CHECK-NEXT:        .long   Ltmp1
 ;CHECK-NEXT:        .long   Ltmp2
-;CHECK-NEXT: Lset8 = Ltmp10-Ltmp9                    @ Loc expr size
-;CHECK-NEXT:        .short  Lset8
+;CHECK-NEXT: Lset[[N:[0-9]+]] = Ltmp10-Ltmp9        @ Loc expr size
+;CHECK-NEXT:        .short  Lset[[N]]
 ;CHECK-NEXT: Ltmp9:
 ;CHECK-NEXT:        .byte   144                     @ DW_OP_regx for S register
 
index 2ba12dfc568040bda71eb9c327d01e0fbd8eb123..b9b538a4c9e830c5ef2c100f11fab612a331ce4e 100644 (file)
@@ -5,17 +5,17 @@
 ; CHECK:       .byte   17                      ## DW_TAG_compile_unit
 ; CHECK-NEXT:  .byte   1                       ## DW_CHILDREN_yes
 ; CHECK-NEXT:  .byte   37                      ## DW_AT_producer
-; CHECK-NEXT:  .byte   8                       ## DW_FORM_string
+; CHECK-NEXT:  .byte   14                      ## DW_FORM_strp
 ; CHECK-NEXT:  .byte   19                      ## DW_AT_language
 ; CHECK-NEXT:  .byte   5                       ## DW_FORM_data2
 ; CHECK-NEXT:  .byte   3                       ## DW_AT_name
-; CHECK-NEXT:  .byte   8                       ## DW_FORM_string
+; CHECK-NEXT:  .byte   14                      ## DW_FORM_strp
 ; CHECK-NEXT:  .byte   82                      ## DW_AT_entry_pc
 ; CHECK-NEXT:  .byte   1                       ## DW_FORM_addr
 ; CHECK-NEXT:  .byte   16                      ## DW_AT_stmt_list
 ; CHECK-NEXT:  .byte   6                       ## DW_FORM_data4
 ; CHECK-NEXT:  .byte   27                      ## DW_AT_comp_dir
-; CHECK-NEXT:  .byte   8                       ## DW_FORM_string
+; CHECK-NEXT:  .byte   14                      ## DW_FORM_strp
 ; CHECK-NEXT:  .byte   225                     ## DW_AT_APPLE_optimized
 
 %struct.a = type { i32, %struct.a* }
index 3e9fa88fc77f73a99ca1a4e8218abeb26ae8e956..1452ff988ba1e908fa8f094bf15262338d627e47 100644 (file)
@@ -2,14 +2,14 @@
 
 ; ModuleID = 'test.c'
 
-@GLOBAL = common global i32 0, align 4
+@GLB = common global i32 0, align 4
 
 define i32 @f() nounwind {
-  %LOCAL = alloca i32, align 4
-  call void @llvm.dbg.declare(metadata !{i32* %LOCAL}, metadata !15), !dbg !17
-  %1 = load i32* @GLOBAL, align 4, !dbg !18
-  store i32 %1, i32* %LOCAL, align 4, !dbg !18
-  %2 = load i32* @GLOBAL, align 4, !dbg !19
+  %LOC = alloca i32, align 4
+  call void @llvm.dbg.declare(metadata !{i32* %LOC}, metadata !15), !dbg !17
+  %1 = load i32* @GLB, align 4, !dbg !18
+  store i32 %1, i32* %LOC, align 4, !dbg !18
+  %2 = load i32* @GLB, align 4, !dbg !19
   ret i32 %2, !dbg !19
 }
 
@@ -31,17 +31,17 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
 !11 = metadata !{i32 720932}                      ; [ DW_TAG_base_type ]
 !12 = metadata !{metadata !13}
 !13 = metadata !{metadata !14}
-!14 = metadata !{i32 720948, i32 0, null, metadata !"GLOBAL", metadata !"GLOBAL", metadata !"", metadata !6, i32 1, metadata !9, i32 0, i32 1, i32* @GLOBAL} ; [ DW_TAG_variable ]
-!15 = metadata !{i32 721152, metadata !16, metadata !"LOCAL", metadata !6, i32 4, metadata !9, i32 0, i32 0} ; [ DW_TAG_auto_variable ]
+!14 = metadata !{i32 720948, i32 0, null, metadata !"GLB", metadata !"GLB", metadata !"", metadata !6, i32 1, metadata !9, i32 0, i32 1, i32* @GLB} ; [ DW_TAG_variable ]
+!15 = metadata !{i32 721152, metadata !16, metadata !"LOC", metadata !6, i32 4, metadata !9, i32 0, i32 0} ; [ DW_TAG_auto_variable ]
 !16 = metadata !{i32 720907, metadata !5, i32 3, i32 9, metadata !6, i32 0} ; [ DW_TAG_lexical_block ]
 !17 = metadata !{i32 4, i32 9, metadata !16, null}
 !18 = metadata !{i32 4, i32 23, metadata !16, null}
 !19 = metadata !{i32 5, i32 5, metadata !16, null}
 
-; CHECK: .ascii         "GLOBAL"
+; CHECK: .ascii         "GLB"
 ; CHECK: .byte 1
 ; CHECK: .byte 1
 
-; CHECK: .ascii         "LOCAL"
+; CHECK: .ascii         "LOC"
 ; CHECK: .byte 1
 ; CHECK: .byte 4
diff --git a/test/DebugInfo/stringpool.ll b/test/DebugInfo/stringpool.ll
new file mode 100644 (file)
index 0000000..0a7c979
--- /dev/null
@@ -0,0 +1,54 @@
+; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefix=LINUX
+; RUN: llc -O0 -mtriple=x86_64-darwin < %s | FileCheck %s --check-prefix=DARWIN
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@x = common global i32 0, align 4
+@yyyyyyyy = common global i32 0, align 4
+
+!llvm.dbg.cu = !{!0}
+
+!0 = metadata !{i32 720913, i32 0, i32 12, metadata !"hello.c", metadata !"/home/nlewycky", metadata !"clang version 3.1 (trunk 143048)", i1 true, i1 true, metadata !"", i32 0, metadata !1, metadata !1, metadata !1, metadata !3} ; [ DW_TAG_compile_unit ]
+!1 = metadata !{metadata !2}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{metadata !5, metadata !8}
+!5 = metadata !{i32 720948, i32 0, null, metadata !"x", metadata !"x", metadata !"", metadata !6, i32 1, metadata !7, i32 0, i32 1, i32* @x} ; [ DW_TAG_variable ]
+!6 = metadata !{i32 720937, metadata !"hello.c", metadata !"/home/nlewycky", null} ; [ DW_TAG_file_type ]
+!7 = metadata !{i32 720932, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
+!8 = metadata !{i32 720948, i32 0, null, metadata !"yyyyyyyy", metadata !"yyyyyyyy", metadata !"", metadata !6, i32 2, metadata !7, i32 0, i32 1, i32* @yyyyyyyy} ; [ DW_TAG_variable ]
+
+; 120 is ASCII 'x'. Verify that we use it directly as its name and don't emit
+; a reference to the string pool.
+; LINUX:        .byte   120                     # DW_AT_name
+; DARWIN:       .byte   120                     ## DW_AT_name
+
+; Verify that we refer to 'yyyyyyyy' with a relocation.
+; LINUX:      .long   .Lstring{{[0-9]+}}      # DW_AT_name
+; LINUX-NEXT: .long   39                      # DW_AT_type
+; LINUX-NEXT: .byte   1                       # DW_AT_external
+; LINUX-NEXT: .byte   1                       # DW_AT_decl_file
+; LINUX-NEXT: .byte   2                       # DW_AT_decl_line
+; LINUX-NEXT: .byte   9                       # DW_AT_location
+; LINUX-NEXT: .byte   3
+; LINUX-NEXT: .quad   yyyyyyyy
+
+; Verify that we refer to 'yyyyyyyy' without a relocation.
+; DARWIN: Lset[[N:[0-9]+]] = Lstring{{[0-9]+}}-Lsection_str   ## DW_AT_name
+; DARWIN-NEXT:        .long   Lset[[N]]
+; DARWIN-NEXT:        .long   39                      ## DW_AT_type
+; DARWIN-NEXT:        .byte   1                       ## DW_AT_external
+; DARWIN-NEXT:        .byte   1                       ## DW_AT_decl_file
+; DARWIN-NEXT:        .byte   2                       ## DW_AT_decl_line
+; DARWIN-NEXT:        .byte   9                       ## DW_AT_location
+; DARWIN-NEXT:        .byte   3
+; DARWIN-NEXT:        .quad   _yyyyyyyy
+
+
+; Verify that "yyyyyyyy" ended up in the stringpool.
+; LINUX: .section .debug_str,"MS",@progbits,1
+; LINUX-NOT: .section
+; LINUX: yyyyyyyy
+; DARWIN: .section __DWARF,__debug_str,regular,debug
+; DARWIN-NOT: .section
+; DARWIN: yyyyyyyy