[cfe-commits] r99012 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/Mangle.h test/CodeGenCXX/attr.cpp

John McCall rjmccall at apple.com
Fri Mar 19 16:29:14 PDT 2010


Author: rjmccall
Date: Fri Mar 19 18:29:14 2010
New Revision: 99012

URL: http://llvm.org/viewvc/llvm-project?rev=99012&view=rev
Log:
Change CodeGenModule to rely on the Module's symbol table instead of
shadowing it in the GlobalDeclMap.  Eliminates the string-uniquing
requirement for mangled names, which should help C++ codegen times a little.
Forces us to do string lookups instead of pointer lookups, which might hurt
codegen times a little across the board.  We'll see how it plays out.

Removing the string-uniquing requirement implicitly fixes any bugs like
PR6635 which arose from the fact that we had multiple uniquing tables for
different kinds of identifiers.


Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/Mangle.h
    cfe/trunk/test/CodeGenCXX/attr.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=99012&r1=99011&r2=99012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Mar 19 18:29:14 2010
@@ -165,19 +165,21 @@
     new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
 
   // Switch any previous uses to the alias.
-  const char *MangledName = getMangledName(AliasDecl);
-  llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
+  MangleBuffer MangledName;
+  getMangledName(MangledName, AliasDecl);
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
   if (Entry) {
     assert(Entry->isDeclaration() && "definition already exists for alias");
     assert(Entry->getType() == AliasType &&
            "declaration exists with different type");
+    Alias->takeName(Entry);
     Entry->replaceAllUsesWith(Alias);
     Entry->eraseFromParent();
+  } else {
+    Alias->setName(MangledName.getString());
   }
-  Entry = Alias;
 
   // Finally, set up the alias with its proper name and attributes.
-  Alias->setName(MangledName);
   SetCommonAttributes(AliasDecl.getDecl(), Alias);
 
   return false;
@@ -214,8 +216,9 @@
 llvm::GlobalValue *
 CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
                                        CXXCtorType Type) {
-  const char *Name = getMangledCXXCtorName(D, Type);
-  if (llvm::GlobalValue *V = GlobalDeclMap[Name])
+  MangleBuffer Name;
+  getMangledCXXCtorName(Name, D, Type);
+  if (llvm::GlobalValue *V = GetGlobalValue(Name))
     return V;
 
   const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>();
@@ -226,13 +229,10 @@
                       GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
 }
 
-const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D,
-                                                 CXXCtorType Type) {
-  llvm::SmallString<256> Name;
-  getMangleContext().mangleCXXCtor(D, Type, Name);
-
-  Name += '\0';
-  return UniqueMangledName(Name.begin(), Name.end());
+void CodeGenModule::getMangledCXXCtorName(MangleBuffer &Name,
+                                          const CXXConstructorDecl *D,
+                                          CXXCtorType Type) {
+  getMangleContext().mangleCXXCtor(D, Type, Name.getBuffer());
 }
 
 void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
@@ -279,8 +279,9 @@
 llvm::GlobalValue *
 CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
                                       CXXDtorType Type) {
-  const char *Name = getMangledCXXDtorName(D, Type);
-  if (llvm::GlobalValue *V = GlobalDeclMap[Name])
+  MangleBuffer Name;
+  getMangledCXXDtorName(Name, D, Type);
+  if (llvm::GlobalValue *V = GetGlobalValue(Name))
     return V;
 
   const llvm::FunctionType *FTy =
@@ -290,13 +291,10 @@
                       GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
 }
 
-const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
-                                                 CXXDtorType Type) {
-  llvm::SmallString<256> Name;
-  getMangleContext().mangleCXXDtor(D, Type, Name);
-
-  Name += '\0';
-  return UniqueMangledName(Name.begin(), Name.end());
+void CodeGenModule::getMangledCXXDtorName(MangleBuffer &Name,
+                                          const CXXDestructorDecl *D,
+                                          CXXDtorType Type) {
+  getMangleContext().mangleCXXDtor(D, Type, Name.getBuffer());
 }
 
 llvm::Constant *
@@ -470,12 +468,10 @@
                                           OutName);
   else
     getMangleContext().mangleThunk(MD, ThisAdjustment, OutName);
