forked from OSchip/llvm-project
Rename EmitStatics (etc) to EmitDeferred; provide basic infrastructure
for attribute used support. - No functionality change. llvm-svn: 64487
This commit is contained in:
parent
499ae7ec91
commit
08b26a0587
|
@ -60,7 +60,7 @@ CodeGenModule::~CodeGenModule() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenModule::Release() {
|
void CodeGenModule::Release() {
|
||||||
EmitStatics();
|
EmitDeferred();
|
||||||
EmitAliases();
|
EmitAliases();
|
||||||
if (Runtime)
|
if (Runtime)
|
||||||
if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
|
if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
|
||||||
|
@ -68,6 +68,7 @@ void CodeGenModule::Release() {
|
||||||
EmitCtorList(GlobalCtors, "llvm.global_ctors");
|
EmitCtorList(GlobalCtors, "llvm.global_ctors");
|
||||||
EmitCtorList(GlobalDtors, "llvm.global_dtors");
|
EmitCtorList(GlobalDtors, "llvm.global_dtors");
|
||||||
EmitAnnotations();
|
EmitAnnotations();
|
||||||
|
EmitLLVMUsed();
|
||||||
BindRuntimeFunctions();
|
BindRuntimeFunctions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,16 +389,40 @@ void CodeGenModule::EmitAliases() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenModule::EmitStatics() {
|
void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) {
|
||||||
// Emit code for each used static decl encountered. Since a previously unused
|
assert(!GV->isDeclaration() &&
|
||||||
// static decl may become used during the generation of code for a static
|
"Only globals with definition can force usage.");
|
||||||
// function, iterate until no changes are made.
|
llvm::Type *i8PTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
|
||||||
|
LLVMUsed.push_back(llvm::ConstantExpr::getBitCast(GV, i8PTy));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeGenModule::EmitLLVMUsed() {
|
||||||
|
// Don't create llvm.used if there is no need.
|
||||||
|
if (LLVMUsed.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
llvm::ArrayType *ATy = llvm::ArrayType::get(LLVMUsed[0]->getType(),
|
||||||
|
LLVMUsed.size());
|
||||||
|
llvm::GlobalVariable *GV =
|
||||||
|
new llvm::GlobalVariable(ATy, false,
|
||||||
|
llvm::GlobalValue::AppendingLinkage,
|
||||||
|
llvm::ConstantArray::get(ATy, LLVMUsed),
|
||||||
|
"llvm.used", &getModule());
|
||||||
|
|
||||||
|
GV->setSection("llvm.metadata");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeGenModule::EmitDeferred() {
|
||||||
|
// Emit code for any deferred decl which was used. Since a
|
||||||
|
// previously unused static decl may become used during the
|
||||||
|
// generation of code for a static function, iterate until no
|
||||||
|
// changes are made.
|
||||||
bool Changed;
|
bool Changed;
|
||||||
do {
|
do {
|
||||||
Changed = false;
|
Changed = false;
|
||||||
|
|
||||||
for (std::list<const ValueDecl*>::iterator i = StaticDecls.begin(),
|
for (std::list<const ValueDecl*>::iterator i = DeferredDecls.begin(),
|
||||||
e = StaticDecls.end(); i != e; ) {
|
e = DeferredDecls.end(); i != e; ) {
|
||||||
const ValueDecl *D = *i;
|
const ValueDecl *D = *i;
|
||||||
|
|
||||||
// Check if we have used a decl with the same name
|
// Check if we have used a decl with the same name
|
||||||
|
@ -414,7 +439,7 @@ void CodeGenModule::EmitStatics() {
|
||||||
EmitGlobalDefinition(D);
|
EmitGlobalDefinition(D);
|
||||||
|
|
||||||
// Erase the used decl from the list.
|
// Erase the used decl from the list.
|
||||||
i = StaticDecls.erase(i);
|
i = DeferredDecls.erase(i);
|
||||||
|
|
||||||
// Remember that we made a change.
|
// Remember that we made a change.
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
@ -481,16 +506,14 @@ void CodeGenModule::EmitGlobal(const ValueDecl *Global) {
|
||||||
|
|
||||||
isDef = FD->isThisDeclarationADefinition();
|
isDef = FD->isThisDeclarationADefinition();
|
||||||
isStatic = FD->getStorageClass() == FunctionDecl::Static;
|
isStatic = FD->getStorageClass() == FunctionDecl::Static;
|
||||||
} else if (const VarDecl *VD = cast<VarDecl>(Global)) {
|
} else {
|
||||||
|
const VarDecl *VD = cast<VarDecl>(Global);
|
||||||
assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
|
assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
|
||||||
|
|
||||||
isDef = !((VD->getStorageClass() == VarDecl::Extern ||
|
isDef = !((VD->getStorageClass() == VarDecl::Extern ||
|
||||||
VD->getStorageClass() == VarDecl::PrivateExtern) &&
|
VD->getStorageClass() == VarDecl::PrivateExtern) &&
|
||||||
VD->getInit() == 0);
|
VD->getInit() == 0);
|
||||||
isStatic = VD->getStorageClass() == VarDecl::Static;
|
isStatic = VD->getStorageClass() == VarDecl::Static;
|
||||||
} else {
|
|
||||||
assert(0 && "Invalid argument to EmitGlobal");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward declarations are emitted lazily on first use.
|
// Forward declarations are emitted lazily on first use.
|
||||||
|
@ -500,7 +523,7 @@ void CodeGenModule::EmitGlobal(const ValueDecl *Global) {
|
||||||
// If the global is a static, defer code generation until later so
|
// If the global is a static, defer code generation until later so
|
||||||
// we can easily omit unused statics.
|
// we can easily omit unused statics.
|
||||||
if (isStatic && !Features.EmitAllDecls) {
|
if (isStatic && !Features.EmitAllDecls) {
|
||||||
StaticDecls.push_back(Global);
|
DeferredDecls.push_back(Global);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,12 +95,18 @@ class CodeGenModule {
|
||||||
/// and may reference forward.
|
/// and may reference forward.
|
||||||
std::vector<const FunctionDecl*> Aliases;
|
std::vector<const FunctionDecl*> Aliases;
|
||||||
|
|
||||||
/// StaticDecls - List of static global for which code generation is
|
/// DeferredDecls - List of decls for which code generation has been
|
||||||
/// delayed. When the translation unit has been fully processed we will lazily
|
/// deferred. When the translation unit has been fully processed we
|
||||||
/// emit definitions for only the decls that were actually used. This should
|
/// will lazily emit definitions for only the decls that were
|
||||||
/// contain only Function and Var decls, and only those which actually define
|
/// actually used. This should contain only Function and Var decls,
|
||||||
/// something.
|
/// and only those which actually define something.
|
||||||
std::list<const ValueDecl*> StaticDecls;
|
std::list<const ValueDecl*> DeferredDecls;
|
||||||
|
|
||||||
|
/// LLVMUsed - List of global values which are required to be
|
||||||
|
/// present in the object file; bitcast to i8*. This is used for
|
||||||
|
/// forcing visibility of symbols which may otherwise be optimized
|
||||||
|
/// out.
|
||||||
|
std::vector<llvm::Constant*> LLVMUsed;
|
||||||
|
|
||||||
/// GlobalCtors - Store the list of global constructors and their respective
|
/// GlobalCtors - Store the list of global constructors and their respective
|
||||||
/// priorities to be emitted when the translation unit is complete.
|
/// priorities to be emitted when the translation unit is complete.
|
||||||
|
@ -228,6 +234,11 @@ public:
|
||||||
/// EmitTopLevelDecl - Emit code for a single top level declaration.
|
/// EmitTopLevelDecl - Emit code for a single top level declaration.
|
||||||
void EmitTopLevelDecl(Decl *D);
|
void EmitTopLevelDecl(Decl *D);
|
||||||
|
|
||||||
|
/// AddUsedGlobal - Add a global which should be forced to be
|
||||||
|
/// present in the object file; these are emitted to the llvm.used
|
||||||
|
/// metadata global.
|
||||||
|
void AddUsedGlobal(llvm::GlobalValue *GV);
|
||||||
|
|
||||||
void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
|
void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
|
||||||
|
|
||||||
/// CreateRuntimeFunction - Create a new runtime function whose name must be
|
/// CreateRuntimeFunction - Create a new runtime function whose name must be
|
||||||
|
@ -303,7 +314,14 @@ private:
|
||||||
|
|
||||||
void EmitAliases(void);
|
void EmitAliases(void);
|
||||||
void EmitAnnotations(void);
|
void EmitAnnotations(void);
|
||||||
void EmitStatics(void);
|
|
||||||
|
/// EmitDeferred - Emit any needed decls for which code generation
|
||||||
|
/// was deferred.
|
||||||
|
void EmitDeferred(void);
|
||||||
|
|
||||||
|
/// EmitLLVMUsed - Emit the llvm.used metadata used to force
|
||||||
|
/// references to global which may otherwise be optimized out.
|
||||||
|
void EmitLLVMUsed(void);
|
||||||
|
|
||||||
void BindRuntimeFunctions();
|
void BindRuntimeFunctions();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue