[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