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() {
|
||||
EmitStatics();
|
||||
EmitDeferred();
|
||||
EmitAliases();
|
||||
if (Runtime)
|
||||
if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
|
||||
|
@ -68,6 +68,7 @@ void CodeGenModule::Release() {
|
|||
EmitCtorList(GlobalCtors, "llvm.global_ctors");
|
||||
EmitCtorList(GlobalDtors, "llvm.global_dtors");
|
||||
EmitAnnotations();
|
||||
EmitLLVMUsed();
|
||||
BindRuntimeFunctions();
|
||||
}
|
||||
|
||||
|
@ -388,16 +389,40 @@ void CodeGenModule::EmitAliases() {
|
|||
}
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitStatics() {
|
||||
// Emit code for each used static decl encountered. Since a previously unused
|
||||
// static decl may become used during the generation of code for a static
|
||||
// function, iterate until no changes are made.
|
||||
void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) {
|
||||
assert(!GV->isDeclaration() &&
|
||||
"Only globals with definition can force usage.");
|
||||
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;
|
||||
do {
|
||||
Changed = false;
|
||||
|
||||
for (std::list<const ValueDecl*>::iterator i = StaticDecls.begin(),
|
||||
e = StaticDecls.end(); i != e; ) {
|
||||
for (std::list<const ValueDecl*>::iterator i = DeferredDecls.begin(),
|
||||
e = DeferredDecls.end(); i != e; ) {
|
||||
const ValueDecl *D = *i;
|
||||
|
||||
// Check if we have used a decl with the same name
|
||||
|
@ -414,7 +439,7 @@ void CodeGenModule::EmitStatics() {
|
|||
EmitGlobalDefinition(D);
|
||||
|
||||
// Erase the used decl from the list.
|
||||
i = StaticDecls.erase(i);
|
||||
i = DeferredDecls.erase(i);
|
||||
|
||||
// Remember that we made a change.
|
||||
Changed = true;
|
||||
|
@ -481,16 +506,14 @@ void CodeGenModule::EmitGlobal(const ValueDecl *Global) {
|
|||
|
||||
isDef = FD->isThisDeclarationADefinition();
|
||||
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.");
|
||||
|
||||
isDef = !((VD->getStorageClass() == VarDecl::Extern ||
|
||||
VD->getStorageClass() == VarDecl::PrivateExtern) &&
|
||||
VD->getInit() == 0);
|
||||
isStatic = VD->getStorageClass() == VarDecl::Static;
|
||||
} else {
|
||||
assert(0 && "Invalid argument to EmitGlobal");
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
// we can easily omit unused statics.
|
||||
if (isStatic && !Features.EmitAllDecls) {
|
||||
StaticDecls.push_back(Global);
|
||||
DeferredDecls.push_back(Global);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,12 +95,18 @@ class CodeGenModule {
|
|||
/// and may reference forward.
|
||||
std::vector<const FunctionDecl*> Aliases;
|
||||
|
||||
/// StaticDecls - List of static global for which code generation is
|
||||
/// delayed. When the translation unit has been fully processed we will lazily
|
||||
/// emit definitions for only the decls that were actually used. This should
|
||||
/// contain only Function and Var decls, and only those which actually define
|
||||
/// something.
|
||||
std::list<const ValueDecl*> StaticDecls;
|
||||
/// DeferredDecls - List of decls for which code generation has been
|
||||
/// deferred. When the translation unit has been fully processed we
|
||||
/// will lazily emit definitions for only the decls that were
|
||||
/// actually used. This should contain only Function and Var decls,
|
||||
/// and only those which actually define something.
|
||||
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
|
||||
/// priorities to be emitted when the translation unit is complete.
|
||||
|
@ -228,6 +234,11 @@ public:
|
|||
/// EmitTopLevelDecl - Emit code for a single top level declaration.
|
||||
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); }
|
||||
|
||||
/// CreateRuntimeFunction - Create a new runtime function whose name must be
|
||||
|
@ -303,7 +314,14 @@ private:
|
|||
|
||||
void EmitAliases(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();
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue