@@ -552,8 +552,11 @@ class SymbolAlias {
552552 // / Print this alias to the given stream.
553553 void print (raw_ostream &os) const {
554554 os << (isType ? " !" : " #" ) << name;
555- if (suffixIndex)
555+ if (suffixIndex) {
556+ if (isdigit (name.back ()))
557+ os << ' _' ;
556558 os << suffixIndex;
559+ }
557560 }
558561
559562 // / Returns true if this is a type alias.
@@ -659,6 +662,12 @@ class AliasInitializer {
659662 template <typename T>
660663 void generateAlias (T symbol, InProgressAliasInfo &alias, bool canBeDeferred);
661664
665+ // / Uniques the given alias name within the printer by generating name index
666+ // / used as alias name suffix.
667+ static unsigned
668+ uniqueAliasNameIndex (StringRef alias, llvm::StringMap<unsigned > &nameCounts,
669+ llvm::StringSet<llvm::BumpPtrAllocator &> &usedAliases);
670+
662671 // / Given a collection of aliases and symbols, initialize a mapping from a
663672 // / symbol to a given alias.
664673 static void initializeAliases (
@@ -1025,8 +1034,7 @@ class DummyAliasDialectAsmPrinter : public DialectAsmPrinter {
10251034// / the string needs to be modified in any way, the provided buffer is used to
10261035// / store the new copy,
10271036static StringRef sanitizeIdentifier (StringRef name, SmallString<16 > &buffer,
1028- StringRef allowedPunctChars = " $._-" ,
1029- bool allowTrailingDigit = true ) {
1037+ StringRef allowedPunctChars = " $._-" ) {
10301038 assert (!name.empty () && " Shouldn't have an empty name here" );
10311039
10321040 auto validChar = [&](char ch) {
@@ -1053,14 +1061,6 @@ static StringRef sanitizeIdentifier(StringRef name, SmallString<16> &buffer,
10531061 return buffer;
10541062 }
10551063
1056- // If the name ends with a trailing digit, add a '_' to avoid potential
1057- // conflicts with autogenerated ID's.
1058- if (!allowTrailingDigit && isdigit (name.back ())) {
1059- copyNameToBuffer ();
1060- buffer.push_back (' _' );
1061- return buffer;
1062- }
1063-
10641064 // Check to see that the name consists of only valid identifier characters.
10651065 for (char ch : name) {
10661066 if (!validChar (ch)) {
@@ -1073,6 +1073,37 @@ static StringRef sanitizeIdentifier(StringRef name, SmallString<16> &buffer,
10731073 return name;
10741074}
10751075
1076+ unsigned AliasInitializer::uniqueAliasNameIndex (
1077+ StringRef alias, llvm::StringMap<unsigned > &nameCounts,
1078+ llvm::StringSet<llvm::BumpPtrAllocator &> &usedAliases) {
1079+ // Get nameIndex that will not generate conflicting name.
1080+ unsigned nameIndex = 0 ;
1081+ if (!usedAliases.count (alias)) {
1082+ usedAliases.insert (alias);
1083+ } else {
1084+ // Otherwise, we had a conflict - probe until we find a unique name.
1085+ SmallString<64 > probeAlias (alias);
1086+ // alias with trailing digit will be printed as _N
1087+ if (isdigit (alias.back ()))
1088+ probeAlias.push_back (' _' );
1089+ // nameCounts start from 1 because 0 is not printed in SymbolAlias.
1090+ if (nameCounts[probeAlias] == 0 )
1091+ nameCounts[probeAlias] = 1 ;
1092+ // This is guaranteed to terminate (and usually in a single iteration)
1093+ // because it generates new names by incrementing nameCounts.
1094+ while (true ) {
1095+ nameIndex = nameCounts[probeAlias]++;
1096+ probeAlias += llvm::utostr (nameIndex);
1097+ if (!usedAliases.count (probeAlias)) {
1098+ usedAliases.insert (probeAlias);
1099+ break ;
1100+ }
1101+ probeAlias.resize (alias.size () + isdigit (alias.back ()) ? 1 : 0 );
1102+ }
1103+ }
1104+ return nameIndex;
1105+ }
1106+
10761107// / Given a collection of aliases and symbols, initialize a mapping from a
10771108// / symbol to a given alias.
10781109void AliasInitializer::initializeAliases (
@@ -1084,12 +1115,17 @@ void AliasInitializer::initializeAliases(
10841115 return lhs.second < rhs.second ;
10851116 });
10861117
1118+ // This keeps track of all of the non-numeric names that are in flight,
1119+ // allowing us to check for duplicates.
1120+ llvm::BumpPtrAllocator usedAliasAllocator;
1121+ llvm::StringSet<llvm::BumpPtrAllocator &> usedAliases (usedAliasAllocator);
1122+
10871123 llvm::StringMap<unsigned > nameCounts;
10881124 for (auto &[symbol, aliasInfo] : unprocessedAliases) {
10891125 if (!aliasInfo.alias )
10901126 continue ;
10911127 StringRef alias = *aliasInfo.alias ;
1092- unsigned nameIndex = nameCounts[ alias]++ ;
1128+ unsigned nameIndex = uniqueAliasNameIndex ( alias, nameCounts, usedAliases) ;
10931129 symbolToAlias.insert (
10941130 {symbol, SymbolAlias (alias, nameIndex, aliasInfo.isType ,
10951131 aliasInfo.canBeDeferred )});
@@ -1196,8 +1232,7 @@ void AliasInitializer::generateAlias(T symbol, InProgressAliasInfo &alias,
11961232
11971233 SmallString<16 > tempBuffer;
11981234 StringRef name =
1199- sanitizeIdentifier (nameBuffer, tempBuffer, /* allowedPunctChars=*/ " $_-" ,
1200- /* allowTrailingDigit=*/ false );
1235+ sanitizeIdentifier (nameBuffer, tempBuffer, /* allowedPunctChars=*/ " $_-" );
12011236 name = name.copy (aliasAllocator);
12021237 alias = InProgressAliasInfo (name);
12031238}
0 commit comments