[cfe-commits] r64487 - in /cfe/trunk/lib/CodeGen: CodeGenModule.cpp CodeGenModule.h

Daniel Dunbar daniel at zuster.org
Fri Feb 13 12:29:51 PST 2009


Author: ddunbar
Date: Fri Feb 13 14:29:50 2009
New Revision: 64487

URL: http://llvm.org/viewvc/llvm-project?rev=64487&view=rev
Log:
Rename EmitStatics (etc) to EmitDeferred; provide basic infrastructure
for attribute used support.  
- No functionality change.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=64487&r1=64486&r2=64487&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Feb 13 14:29:50 2009
@@ -60,7 +60,7 @@
 }
 
 void CodeGenModule::Release() {
-  EmitStatics();
+  EmitDeferred();
   EmitAliases();
   if (Runtime)
     if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
@@ -68,6 +68,7 @@
   EmitCtorList(GlobalCtors, "llvm.global_ctors");
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitAnnotations();
+  EmitLLVMUsed();
   BindRuntimeFunctions();
 }
 
@@ -388,16 +389,40 @@
   }
 }
 
-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 @@
       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 @@
 
     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 @@
   // 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;
   }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=64487&r1=64486&r2=64487&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Feb 13 14:29:50 2009
@@ -95,12 +95,18 @@
   /// 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 @@
   /// 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 @@
 
   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();
 };





More information about the cfe-commits mailing list