[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