[cfe-commits] r49987 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h
Nate Begeman
natebegeman at mac.com
Sat Apr 19 23:29:50 PDT 2008
Author: sampo
Date: Sun Apr 20 01:29:50 2008
New Revision: 49987
URL: http://llvm.org/viewvc/llvm-project?rev=49987&view=rev
Log:
Only generate code for static functions and global variables that are actually used.
Warn about unused static functions and variables.
This fixes PR1998.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=49987&r1=49986&r2=49987&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sun Apr 20 01:29:50 2008
@@ -1036,4 +1036,10 @@
DIAG(ext_return_has_expr, EXTENSION,
"void function '%0' should not return a value")
+//===----------------------------------------------------------------------===//
+// Codegen
+//===----------------------------------------------------------------------===//
+
+DIAG(warn_unused_static, WARNING, "static '%0' defined but not used")
+
#undef DIAG
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=49987&r1=49986&r2=49987&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Apr 20 01:29:50 2008
@@ -44,6 +44,7 @@
llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction();
if (ObjCInitFunction)
AddGlobalCtor(ObjCInitFunction);
+ EmitStatics();
EmitGlobalCtors();
EmitAnnotations();
delete Runtime;
@@ -167,8 +168,8 @@
// If it doesn't already exist, just create and return an entry.
if (F == 0) {
// FIXME: param attributes for sext/zext etc.
- F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage, D->getName(),
- &getModule());
+ F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
+ D->getName(), &getModule());
// Set the appropriate calling convention for the Function.
if (D->getAttr<FastCallAttr>())
@@ -298,8 +299,58 @@
void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
// If this is not a prototype, emit the body.
- if (FD->getBody())
+ if (FD->getBody()) {
+ // If the function is a static, defer code generation until later so we can
+ // easily omit unused statics.
+ if (FD->getStorageClass() == FunctionDecl::Static) {
+ StaticDecls.push_back(FD);
+ return;
+ }
CodeGenFunction(*this).GenerateCode(FD);
+ }
+}
+
+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.
+ bool Changed;
+ do {
+ Changed = false;
+ for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
+ // Check the map of used decls for our static. If not found, continue.
+ const Decl *D = StaticDecls[i];
+ if (GlobalDeclMap[D] == 0)
+ continue;
+
+ // If this is a function decl, generate code for the static function if it
+ // has a body. Otherwise, we must have a var decl for a static global
+ // variable.
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->getBody())
+ CodeGenFunction(*this).GenerateCode(FD);
+ } else {
+ const VarDecl *VD = cast<VarDecl>(D);
+ EmitGlobalVarInit(VD);
+ }
+ // Erase the used decl from the list.
+ StaticDecls[i] = StaticDecls.back();
+ StaticDecls.pop_back();
+ --i;
+ --e;
+
+ // Remember that we made a change.
+ Changed = true;
+ }
+ } while (Changed);
+
+ // Warn about all statics that are still unused at end of code generation.
+ for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
+ const Decl *D = StaticDecls[i];
+ std::string Msg = cast<NamedDecl>(D)->getName();
+ getDiags().Report(Context.getFullLoc(D->getLocation()),
+ diag::warn_unused_static, &Msg, 1);
+ }
}
llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
@@ -351,11 +402,22 @@
}
void CodeGenModule::EmitGlobalVar(const VarDecl *D) {
+ // If the VarDecl is a static, defer code generation until later so we can
+ // easily omit unused statics.
+ if (D->getStorageClass() == VarDecl::Static) {
+ StaticDecls.push_back(D);
+ return;
+ }
+
// If this is just a forward declaration of the variable, don't emit it now,
// allow it to be emitted lazily on its first use.
if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0)
return;
+ EmitGlobalVarInit(D);
+}
+
+void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) {
// Get the global, forcing it to be a direct reference.
llvm::GlobalVariable *GV =
cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, true));
@@ -468,8 +530,9 @@
}
// FIXME: param attributes for sext/zext etc.
- return FunctionSlot = llvm::Function::Create(Ty, llvm::Function::ExternalLinkage,
- Name, &getModule());
+ return FunctionSlot =
+ llvm::Function::Create(Ty, llvm::Function::ExternalLinkage, Name,
+ &getModule());
}
llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=49987&r1=49986&r2=49987&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sun Apr 20 01:29:50 2008
@@ -59,6 +59,8 @@
llvm::Function *MemCpyFn;
llvm::Function *MemSetFn;
llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
+ std::vector<const Decl*> StaticDecls;
+
std::vector<llvm::Constant*> GlobalCtors;
std::vector<llvm::Constant*> Annotations;
@@ -103,10 +105,12 @@
void EmitGlobalCtors(void);
void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
void EmitAnnotations(void);
+ void EmitStatics(void);
void EmitObjCMethod(const ObjCMethodDecl *OMD);
void EmitFunction(const FunctionDecl *FD);
void EmitGlobalVar(const VarDecl *D);
+ void EmitGlobalVarInit(const VarDecl *D);
void EmitGlobalVarDeclarator(const VarDecl *D);
void UpdateCompletedType(const TagDecl *D);
llvm::Constant *EmitGlobalInit(const Expr *E);
More information about the cfe-commits
mailing list