-  OutName += '\0';
-  const char* Name = UniqueMangledName(OutName.begin(), OutName.end());
 
   // Get function for mangled name
   const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD);
-  return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
+  return GetOrCreateLLVMFunction(OutName, Ty, GlobalDecl());
 }
 
 llvm::Constant *
@@ -484,10 +480,8 @@
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
 
   // Compute mangled name
-  llvm::SmallString<256> OutName;
-  getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName);
-  OutName += '\0';
-  const char* Name = UniqueMangledName(OutName.begin(), OutName.end());
+  llvm::SmallString<256> Name;
+  getMangleContext().mangleCovariantThunk(MD, Adjustment, Name);
 
   // Get function for mangled name
   const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD);
@@ -528,9 +522,6 @@
         llvm::Constant *SubExpr =
             cast<llvm::ConstantExpr>(FnConst)->getOperand(0);
         llvm::Function *OldFn = cast<llvm::Function>(SubExpr);
-        std::string Name = OldFn->getNameStr();
-        GlobalDeclMap.erase(UniqueMangledName(Name.data(),
-                                              Name.data() + Name.size() + 1));
         llvm::Constant *NewFnConst;
         if (!ReturnAdjustment.isEmpty())
           NewFnConst = GetAddrOfCovariantThunk(GD, CoAdj);

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=99012&r1=99011&r2=99012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Mar 19 18:29:14 2010
@@ -569,13 +569,13 @@
     isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
   
   llvm::StringRef MethodName = getFunctionName(Method);
-  llvm::StringRef MethodLinkageName;
   llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit);
   
   // Since a single ctor/dtor corresponds to multiple functions, it doesn't
   // make sense to give a single ctor/dtor a linkage name.
+  MangleBuffer MethodLinkageName;
   if (!IsCtorOrDtor)
-    MethodLinkageName = CGM.getMangledName(Method);
+    CGM.getMangledName(MethodLinkageName, Method);
 
   SourceManager &SM = CGM.getContext().getSourceManager();
 
@@ -1307,7 +1307,7 @@
                                     CGBuilderTy &Builder) {
 
   llvm::StringRef Name;
-  llvm::StringRef LinkageName;
+  MangleBuffer LinkageName;
 
   const Decl *D = GD.getDecl();
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
@@ -1326,11 +1326,11 @@
     if (!Name.empty() && Name[0] == '\01')
       Name = Name.substr(1);
     // Use mangled name as linkage name for c/c++ functions.
-    LinkageName = CGM.getMangledName(GD);
+    CGM.getMangledName(LinkageName, GD);
   } else {
     // Use llvm function name as linkage name.
     Name = Fn->getName();
-    LinkageName = Name;
+    LinkageName.setString(Name);
     if (!Name.empty() && Name[0] == '\01')
       Name = Name.substr(1);
   }

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=99012&r1=99011&r2=99012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Mar 19 18:29:14 2010
@@ -103,13 +103,18 @@
 static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
                                      const char *Separator) {
   CodeGenModule &CGM = CGF.CGM;
-  if (CGF.getContext().getLangOptions().CPlusPlus)
-    return CGM.getMangledName(&D);
+  if (CGF.getContext().getLangOptions().CPlusPlus) {
+    MangleBuffer Name;
+    CGM.getMangledName(Name, &D);
+    return Name.getString().str();
+  }
   
   std::string ContextName;
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl))
-    ContextName = CGM.getMangledName(FD);
-  else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
+    MangleBuffer Name;
+    CGM.getMangledName(Name, FD);
+    ContextName = Name.getString().str();
+  } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
     ContextName = CGF.CurFn->getName();
   else
     // FIXME: What about in a block??

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=99012&r1=99011&r2=99012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Mar 19 18:29:14 2010
@@ -163,15 +163,15 @@
   }
 }
 
