forked from OSchip/llvm-project
emit aliases as the definitions fly by, don't bother deferring until
the end of the module. llvm-svn: 67482
This commit is contained in:
parent
827a3552a4
commit
5404169327
|
@ -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<AliasAttr>();
|
||||
|
||||
// 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<llvm::FunctionType>(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<AliasAttr>()) {
|
||||
Aliases.push_back(Global);
|
||||
return;
|
||||
}
|
||||
// If this is an alias definition (which otherwise looks like a declaration)
|
||||
// emit it now.
|
||||
if (Global->getAttr<AliasAttr>())
|
||||
return EmitAliasDefinition(Global);
|
||||
|
||||
// Ignore declarations, they will be emitted on their first use.
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(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<AliasAttr>();
|
||||
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<llvm::FunctionType>(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);
|
||||
|
|
|
@ -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<const ValueDecl*> 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
|
||||
|
|
Loading…
Reference in New Issue