Add support for hashing location information for CU level hashes.
Add a testcase based on sret.cpp where we can now hash the entire
compile unit.

llvm-svn: 203319
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
index cff8f21..024ce0e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -13,8 +13,10 @@
 
 #define DEBUG_TYPE "dwarfdebug"
 
+#include "ByteStreamer.h"
 #include "DIEHash.h"
 #include "DIE.h"
+#include "DwarfDebug.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/CodeGen/AsmPrinter.h"
@@ -279,6 +281,28 @@
     Hash.update((uint64_t)cast<DIEInteger>(*I)->getValue());
 }
 
+// Hash the contents of a loclistptr class.
+void DIEHash::hashLocList(const DIELocList &LocList) {
+  SmallVectorImpl<DotDebugLocEntry>::const_iterator Start =
+      AP->getDwarfDebug()->getDebugLocEntries().begin();
+  Start += LocList.getValue();
+  HashingByteStreamer Streamer(*this);
+  for (SmallVectorImpl<DotDebugLocEntry>::const_iterator
+           I = Start,
+           E = AP->getDwarfDebug()->getDebugLocEntries().end();
+       I != E; ++I) {
+    const DotDebugLocEntry &Entry = *I;
+    // Go through the entries until we hit the end of the list,
+    // which is the next empty entry.
+    if (Entry.isEmpty())
+      return;
+    else if (Entry.isMerged())
+      continue;
+    else
+      AP->getDwarfDebug()->emitDebugLocEntry(Streamer, Entry);
+  }
+}
+
 // Hash an individual attribute \param Attr based on the type of attribute and
 // the form.
 void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
@@ -333,19 +357,23 @@
     break;
   case DIEValue::isBlock:
   case DIEValue::isLoc:
+  case DIEValue::isLocList:
     addULEB128('A');
     addULEB128(Attribute);
     addULEB128(dwarf::DW_FORM_block);
     if (isa<DIEBlock>(Value)) {
       addULEB128(cast<DIEBlock>(Value)->ComputeSize(AP));
       hashBlockData(cast<DIEBlock>(Value)->getValues());
-    } else {
+    } else if (isa<DIELoc>(Value)) {
       addULEB128(cast<DIELoc>(Value)->ComputeSize(AP));
       hashBlockData(cast<DIELoc>(Value)->getValues());
+    } else {
+      // We could add the block length, but that would take
+      // a bit of work and not add a lot of uniqueness
+      // to the hash in some way we could test.
+      hashLocList(*cast<DIELocList>(Value));
     }
     break;
-    // FIXME: Handle loclistptr.
-  case DIEValue::isLocList:
     // FIXME: It's uncertain whether or not we should handle this at the moment.
   case DIEValue::isExpr:
   case DIEValue::isLabel:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.h b/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
index c3db2d0..48f1601 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -137,6 +137,9 @@
   /// DW_FORM_exprloc.
   void hashBlockData(const SmallVectorImpl<DIEValue *> &Values);
 
+  /// \brief Hashes the contents pointed to in the .debug_loc section.
+  void hashLocList(const DIELocList &LocList);
+
   /// \brief Hashes an individual attribute.
   void hashAttribute(AttrEntry Attr, dwarf::Tag Tag);
 
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 0dadb73..b8cfdd3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -588,9 +588,6 @@
   /// \brief Emit visible names into a debug str section.
   void emitDebugStr();
 
-  /// \brief Emit an entry for the debug loc section.
-  void emitDebugLocEntry(ByteStreamer &Streamer, const DotDebugLocEntry &Entry);
-
   /// \brief Emit visible names into a debug loc section.
   void emitDebugLoc();
 
@@ -761,6 +758,15 @@
   /// Returns the section symbol for the .debug_loc section.
   MCSymbol *getDebugLocSym() const { return DwarfDebugLocSectionSym; }
 
+  /// Returns the entries for the .debug_loc section.
+  const SmallVectorImpl<DotDebugLocEntry> &getDebugLocEntries() const {
+    return DotDebugLocEntries;
+  }
+
+  /// \brief Emit an entry for the debug loc section. This can be used to
+  /// handle an entry that's going to be emitted into the debug loc section.
+  void emitDebugLocEntry(ByteStreamer &Streamer, const DotDebugLocEntry &Entry);
+
   /// Find the MDNode for the given reference.
   template <typename T> T resolve(DIRef<T> Ref) const {
     return Ref.resolve(TypeIdentifierMap);