-const char *CodeGenModule::getMangledName(const GlobalDecl &GD) {
+void CodeGenModule::getMangledName(MangleBuffer &Buffer, GlobalDecl GD) {
   const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
 
   if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
-    return getMangledCXXCtorName(D, GD.getCtorType());
+    return getMangledCXXCtorName(Buffer, D, GD.getCtorType());
   if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
-    return getMangledCXXDtorName(D, GD.getDtorType());
+    return getMangledCXXDtorName(Buffer, D, GD.getDtorType());
 
-  return getMangledName(ND);
+  return getMangledName(Buffer, ND);
 }
 
 /// \brief Retrieves the mangled name for the given declaration.
@@ -180,23 +180,19 @@
 /// const char* containing the mangled name.  Otherwise, returns
 /// the unmangled name.
 ///
-const char *CodeGenModule::getMangledName(const NamedDecl *ND) {
+void CodeGenModule::getMangledName(MangleBuffer &Buffer,
+                                   const NamedDecl *ND) {
   if (!getMangleContext().shouldMangleDeclName(ND)) {
     assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
-    return ND->getNameAsCString();
+    Buffer.setString(ND->getNameAsCString());
+    return;
   }
 
-  llvm::SmallString<256> Name;
-  getMangleContext().mangleName(ND, Name);
-  Name += '\0';
-  return UniqueMangledName(Name.begin(), Name.end());
+  getMangleContext().mangleName(ND, Buffer.getBuffer());
 }
 
-const char *CodeGenModule::UniqueMangledName(const char *NameStart,
-                                             const char *NameEnd) {
-  assert(*(NameEnd - 1) == '\0' && "Mangled name must be null terminated!");
-
-  return MangledNames.GetOrCreateValue(NameStart, NameEnd).getKeyData();
+llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) {
+  return getModule().getNamedValue(Name);
 }
 
 /// AddGlobalCtor - Add a function to the list that will be called before
@@ -505,11 +501,12 @@
     GlobalDecl D = DeferredDeclsToEmit.back();
     DeferredDeclsToEmit.pop_back();
 
-    // The mangled name for the decl must have been emitted in GlobalDeclMap.
     // Look it up to see if it was defined with a stronger definition (e.g. an
     // extern inline function with a strong function redefinition).  If so,
     // just ignore the deferred decl.
-    llvm::GlobalValue *CGRef = GlobalDeclMap[getMangledName(D)];
+    MangleBuffer Name;
+    getMangledName(Name, D);
+    llvm::GlobalValue *CGRef = GetGlobalValue(Name);
     assert(CGRef && "Deferred decl wasn't referenced?");
 
     if (!CGRef->isDeclaration())
@@ -644,18 +641,14 @@
 
   const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType());
 
-  // Unique the name through the identifier table.
-  const char *AliaseeName =
-    getContext().Idents.get(AA->getAliasee()).getNameStart();
-
   // See if there is already something with the target's name in the module.
-  llvm::GlobalValue *Entry = GlobalDeclMap[AliaseeName];
+  llvm::GlobalValue *Entry = GetGlobalValue(AA->getAliasee());
 
   llvm::Constant *Aliasee;
   if (isa<llvm::FunctionType>(DeclTy))
-    Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl());
+    Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
   else
