From: Chris Lattner Date: Sun, 22 Mar 2009 21:47:11 +0000 (+0000) Subject: emit aliases as the definitions fly by, don't bother deferring until X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd53271dc7570b54f7b7cab7b09bcf04c6e927f6;p=clang emit aliases as the definitions fly by, don't bother deferring until the end of the module. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67482 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 21f67901d1..9bb12900fa 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -57,7 +57,6 @@ CodeGenModule::~CodeGenModule() { } void CodeGenModule::Release() { - EmitAliases(); EmitDeferred(); if (Runtime) if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction()) @@ -324,75 +323,6 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, FD->isInline(), F, false); } - -void CodeGenModule::EmitAliases() { - for (unsigned i = 0, e = Aliases.size(); i != e; ++i) { - const ValueDecl *D = Aliases[i]; - const AliasAttr *AA = D->getAttr(); - - // This is something of a hack, if the FunctionDecl got overridden - // then its attributes will be moved to the new declaration. In - // this case the current decl has no alias attribute, but we will - // eventually see it. - if (!AA) - continue; - - const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); - - // Unique the name through the identifier table. - const char *AliaseeName = AA->getAliasee().c_str(); - AliaseeName = getContext().Idents.get(AliaseeName).getName(); - - // Create a reference to the named value. This ensures that it is emitted - // if a deferred decl. - llvm::Constant *Aliasee; - if (isa(DeclTy)) - Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, 0); - else - Aliasee = GetOrCreateLLVMGlobal(AliaseeName, - llvm::PointerType::getUnqual(DeclTy), 0); - - // Create the new alias itself, but don't set a name yet. - llvm::GlobalValue *GA = - new llvm::GlobalAlias(Aliasee->getType(), - 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. - delete GA; - continue; - } - - if (Entry) { - // If there is a declaration in the module, then we had an extern followed - // by the alias, as in: - // extern int test6(); - // ... - // int test6() __attribute__((alias("test7"))); - // - // Remove it and replace uses of it with the alias. - - Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA, - Entry->getType())); - // FIXME: What if it was attribute used? Dangling pointer from LLVMUsed. - Entry->eraseFromParent(); - } - - // Now we know that there is no conflict, set the name. - Entry = GA; - GA->setName(MangledName); - - // Alias should never be internal or inline. - SetGlobalValueAttributes(D, false, false, GA, true); - } -} - void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) { assert(!GV->isDeclaration() && "Only globals with definition can force usage."); @@ -509,12 +439,10 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { } void CodeGenModule::EmitGlobal(const ValueDecl *Global) { - // Aliases are deferred until code for everything else has been - // emitted. - if (Global->getAttr()) { - Aliases.push_back(Global); - return; - } + // If this is an alias definition (which otherwise looks like a declaration) + // emit it now. + if (Global->getAttr()) + return EmitAliasDefinition(Global); // Ignore declarations, they will be emitted on their first use. if (const FunctionDecl *FD = dyn_cast(Global)) { @@ -936,6 +864,65 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { AddGlobalDtor(Fn, DA->getPriority()); } +void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { + const AliasAttr *AA = D->getAttr(); + assert(AA && "Not an alias?"); + + const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); + + // Unique the name through the identifier table. + const char *AliaseeName = AA->getAliasee().c_str(); + AliaseeName = getContext().Idents.get(AliaseeName).getName(); + + // Create a reference to the named value. This ensures that it is emitted + // if a deferred decl. + llvm::Constant *Aliasee; + if (isa(DeclTy)) + Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, 0); + else + Aliasee = GetOrCreateLLVMGlobal(AliaseeName, + llvm::PointerType::getUnqual(DeclTy), 0); + + // Create the new alias itself, but don't set a name yet. + llvm::GlobalValue *GA = + new llvm::GlobalAlias(Aliasee->getType(), + 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) { + // If there is a declaration in the module, then we had an extern followed + // by the alias, as in: + // extern int test6(); + // ... + // int test6() __attribute__((alias("test7"))); + // + // Remove it and replace uses of it with the alias. + + Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA, + Entry->getType())); + // FIXME: What if it was attribute used? Dangling pointer from LLVMUsed. + Entry->eraseFromParent(); + } + + // Now we know that there is no conflict, set the name. + Entry = GA; + GA->setName(MangledName); + + // Alias should never be internal or inline. + SetGlobalValueAttributes(D, false, false, GA, true); +} + void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { // Make sure that this type is translated. Types.UpdateCompletedType(TD); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index bea2d15c40..fdf5775170 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -104,11 +104,6 @@ class CodeGenModule : public BlockModule { /// has one). llvm::StringSet<> MangledNames; - /// Aliases - List of aliases in module. These cannot be emitted until all the - /// code has been seen, as they reference things by name instead of directly - /// and may reference forward. - std::vector Aliases; - /// 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 @@ -331,6 +326,7 @@ private: void EmitGlobalFunctionDefinition(const FunctionDecl *D); void EmitGlobalVarDefinition(const VarDecl *D); + void EmitAliasDefinition(const ValueDecl *D); void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); // FIXME: Hardcoding priority here is gross. @@ -342,7 +338,6 @@ private: /// suitable for use as a LLVM constructor or destructor array. void EmitCtorList(const CtorList &Fns, const char *GlobalName); - void EmitAliases(void); void EmitAnnotations(void); /// EmitDeferred - Emit any needed decls for which code generation