@@ -160,8 +160,19 @@ class Remangler {
160160
161161 static const size_t MaxNumWords = 26 ;
162162
163+ // An efficient hash-map implementation in the spirit of llvm's SmallPtrSet:
164+ // The first 16 substitutions are stored in an inline-allocated array to avoid
165+ // malloc calls in the common case.
166+ // Lookup is still reasonable fast because there are max 16 elements in the
167+ // array.
168+ static const size_t InlineSubstCapacity = 16 ;
169+ SubstitutionEntry InlineSubstitutions[InlineSubstCapacity];
170+ size_t NumInlineSubsts = 0 ;
171+
172+ // The "overflow" for InlineSubstitutions. Only if InlineSubstitutions is
173+ // full, new substitutions are stored in OverflowSubstitutions.
163174 std::unordered_map<SubstitutionEntry, unsigned ,
164- SubstitutionEntry::Hasher> Substitutions ;
175+ SubstitutionEntry::Hasher> OverflowSubstitutions ;
165176
166177 SubstitutionMerging SubstMerging;
167178
@@ -180,6 +191,24 @@ class Remangler {
180191 Words.push_back (word, Factory);
181192 }
182193
194+ // Find a substitution and return its index.
195+ // Returns -1 if no substitution is found.
196+ int findSubstitution (const SubstitutionEntry &entry) {
197+ // First search in InlineSubstitutions.
198+ SubstitutionEntry *result
199+ = std::find (InlineSubstitutions, InlineSubstitutions + NumInlineSubsts,
200+ entry);
201+ if (result != InlineSubstitutions + NumInlineSubsts)
202+ return result - InlineSubstitutions;
203+
204+ // Then search in OverflowSubstitutions.
205+ auto it = OverflowSubstitutions.find (entry);
206+ if (it == OverflowSubstitutions.end ())
207+ return -1 ;
208+
209+ return it->second ;
210+ }
211+
183212 StringRef getBufferStr () const { return Buffer.getStringRef (); }
184213
185214 void resetBuffer (size_t toPos) { Buffer.resetSize (toPos); }
@@ -343,11 +372,10 @@ bool Remangler::trySubstitution(Node *node, SubstitutionEntry &entry,
343372 // Go ahead and initialize the substitution entry.
344373 entry.setNode (node, treatAsIdentifier);
345374
346- auto it = Substitutions. find (entry);
347- if (it == Substitutions. end () )
375+ int Idx = findSubstitution (entry);
376+ if (Idx < 0 )
348377 return false ;
349378
350- unsigned Idx = it->second ;
351379 if (Idx >= 26 ) {
352380 Buffer << ' A' ;
353381 mangleIndex (Idx - 26 );
@@ -361,17 +389,16 @@ bool Remangler::trySubstitution(Node *node, SubstitutionEntry &entry,
361389}
362390
363391void Remangler::addSubstitution (const SubstitutionEntry &entry) {
364- unsigned Idx = Substitutions.size ();
365- #if false
366- llvm::outs () << " add subst " ;
367- if (Idx < 26 ) {
368- llvm::outs () << char (' A' + Idx);
369- } else {
370- llvm::outs () << Idx;
392+ assert (findSubstitution (entry) < 0 );
393+ if (NumInlineSubsts < InlineSubstCapacity) {
394+ // There is still free space in NumInlineSubsts.
395+ assert (OverflowSubstitutions.empty ());
396+ InlineSubstitutions[NumInlineSubsts++] = entry;
397+ return ;
371398 }
372- llvm::outs () << " at pos " << getBufferStr (). size () << ' \n ' ;
373- # endif
374- auto result = Substitutions .insert ({entry, Idx});
399+ // We have to add the entry to OverflowSubstitutions.
400+ unsigned Idx = OverflowSubstitutions. size () + InlineSubstCapacity;
401+ auto result = OverflowSubstitutions .insert ({entry, Idx});
375402 assert (result.second );
376403 (void ) result;
377404}
0 commit comments