-    Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
+    Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
                                     llvm::PointerType::getUnqual(DeclTy), 0);
   if (!Entry) {
     llvm::GlobalValue* F = cast<llvm::GlobalValue>(Aliasee);
@@ -676,7 +669,7 @@
   // If this is an alias definition (which otherwise looks like a declaration)
   // emit it now.
   if (Global->hasAttr<AliasAttr>())
-    return EmitAliasDefinition(Global);
+    return EmitAliasDefinition(GD);
 
   // Ignore declarations, they will be emitted on their first use.
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
@@ -696,8 +689,9 @@
   if (MayDeferGeneration(Global)) {
     // If the value has already been used, add it directly to the
     // DeferredDeclsToEmit list.
-    const char *MangledName = getMangledName(GD);
-    if (GlobalDeclMap.count(MangledName))
+    MangleBuffer MangledName;
+    getMangledName(MangledName, GD);
+    if (GetGlobalValue(MangledName))
       DeferredDeclsToEmit.push_back(GD);
     else {
       // Otherwise, remember that we saw a deferred decl with this name.  The
@@ -753,11 +747,12 @@
 ///
 /// If D is non-null, it specifies a decl that correspond to this.  This is used
 /// to set the attributes on the function when it is first created.
-llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
-                                                       const llvm::Type *Ty,
-                                                       GlobalDecl D) {
+llvm::Constant *
+CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName,
+                                       const llvm::Type *Ty,
+                                       GlobalDecl D) {
   // Lookup the entry, lazily creating it if necessary.
-  llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
   if (Entry) {
     if (WeakRefReferences.count(Entry)) {
       const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl());
@@ -786,17 +781,15 @@
   }
   llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
                                              llvm::Function::ExternalLinkage,
-                                             "", &getModule());
-  F->setName(MangledName);
+                                             MangledName, &getModule());
+  assert(F->getName() == MangledName && "name was uniqued!");
   if (D.getDecl())
     SetFunctionAttributes(D, F, IsIncompleteFunction);
-  Entry = F;
 
   // This is the first use or definition of a mangled name.  If there is a
   // deferred decl with this name, remember that we need to emit it at the end
   // of the file.
-  llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
-    DeferredDecls.find(MangledName);
+  llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
   if (DDI != DeferredDecls.end()) {
     // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
     // list, and remove it from DeferredDecls (since we don't need it anymore).
@@ -839,16 +832,16 @@
   // If there was no specific requested type, just convert it now.
   if (!Ty)
     Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
-  return GetOrCreateLLVMFunction(getMangledName(GD), Ty, GD);
+  MangleBuffer MangledName;
+  getMangledName(MangledName, GD);
+  return GetOrCreateLLVMFunction(MangledName, Ty, GD);
 }
 
 /// CreateRuntimeFunction - Create a new runtime function with the specified
 /// type and name.
 llvm::Constant *
 CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
-                                     const char *Name) {
-  // Convert Name to be a uniqued string from the IdentifierInfo table.
-  Name = getContext().Idents.get(Name).getNameStart();
+                                     llvm::StringRef Name) {
   return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl());
 }
 
@@ -870,11 +863,12 @@
 ///
 /// If D is non-null, it specifies a decl that correspond to this.  This is used
 /// to set the attributes on the global when it is first created.
-llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
-                                                     const llvm::PointerType*Ty,
-                                                     const VarDecl *D) {
+llvm::Constant *
+CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
+                                     const llvm::PointerType *Ty,
+                                     const VarDecl *D) {
   // Lookup the entry, lazily creating it if necessary.
-  llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
   if (Entry) {
     if (WeakRefReferences.count(Entry)) {
       if (D && !D->hasAttr<WeakAttr>())
@@ -893,8 +887,7 @@
   // This is the first use or definition of a mangled name.  If there is a
   // deferred decl with this name, remember that we need to emit it at the end
   // of the file.
-  llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
-    DeferredDecls.find(MangledName);
+  llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
   if (DDI != DeferredDecls.end()) {
     // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
     // list, and remove it from DeferredDecls (since we don't need it anymore).
@@ -905,9 +898,8 @@
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
                              llvm::GlobalValue::ExternalLinkage,
-                             0, "", 0,
+                             0, MangledName, 0,
                              false, Ty->getAddressSpace());
-  GV->setName(MangledName);
 
   // Handle things which are present even on external declarations.
   if (D) {
@@ -926,7 +918,7 @@
     GV->setThreadLocal(D->isThreadSpecified());
   }
 
-  return Entry = GV;
+  return GV;
 }
 
 
@@ -943,16 +935,17 @@
 
   const llvm::PointerType *PTy =
     llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
-  return GetOrCreateLLVMGlobal(getMangledName(D), PTy, D);
+
+  MangleBuffer MangledName;
+  getMangledName(MangledName, D);
+  return GetOrCreateLLVMGlobal(MangledName, PTy, D);
 }
 
 /// CreateRuntimeVariable - Create a new runtime global variable with the
 /// specified type and name.
 llvm::Constant *
 CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,
-                                     const char *Name) {
-  // Convert Name to be a uniqued string from the IdentifierInfo table.
-  Name = getContext().Idents.get(Name).getNameStart();
+                                     llvm::StringRef Name) {
   return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0);
 }
 
