MC: Merge MCSymbol and MCSymbolData
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sat, 16 May 2015 00:03:06 +0000 (00:03 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sat, 16 May 2015 00:03:06 +0000 (00:03 +0000)
Turn `MCSymbolData` into a field inside of `MCSymbol`.  Keep all the old
API alive for now, so that consumers can be updated in a later commit.
This means we still temporarily need the back pointer from
`MCSymbolData` to `MCSymbol`, but I'll remove it in a follow-up.

This optimizes for object emission over assembly emission.  By removing
the `DenseMap` in `MCAssembler`, llc memory usage drops from around 1040
MB to 1001 MB (3.8%).

(I'm looking at `llc` memory usage on `verify-uselistorder.lto.opt.bc`;
see r236629 for details.)

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

include/llvm/MC/MCAssembler.h
include/llvm/MC/MCSymbol.h
lib/MC/MCAssembler.cpp

index ffe9d829214f42a02a3e0e1374a1360d5e051f11..a27482c32a96a5d15af6700500b6f79f869fd750 100644 (file)
@@ -676,7 +676,7 @@ class MCAssembler {
 
 public:
   typedef iplist<MCSectionData> SectionDataListType;
-  typedef std::vector<std::unique_ptr<MCSymbolData>> SymbolDataListType;
+  typedef std::vector<MCSymbolData *> SymbolDataListType;
 
   typedef SectionDataListType::const_iterator const_iterator;
   typedef SectionDataListType::iterator iterator;
@@ -734,11 +734,6 @@ private:
   // FIXME: Avoid this indirection?
   DenseMap<const MCSection *, MCSectionData *> SectionMap;
 
-  /// The map of symbols to their associated assembler backend data.
-  //
-  // FIXME: Avoid this indirection?
-  DenseMap<const MCSymbol *, MCSymbolData *> SymbolMap;
-
   std::vector<IndirectSymbolData> IndirectSymbols;
 
   std::vector<DataRegionData> DataRegions;
@@ -1039,7 +1034,7 @@ public:
   }
 
   bool hasSymbolData(const MCSymbol &Symbol) const {
-    return SymbolMap.lookup(&Symbol) != nullptr;
+    return Symbol.getUnsafeData().isInitialized();
   }
 
   MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
@@ -1048,23 +1043,18 @@ public:
   }
 
   const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
-    MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
-    assert(Entry && "Missing symbol data!");
-    return *Entry;
+    return Symbol.getData();
   }
 
   MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
                                       bool *Created = nullptr) {
-    MCSymbolData *&Entry = SymbolMap[&Symbol];
-
     if (Created)
-      *Created = !Entry;
-    if (!Entry) {
-      Symbols.emplace_back(new MCSymbolData(Symbol, nullptr, 0));
-      Entry = Symbols.back().get();
+      *Created = !hasSymbolData(Symbol);
+    if (!hasSymbolData(Symbol)) {
+      Symbol.getUnsafeData().initialize(Symbol, nullptr, 0);
+      Symbols.push_back(&Symbol.getData());
     }
-
-    return *Entry;
+    return Symbol.getData();
   }
 
   const_file_name_iterator file_names_begin() const {
index 08ee59c9b09c05c0e2d2e15eca035751f31f9676..67b064568259a20dd7ef74334ad2d84179da50e1 100644 (file)
@@ -27,7 +27,7 @@ class MCSection;
 class MCContext;
 class raw_ostream;
 
-// FIXME: Same concerns as with SectionData.
+// TODO: Merge completely with MCSymbol.
 class MCSymbolData {
   const MCSymbol *Symbol;
 
@@ -64,10 +64,12 @@ class MCSymbolData {
 public:
   // Only for use as sentinel.
   MCSymbolData();
-  MCSymbolData(const MCSymbol &Symbol, MCFragment *Fragment, uint64_t Offset);
+  void initialize(const MCSymbol &Symbol, MCFragment *Fragment,
+                  uint64_t Offset);
 
   /// \name Accessors
   /// @{
+  bool isInitialized() const { return Symbol; }
 
   const MCSymbol &getSymbol() const { return *Symbol; }
 
@@ -185,6 +187,8 @@ class MCSymbol {
   /// IsUsed - True if this symbol has been used.
   mutable unsigned IsUsed : 1;
 
+  mutable MCSymbolData Data;
+
 private: // MCContext creates and uniques these.
   friend class MCExpr;
   friend class MCContext;
@@ -204,6 +208,17 @@ public:
   /// getName - Get the symbol name.
   StringRef getName() const { return Name; }
 
+  /// Get associated symbol data.
+  MCSymbolData &getData() const {
+    assert(Data.isInitialized() && "Missing symbol data!");
+    return Data;
+  }
+
+  /// Get unsafe symbol data (even if uninitialized).
+  ///
+  /// Don't assert on uninitialized data; just return it.
+  MCSymbolData &getUnsafeData() const { return Data; }
+
   /// \name Accessors
   /// @{
 
index b4b9a47824199e35744154a0dbdd473fad6a4c48..ff230dfd9f9f246b520c43144cacd3665f589cb3 100644 (file)
@@ -360,10 +360,18 @@ void MCSectionData::setBundleLockState(BundleLockStateType NewState) {
 
 MCSymbolData::MCSymbolData() : Symbol(nullptr) {}
 
-MCSymbolData::MCSymbolData(const MCSymbol &Symbol, MCFragment *Fragment,
-                           uint64_t Offset)
-    : Symbol(&Symbol), Fragment(Fragment), Offset(Offset), SymbolSize(nullptr),
-      CommonAlign(-1U), Flags(0), Index(0) {}
+void MCSymbolData::initialize(const MCSymbol &Symbol, MCFragment *Fragment,
+                              uint64_t Offset) {
+  assert(!isInitialized() && "Expected uninitialized symbol");
+
+  this->Symbol = &Symbol;
+  this->Fragment.setPointer(Fragment);
+  this->Offset = Offset;
+  this->SymbolSize = nullptr;
+  this->CommonAlign = -1U;
+  this->Flags = 0;
+  this->Index = 0;
+}
 
 /* *** */
 
@@ -383,7 +391,6 @@ void MCAssembler::reset() {
   Sections.clear();
   Symbols.clear();
   SectionMap.clear();
-  SymbolMap.clear();
   IndirectSymbols.clear();
   DataRegions.clear();
   LinkerOptions.clear();