From 9f44724be058d17944dcd9ef6a6b57734b3744b8 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 1 Dec 2010 20:46:11 +0000 Subject: [PATCH] Rename temporary symbols if they conflict with artificial symbols created by the assembler. This was blocking parsing any large .s produced by clang for example. Fixes PR8596. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120603 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCContext.h | 7 ++++++ lib/MC/MCContext.cpp | 45 ++++++++++++++++++++++++++++--------- test/MC/AsmParser/rename.s | 10 +++++++++ 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 test/MC/AsmParser/rename.s diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index e7c3967d2d3..ae502baa1dd 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -45,6 +45,10 @@ namespace llvm { /// Symbols - Bindings of names to symbols. StringMap Symbols; + /// UsedNames - Keeps tracks of names that were used both for used declared + /// and artificial symbols. + StringMap UsedNames; + /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary /// symbol. unsigned NextUniqueID; @@ -91,6 +95,9 @@ namespace llvm { BumpPtrAllocator Allocator; void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; + + MCSymbol *CreateSymbol(StringRef Name); + public: explicit MCContext(const MCAsmInfo &MAI); ~MCContext(); diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 23df840fb39..a1bc9d8b6f5 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -57,19 +57,41 @@ MCContext::~MCContext() { MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) { assert(!Name.empty() && "Normal symbols cannot be unnamed!"); - // Determine whether this is an assembler temporary or normal label. - bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix()); - // Do the lookup and get the entire StringMapEntry. We want access to the // key if we are creating the entry. StringMapEntry &Entry = Symbols.GetOrCreateValue(Name); - if (Entry.getValue()) return Entry.getValue(); + MCSymbol *Sym = Entry.getValue(); + + if (Sym) + return Sym; + + Sym = CreateSymbol(Name); + Entry.setValue(Sym); + return Sym; +} + +MCSymbol *MCContext::CreateSymbol(StringRef Name) { + // Determine whether this is an assembler temporary or normal label. + bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix()); + + StringMapEntry *NameEntry = &UsedNames.GetOrCreateValue(Name); + if (NameEntry->getValue()) { + assert(isTemporary && "Cannot rename non temporary symbols"); + SmallString<128> NewName; + do { + Twine T = Name + Twine(NextUniqueID++); + T.toVector(NewName); + StringRef foo = NewName; + NameEntry = &UsedNames.GetOrCreateValue(foo); + } while (NameEntry->getValue()); + } + NameEntry->setValue(true); // Ok, the entry doesn't already exist. Have the MCSymbol object itself refer - // to the copy of the string that is embedded in the StringMapEntry. - MCSymbol *Result = new (*this) MCSymbol(Entry.getKey(), isTemporary); - Entry.setValue(Result); - return Result; + // to the copy of the string that is embedded in the UsedNames entry. + MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary); + + return Result; } MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) { @@ -79,8 +101,11 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) { } MCSymbol *MCContext::CreateTempSymbol() { - return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) + - "tmp" + Twine(NextUniqueID++)); + SmallString<128> NameSV; + Twine Name = Twine(MAI.getPrivateGlobalPrefix()) + "tmp" + + Twine(NextUniqueID++); + Name.toVector(NameSV); + return CreateSymbol(NameSV); } unsigned MCContext::NextInstance(int64_t LocalLabelVal) { diff --git a/test/MC/AsmParser/rename.s b/test/MC/AsmParser/rename.s new file mode 100644 index 00000000000..64ca5153812 --- /dev/null +++ b/test/MC/AsmParser/rename.s @@ -0,0 +1,10 @@ +// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s + + .size bar, . - bar +.Ltmp0: + .size foo, .Ltmp0 - foo + +// CHECK: .Ltmp0: +// CHECK: .size bar, .Ltmp0-bar +// CHECK: .Ltmp01 +// CHECK: .size foo, .Ltmp01-foo