@@ -963,8 +956,9 @@
     // If we have not seen a reference to this variable yet, place it
     // into the deferred declarations table to be emitted if needed
     // later.
-    const char *MangledName = getMangledName(D);
-    if (GlobalDeclMap.count(MangledName) == 0) {
+    MangleBuffer MangledName;
+    getMangledName(MangledName, D);
+    if (!GetGlobalValue(MangledName)) {
       DeferredDecls[MangledName] = D;
       return;
     }
@@ -1133,12 +1127,11 @@
       GV->getType()->getElementType() != InitType ||
       GV->getType()->getAddressSpace() != ASTTy.getAddressSpace()) {
 
-    // Remove the old entry from GlobalDeclMap so that we'll create a new one.
-    GlobalDeclMap.erase(getMangledName(D));
+    // Move the old entry aside so that we'll create a new one.
+    Entry->setName(llvm::StringRef());
 
     // Make a new global with the correct type, this is now guaranteed to work.
     GV = cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, InitType));
-    GV->takeName(cast<llvm::GlobalValue>(Entry));
 
     // Replace all uses of the old global with the new global
     llvm::Constant *NewPtrForOldDecl =
@@ -1296,11 +1289,10 @@
     //
     // This happens if there is a prototype for a function
     // (e.g. "int f()") and then a definition of a different type
-    // (e.g. "int f(int x)").  Start by making a new function of the
-    // correct type, RAUW, then steal the name.
-    GlobalDeclMap.erase(getMangledName(D));
+    // (e.g. "int f(int x)").  Move the old function aside so that it
+    // doesn't interfere with GetAddrOfFunction.
+    OldFn->setName(llvm::StringRef());
     llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
-    NewFn->takeName(OldFn);
 
     // If this is an implementation of a function without a prototype, try to
     // replace any existing uses of the function (which may be calls) with uses
@@ -1336,23 +1328,29 @@
     AddGlobalDtor(Fn, DA->getPriority());
 }
 
-void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
+void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
+  const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
   const AliasAttr *AA = D->getAttr<AliasAttr>();
   assert(AA && "Not an alias?");
 
-  const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
+  MangleBuffer MangledName;
+  getMangledName(MangledName, GD);
 
-  // Unique the name through the identifier table.
-  const char *AliaseeName =
-    getContext().Idents.get(AA->getAliasee()).getNameStart();
+  // If there is a definition in the module, then it wins over the alias.
+  // This is dubious, but allow it to be safe.  Just ignore the alias.
+  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
+  if (Entry && !Entry->isDeclaration())
+    return;
+
+  const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
 
   // Create a reference to the named value.  This ensures that it is emitted
   // if a deferred decl.
   llvm::Constant *Aliasee;
   if (isa<llvm::FunctionType>(DeclTy))
-    Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl());
+    Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
   else
-    Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
+    Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
                                     llvm::PointerType::getUnqual(DeclTy), 0);
 
   // Create the new alias itself, but don't set a name yet.
@@ -1361,18 +1359,9 @@
                           llvm::Function::ExternalLinkage,
                           "", Aliasee, &getModule());
 
-  // See if there is already something with the alias' name in the module.
-  const char *MangledName = getMangledName(D);
-  llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
-
-  if (Entry && !Entry->isDeclaration()) {
-    // If there is a definition in the module, then it wins over the alias.
-    // This is dubious, but allow it to be safe.  Just ignore the alias.
-    GA->eraseFromParent();
-    return;
-  }
-
   if (Entry) {
+    assert(Entry->isDeclaration());
+
     // If there is a declaration in the module, then we had an extern followed
     // by the alias, as in:
     //   extern int test6();
@@ -1380,16 +1369,15 @@
     //   int test6() __attribute__((alias("test7")));
     //
     // Remove it and replace uses of it with the alias.
+    GA->takeName(Entry);
 
     Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA,
                                                           Entry->getType()));
     Entry->eraseFromParent();
