[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

Chris Lattner clattner at apple.com
Tue Mar 23 14:54:01 PDT 2010


On Mar 19, 2010, at 4:29 PM, John McCall wrote:

> 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.

Hi John,

Why not get the best of both worlds and map from StringMapEntry*'s instead of the string itself?  The stringmap entry can be obtained from the LLVM Module, no?

-Chris

> 
> 
> 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")));
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits





More information about the cfe-commits mailing list