+  } else {
+    GA->setName(MangledName.getString());
   }
 
-  // Now we know that there is no conflict, set the name.
-  Entry = GA;
-  GA->setName(MangledName);
-
   // Set attributes which are particular to an alias; this is a
   // specialization of the attributes which may be set on a global
   // variable/function.
@@ -1426,8 +1414,6 @@
   const llvm::FunctionType *Ty =
     cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType()));
 
-  // Unique the name through the identifier table.
-  Name = getContext().Idents.get(Name).getNameStart();
   return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD));
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=99012&r1=99011&r2=99012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Mar 19 18:29:14 2010
@@ -73,7 +73,7 @@
   class CodeGenFunction;
   class CGDebugInfo;
   class CGObjCRuntime;
-
+  class MangleBuffer;
   
 /// CodeGenModule - This class organizes the cross-function state that is used
 /// while generating LLVM code.
@@ -103,38 +103,16 @@
   llvm::Function *MemMoveFn;
   llvm::Function *MemSetFn;
 
-  /// GlobalDeclMap - Mapping of decl names (represented as unique
-  /// character pointers from either the identifier table or the set
-  /// of mangled names) to global variables we have already
-  /// emitted. Note that the entries in this map are the actual
-  /// globals and therefore may not be of the same type as the decl,
-  /// they should be bitcasted on retrieval. Also note that the
-  /// globals are keyed on their source mangled name, not the global name
-  /// (which may change with attributes such as asm-labels).  The key
-  /// to this map should be generated using getMangledName().
-  ///
-  /// Note that this map always lines up exactly with the contents of the LLVM
-  /// IR symbol table, but this is quicker to query since it is doing uniqued
-  /// pointer lookups instead of full string lookups.
-  llvm::DenseMap<const char*, llvm::GlobalValue*> GlobalDeclMap;
-
   // WeakRefReferences - A set of references that have only been seen via
   // a weakref so far. This is used to remove the weak of the reference if we ever
   // see a direct reference or a definition.
   llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences;
 
-  /// \brief Contains the strings used for mangled names.
-  ///
-  /// FIXME: Eventually, this should map from the semantic/canonical
-  /// declaration for each global entity to its mangled name (if it
-  /// has one).
-  llvm::StringSet<> MangledNames;
-
   /// DeferredDecls - This contains all the decls which have definitions but
   /// which are deferred for emission and therefore should only be output if
   /// they are actually used.  If a decl is in this, then it is known to have
-  /// not been referenced yet.  The key to this map is a uniqued mangled name.
-  llvm::DenseMap<const char*, GlobalDecl> DeferredDecls;
+  /// not been referenced yet.
+  llvm::StringMap<GlobalDecl> DeferredDecls;
 
   /// DeferredDeclsToEmit - This is a list of deferred decls which we have seen
   /// that *are* actually referenced.  These get code generated when the module
@@ -346,11 +324,11 @@
   /// CreateRuntimeFunction - Create a new runtime function with the specified
   /// type and name.
   llvm::Constant *CreateRuntimeFunction(const llvm::FunctionType *Ty,
-                                        const char *Name);
+                                        llvm::StringRef Name);
   /// CreateRuntimeVariable - Create a new runtime global variable with the
   /// specified type and name.
   llvm::Constant *CreateRuntimeVariable(const llvm::Type *Ty,
-                                        const char *Name);
+                                        llvm::StringRef Name);
 
   void UpdateCompletedType(const TagDecl *TD) {
     // Make sure that this type is translated.
@@ -422,13 +400,14 @@
                               AttributeListType &PAL,
                               unsigned &CallingConv);
 
-  const char *getMangledName(const GlobalDecl &D);
-
-  const char *getMangledName(const NamedDecl *ND);
-  const char *getMangledCXXCtorName(const CXXConstructorDecl *D,
-                                    CXXCtorType Type);
-  const char *getMangledCXXDtorName(const CXXDestructorDecl *D,
-                                    CXXDtorType Type);
+  void getMangledName(MangleBuffer &Buffer, GlobalDecl D);
+  void getMangledName(MangleBuffer &Buffer, const NamedDecl *ND);
+  void getMangledCXXCtorName(MangleBuffer &Buffer,
+                             const CXXConstructorDecl *D,
+                             CXXCtorType Type);
+  void getMangledCXXDtorName(MangleBuffer &Buffer,
+                             const CXXDestructorDecl *D,
+                             CXXDtorType Type);
 
   void EmitTentativeDefinition(const VarDecl *D);
 
@@ -456,14 +435,12 @@
   std::vector<const CXXRecordDecl*> DeferredVtables;
 
 private:
-  /// UniqueMangledName - Unique a name by (if necessary) inserting it into the
-  /// MangledNames string map.
-  const char *UniqueMangledName(const char *NameStart, const char *NameEnd);
+  llvm::GlobalValue *GetGlobalValue(llvm::StringRef Ref);
 
-  llvm::Constant *GetOrCreateLLVMFunction(const char *MangledName,
+  llvm::Constant *GetOrCreateLLVMFunction(llvm::StringRef MangledName,
                                           const llvm::Type *Ty,
                                           GlobalDecl D);
-  llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName,
+  llvm::Constant *GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
                                         const llvm::PointerType *PTy,
                                         const VarDecl *D);
 
@@ -492,7 +469,7 @@
 
   void EmitGlobalFunctionDefinition(GlobalDecl GD);
   void EmitGlobalVarDefinition(const VarDecl *D);
-  void EmitAliasDefinition(const ValueDecl *D);
+  void EmitAliasDefinition(GlobalDecl GD);
   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
 
   // C++ related functions.

Modified: cfe/trunk/lib/CodeGen/Mangle.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.h?rev=99012&r1=99011&r2=99012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.h (original)
+++ cfe/trunk/lib/CodeGen/Mangle.h Fri Mar 19 18:29:14 2010
@@ -21,10 +21,8 @@
 #include "CGCXX.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/DenseMap.h"
-
-namespace llvm {
-  template<typename T> class SmallVectorImpl;
-}
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallString.h"
 
 namespace clang {
   class ASTContext;
@@ -37,6 +35,33 @@
 namespace CodeGen {
   class CovariantThunkAdjustment;
   class ThunkAdjustment;
+
+/// MangleBuffer - a convenient class for storing a name which is
+/// either the result of a mangling or is a constant string with
+/// external memory ownership.
+class MangleBuffer {
+public:
+  void setString(llvm::StringRef Ref) {
+    String = Ref;
+  }
+
+  llvm::SmallVectorImpl<char> &getBuffer() {
+    return Buffer;
+  }
+
+  llvm::StringRef getString() const {
+    if (!String.empty()) return String;
+    return Buffer.str();
+  }
+
+  operator llvm::StringRef() const {
+    return getString();
+  }
+
+private:
+  llvm::StringRef String;
+  llvm::SmallString<256> Buffer;
+};
    
 /// MangleContext - Context for tracking state which persists across multiple
 /// calls to the C++ name mangler.

Modified: cfe/trunk/test/CodeGenCXX/attr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/attr.cpp?rev=99012&r1=99011&r2=99012&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/attr.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/attr.cpp Fri Mar 19 18:29:14 2010
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
 
+// CHECK: @test2 = alias i32 ()* @_Z5test1v
+
 // CHECK: define i32 @_Z3foov() nounwind align 1024
 int foo() __attribute__((aligned(1024)));
 int foo() { }
@@ -18,3 +20,9 @@
 
 // CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) nounwind align 1024
 void C::bar3() { }
+
+// PR6635
+// CHECK: define i32 @_Z5test1v()
+int test1() { return 10; }
+// CHECK at top of file
+extern "C" int test2() __attribute__((alias("_Z5test1v")));





More information about the cfe-commits mailing list