[cfe-commits] r54179 - in /cfe/trunk/lib/CodeGen: CGExpr.cpp CGExprConstant.cpp CodeGenFunction.cpp CodeGenFunction.h CodeGenModule.cpp CodeGenModule.h ModuleBuilder.cpp

Daniel Dunbar daniel at zuster.org
Tue Jul 29 16:18:29 PDT 2008


Author: ddunbar
Date: Tue Jul 29 18:18:29 2008
New Revision: 54179

URL: http://llvm.org/viewvc/llvm-project?rev=54179&view=rev
Log:
Rework codegen emission of globals
 - No (intended) functionality change.

 - Primary purpose is to clearly separate (lazy) construction of
   globals that are a forward declaration or tentative definition from
   those that are the final definition.

 - Lazy construction is now encapsulated in
   GetAddrOf{Function,GlobalVar} while final definitions are
   constructed in EmitGlobal{Function,Var}Definition.
 
 - External interface for dealing with globals is now limited to
   EmitGlobal and GetAddrOf{Function,GlobalVar}.

 - Also updated helper functions dealing with statics, annotations,
   and ctors to be private.

Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/ModuleBuilder.cpp

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Jul 29 18:18:29 2008
@@ -373,7 +373,7 @@
   if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD) ||
         isa<ImplicitParamDecl>(VD))) {
     if (VD->getStorageClass() == VarDecl::Extern)
-      return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false),
+      return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
                               E->getType().getCVRQualifiers());
     else {
       llvm::Value *V = LocalDeclMap[VD];
@@ -381,10 +381,10 @@
       return LValue::MakeAddr(V, E->getType().getCVRQualifiers());
     }
   } else if (VD && VD->isFileVarDecl()) {
-    return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false),
+    return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
                             E->getType().getCVRQualifiers());
   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
-    return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false),
+    return LValue::MakeAddr(CGM.GetAddrOfFunction(FD),
                             E->getType().getCVRQualifiers());
   }
   else if (const ImplicitParamDecl *IPD =

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Jul 29 18:18:29 2008
@@ -735,10 +735,10 @@
     case Expr::DeclRefExprClass: {
       ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
-        return CGM.GetAddrOfFunctionDecl(FD, false);
+        return CGM.GetAddrOfFunction(FD);
       if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
         if (VD->isFileVarDecl())
-          return CGM.GetAddrOfGlobalVar(VD, false);
+          return CGM.GetAddrOfGlobalVar(VD);
         else if (VD->isBlockVarDecl()) {
           assert(CGF && "Can't access static local vars without CGF");
           return CGF->GetAddrOfStaticLocalVar(VD);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Jul 29 18:18:29 2008
@@ -102,10 +102,11 @@
   assert(!verifyFunction(*CurFn) && "Generated function is not well formed.");
 }
 
-void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
+void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
+                                   llvm::Function *Fn) {
   CurFuncDecl = FD;
   FnRetTy = FD->getResultType();
-  CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
+  CurFn = Fn;
   assert(CurFn->isDeclaration() && "Function already has body?");
 
   llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jul 29 18:18:29 2008
@@ -1,4 +1,4 @@
-//===--- CodeGenFunction.h - Per-Function state for LLVM CodeGen ----------===//
+//===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -277,7 +277,8 @@
   ASTContext &getContext() const;
 
   void GenerateObjCMethod(const ObjCMethodDecl *OMD);
-  void GenerateCode(const FunctionDecl *FD);
+  void GenerateCode(const FunctionDecl *FD,
+                    llvm::Function *Fn);
   void GenerateFunction(const Stmt *Body);
   
   const llvm::Type *ConvertType(QualType T);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Jul 29 18:18:29 2008
@@ -153,8 +153,6 @@
                                                           CtorValues));
 }
 
-
-
 void CodeGenModule::EmitAnnotations() {
   if (Annotations.empty())
     return;
@@ -171,16 +169,6 @@
   gv->setSection("llvm.metadata");
 }
 
-/// ReplaceMapValuesWith - This is a really slow and bad function that
-/// searches for any entries in GlobalDeclMap that point to OldVal, changing
-/// them to point to NewVal.  This is badbadbad, FIXME!
-void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal,
-                                         llvm::Constant *NewVal) {
-  for (llvm::DenseMap<const Decl*, llvm::Constant*>::iterator 
-       I = GlobalDeclMap.begin(), E = GlobalDeclMap.end(); I != E; ++I)
-    if (I->second == OldVal) I->second = NewVal;
-}
-
 bool hasAggregateLLVMType(QualType T) {
   return !T->isRealType() && !T->isPointerLikeType() &&
          !T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
@@ -251,110 +239,6 @@
   SetGlobalValueAttributes(FD, F);
 }
 
-
-
-llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D,
-                                                     bool isDefinition) {
-  // See if it is already in the map.  If so, just return it.
-  llvm::Constant *&Entry = GlobalDeclMap[D];
-  if (!isDefinition && Entry) return Entry;
-
-  const llvm::Type *Ty = getTypes().ConvertType(D->getType());
-  
-  // Check to see if the function already exists.
-  llvm::Function *F = getModule().getFunction(D->getName());
-  const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
-
-  // If it doesn't already exist, just create and return an entry.
-  if (F == 0) {
-    // FIXME: param attributes for sext/zext etc.
-    if (D->getBody() || !D->getAttr<AliasAttr>())
-      F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
-                                 D->getName(), &getModule());
-    else {
-      const std::string& aliaseeName = D->getAttr<AliasAttr>()->getAliasee();
-      llvm::Function *aliasee = getModule().getFunction(aliaseeName);
-      llvm::GlobalValue *alias = new llvm::GlobalAlias(aliasee->getType(),
-                                               llvm::Function::ExternalLinkage,
-                                                       D->getName(),
-                                                       aliasee,
-                                                       &getModule());
-      SetGlobalValueAttributes(D, alias);
-      return Entry = alias;
-    }
-
-    SetFunctionAttributes(D, F, FTy);
-    return Entry = F;
-  }
-  
-  // If the pointer type matches, just return it.
-  llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty);
-  if (PFTy == F->getType()) return Entry = F;
-    
-  // If this isn't a definition, just return it casted to the right type.
-  if (!isDefinition)
-    return Entry = llvm::ConstantExpr::getBitCast(F, PFTy);
-  
-  // Otherwise, we have a definition after a prototype with the wrong type.
-  // F is the Function* for the one with the wrong type, we must make a new
-  // Function* and update everything that used F (a declaration) with the new
-  // Function* (which will be a definition).
-  //
-  // This happens if there is a prototype for a function (e.g. "int f()") and
-  // then a definition of a different type (e.g. "int f(int x)").  Start by
-  // making a new function of the correct type, RAUW, then steal the name.
-  llvm::Function *NewFn = llvm::Function::Create(FTy, 
-                                             llvm::Function::ExternalLinkage,
-                                             "", &getModule());
-  NewFn->takeName(F);
-  
-  // Replace uses of F with the Function we will endow with a body.
-  llvm::Constant *NewPtrForOldDecl = 
-    llvm::ConstantExpr::getBitCast(NewFn, F->getType());
-  F->replaceAllUsesWith(NewPtrForOldDecl);
-  
-  // FIXME: Update the globaldeclmap for the previous decl of this name.  We
-  // really want a way to walk all of these, but we don't have it yet.  This
-  // is incredibly slow!
-  ReplaceMapValuesWith(F, NewPtrForOldDecl);
-  
-  // Ok, delete the old function now, which is dead.
-  assert(F->isDeclaration() && "Shouldn't replace non-declaration");
-  F->eraseFromParent();
-
-  SetFunctionAttributes(D, NewFn, FTy);
-  // Return the new function which has the right type.
-  return Entry = NewFn;
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
-                                                  bool isDefinition) {
-  assert(D->hasGlobalStorage() && "Not a global variable");
-  assert(!isDefinition && "This shouldn't be called for definitions!");
-
-  // See if it is already in the map.
-  llvm::Constant *&Entry = GlobalDeclMap[D];
-  if (Entry) return Entry;
-
-  QualType ASTTy = D->getType();
-  const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
-
-  // Check to see if the global already exists.
-  llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName(), true);
-
-  // If it doesn't already exist, just create and return an entry.
-  if (GV == 0) {
-    return Entry = new llvm::GlobalVariable(Ty, false, 
-                                            llvm::GlobalValue::ExternalLinkage,
-                                            0, D->getName(), &getModule(), 0,
-                                            ASTTy.getAddressSpace());
-  }
-
-  // Otherwise, it already exists; return the existing version
-  llvm::PointerType *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
-  return Entry = llvm::ConstantExpr::getBitCast(GV, PTy);
-}
-
 void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) {
   // If this is not a prototype, emit the body.
   if (OMD->getBody())
@@ -509,25 +393,6 @@
                          ClassMethodSels, ClassMethodTypes, Protocols);
 }
 
-
-void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
-  // If this is not a prototype, emit the body.
-  if (!FD->isThisDeclarationADefinition()) {
-    if (FD->getAttr<AliasAttr>())
-      GetAddrOfFunctionDecl(FD, true);
-    return;
-  }
-  
-  // If the function is a static, defer code generation until later so we can
-  // easily omit unused statics.
-  if (FD->getStorageClass() != FunctionDecl::Static) {
-    CodeGenFunction(*this).GenerateCode(FD);
-    return;
-  }
-
-  StaticDecls.push_back(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
@@ -536,7 +401,7 @@
   do {
     Changed = false;
     for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
-      const Decl *D = StaticDecls[i];
+      const ValueDecl *D = StaticDecls[i];
 
       // Check if we have used a decl with the same name
       // FIXME: The AST should have some sort of aggregate decls or
@@ -549,17 +414,9 @@
           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 if (FD->getAttr<AliasAttr>())
-          GetAddrOfFunctionDecl(FD, true);
-      } else {
-        EmitGlobalVarInit(cast<VarDecl>(D));
-      }
+      // Emit the definition.
+      EmitGlobalDefinition(D);
+
       // Erase the used decl from the list.
       StaticDecls[i] = StaticDecls.back();
       StaticDecls.pop_back();
@@ -572,10 +429,6 @@
   } while (Changed);
 }
 
-llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
-  return EmitConstantExpr(Expr);
-}
-
 /// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the 
 /// annotation information for a given GlobalValue.  The annotation struct is
 /// {i8 *, i8 *, i8 *, i32}.  The first field is a constant expression, the 
@@ -620,25 +473,85 @@
   return llvm::ConstantStruct::get(Fields, 4, false);
 }
 
-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);
+/// ReplaceMapValuesWith - This is a really slow and bad function that
+/// searches for any entries in GlobalDeclMap that point to OldVal, changing
+/// them to point to NewVal.  This is badbadbad, FIXME!
+void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal,
+                                         llvm::Constant *NewVal) {
+  for (llvm::DenseMap<const Decl*, llvm::Constant*>::iterator 
+       I = GlobalDeclMap.begin(), E = GlobalDeclMap.end(); I != E; ++I)
+    if (I->second == OldVal) I->second = NewVal;
+}
+
+void CodeGenModule::EmitGlobal(const ValueDecl *Global) {
+  bool isDef, isStatic;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
+    isDef = (FD->isThisDeclarationADefinition() ||
+             FD->getAttr<AliasAttr>());
+    isStatic = FD->getStorageClass() == FunctionDecl::Static;
+  } else if (const VarDecl *VD = cast<VarDecl>(Global)) {
+    assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
+
+    isDef = !(VD->getStorageClass() == VarDecl::Extern && VD->getInit() == 0);
+    isStatic = VD->getStorageClass() == VarDecl::Static;
+  } else {
+    assert(0 && "Invalid argument to EmitGlobal");
     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)
+  // Forward declarations are emitted lazily on first use.
+  if (!isDef)
     return;
-  
-  EmitGlobalVarInit(D);
+
+  // If the global is a static, defer code generation until later so
+  // we can easily omit unused statics.
+  if (isStatic) {
+    StaticDecls.push_back(Global);
+    return;
+  }
+
+  // Otherwise emit the definition.
+  EmitGlobalDefinition(Global);
+}
+
+void CodeGenModule::EmitGlobalDefinition(const ValueDecl *D) {
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    EmitGlobalFunctionDefinition(FD);
+  } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    EmitGlobalVarDefinition(VD);
+  } else {
+    assert(0 && "Invalid argument to EmitGlobalDefinition()");
+  }
 }
 
-void CodeGenModule::EmitGlobalVarInit(const VarDecl *D) {
+llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D) {
   assert(D->hasGlobalStorage() && "Not a global variable");
 
+  // See if it is already in the map.
+  llvm::Constant *&Entry = GlobalDeclMap[D];
+  if (Entry) return Entry;
+
+  QualType ASTTy = D->getType();
+  const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
+
+  // Check to see if the global already exists.
+  llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName(), true);
+
+  // If it doesn't already exist, just create and return an entry.
+  if (GV == 0) {
+    return Entry = new llvm::GlobalVariable(Ty, false, 
+                                            llvm::GlobalValue::ExternalLinkage,
+                                            0, D->getName(), &getModule(), 0,
+                                            ASTTy.getAddressSpace());
+  }
+
+  // Otherwise, it already exists; return the existing version
+  llvm::PointerType *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
+  return Entry = llvm::ConstantExpr::getBitCast(GV, PTy);
+}
+
+void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
   llvm::Constant *Init = 0;
   QualType ASTTy = D->getType();
   const llvm::Type *VarTy = getTypes().ConvertTypeForMem(ASTTy);
@@ -659,7 +572,7 @@
     }
     Init = llvm::Constant::getNullValue(InitTy);
   } else {
-    Init = EmitGlobalInit(D->getInit());
+    Init = EmitConstantExpr(D->getInit());
   }
   const llvm::Type* InitType = Init->getType();
 
@@ -772,6 +685,111 @@
   }
 }
 
+llvm::GlobalValue *
+CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) {
+  // FIXME: param attributes for sext/zext etc.
+  if (const AliasAttr *AA = D->getAttr<AliasAttr>()) {
+    assert(!D->getBody() && "Unexpected alias attr on function with body.");
+    
+    const std::string& aliaseeName = AA->getAliasee();
+    llvm::Function *aliasee = getModule().getFunction(aliaseeName);
+    llvm::GlobalValue *alias = new llvm::GlobalAlias(aliasee->getType(),
+                                              llvm::Function::ExternalLinkage,
+                                                     D->getName(),
+                                                     aliasee,
+                                                     &getModule());
+    SetGlobalValueAttributes(D, alias);
+    return alias;
+  } else {
+    const llvm::Type *Ty = getTypes().ConvertType(D->getType());
+    const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
+    llvm::Function *F = llvm::Function::Create(FTy, 
+                                               llvm::Function::ExternalLinkage,
+                                               D->getName(), &getModule());
+    
+    SetFunctionAttributes(D, F, FTy);
+    return F;
+  }
+}
+
+llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D) {
+  // See if it is already in the map.  If so, just return it.
+  llvm::Constant *&Entry = GlobalDeclMap[D];
+  if (Entry) return Entry;
+  
+  // Check to see if the function already exists; this occurs when
+  // this decl shadows a previous one. If it exists we bitcast it to
+  // the proper type for this decl and return.
+  llvm::Function *F = getModule().getFunction(D->getName());
+  if (F) {
+    const llvm::Type *Ty = getTypes().ConvertType(D->getType());
+    llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty);
+    return Entry = llvm::ConstantExpr::getBitCast(F, PFTy);
+  }
+
+  // It doesn't exist; create and return an entry.
+  return Entry = EmitForwardFunctionDefinition(D);
+}
+
+void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
+  llvm::Constant *&Entry = GlobalDeclMap[D];
+
+  const llvm::Type *Ty = getTypes().ConvertType(D->getType());
+  const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
+  
+  // Check to see if the function already exists.
+  llvm::Function *F = getModule().getFunction(D->getName());
+
+  // If it doesn't already exist, just create and return an entry.
+  if (F == 0) {
+    Entry = EmitForwardFunctionDefinition(D);
+  } else {
+    // If the pointer type matches, just return it.
+    llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty);
+    if (PFTy == F->getType()) {
+      Entry = F;
+    } else {    
+      // Otherwise, we have a definition after a prototype with the wrong type.
+      // F is the Function* for the one with the wrong type, we must make a new
+      // Function* and update everything that used F (a declaration) with the new
+      // Function* (which will be a definition).
+      //
+      // This happens if there is a prototype for a function (e.g. "int f()") and
+      // then a definition of a different type (e.g. "int f(int x)").  Start by
+      // making a new function of the correct type, RAUW, then steal the name.
+      llvm::Function *NewFn = llvm::Function::Create(FTy, 
+                                                     llvm::Function::ExternalLinkage,
+                                                     "", &getModule());
+      NewFn->takeName(F);
+      
+      // Replace uses of F with the Function we will endow with a body.
+      llvm::Constant *NewPtrForOldDecl = 
+        llvm::ConstantExpr::getBitCast(NewFn, F->getType());
+      F->replaceAllUsesWith(NewPtrForOldDecl);
+      
+      // FIXME: Update the globaldeclmap for the previous decl of this name.  We
+      // really want a way to walk all of these, but we don't have it yet.  This
+      // is incredibly slow!
+      ReplaceMapValuesWith(F, NewPtrForOldDecl);
+      
+      // Ok, delete the old function now, which is dead.
+      assert(F->isDeclaration() && "Shouldn't replace non-declaration");
+      F->eraseFromParent();
+      
+      SetFunctionAttributes(D, NewFn, FTy);
+      // Return the new function which has the right type.
+      Entry = NewFn;
+    }
+  }
+
+  if (D->getAttr<AliasAttr>()) {
+    ;
+  } else {
+    llvm::Function *Fn = cast<llvm::Function>(Entry);    
+    CodeGenFunction(*this).GenerateCode(D, Fn);
+  }
+}
+
 void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
   // Make sure that this type is translated.
   Types.UpdateCompletedType(TD);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Jul 29 18:18:29 2008
@@ -1,4 +1,4 @@
-//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen --------------===//
+//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -40,6 +40,7 @@
   class Expr;
   class Stmt;
   class NamedDecl;
+  class ValueDecl;
   class VarDecl;
   struct LangOptions;
   class Diagnostic;
@@ -66,7 +67,13 @@
   llvm::Function *MemMoveFn;
   llvm::Function *MemSetFn;
   llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
-  std::vector<const NamedDecl*> 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::vector<const ValueDecl*> StaticDecls;
   
   std::vector<llvm::Constant*> GlobalCtors;
   std::vector<llvm::Constant*> Annotations;
@@ -90,11 +97,14 @@
   CodeGenTypes &getTypes() { return Types; }
   Diagnostic &getDiags() const { return Diags; }
   const llvm::TargetData &getTargetData() const { return TheTargetData; }
-  
-  llvm::Constant *GetAddrOfFunctionDecl(const FunctionDecl *D,
-                                        bool isDefinition);
-  llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, bool isDefinition);
-  
+
+  /// GetAddrOfGlobalVar - Return the llvm::Constant for the address
+  /// of the given global variable.
+  llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D);
+
+  /// GetAddrOfFunction - Return the llvm::Constant for the address
+  /// of the given function.
+  llvm::Constant *GetAddrOfFunction(const FunctionDecl *D);  
   
   /// getBuiltinLibFunction - Given a builtin id for a function like
   /// "__builtin_fabsf", return a Function* for "fabsf".
@@ -111,21 +121,18 @@
   llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0, 
                                unsigned NumTys = 0);
   
-  void AddGlobalCtor(llvm::Function * Ctor);
-  void EmitGlobalCtors(void);
-  void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
-  void EmitAnnotations(void);
-  void EmitStatics(void);
-
   void EmitObjCMethod(const ObjCMethodDecl *OMD);
   void EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD);
   void EmitObjCClassImplementation(const ObjCImplementationDecl *OID);
   void EmitObjCProtocolImplementation(const ObjCProtocolDecl *PD);
-  void EmitFunction(const FunctionDecl *FD);
-  void EmitGlobalVar(const VarDecl *D);
-  void EmitGlobalVarInit(const VarDecl *D);
+
+  /// EmitGlobal - Emit code for a singal global function or var
+  /// decl. Forward declarations are emitted lazily.
+  void EmitGlobal(const ValueDecl *D);
+
+  void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
+
   void UpdateCompletedType(const TagDecl *D);
-  llvm::Constant *EmitGlobalInit(const Expr *E);
   llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
   llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
                                    const AnnotateAttr *AA, unsigned LineNo);
@@ -157,6 +164,16 @@
   void SetGlobalValueAttributes(const FunctionDecl *FD,
                                 llvm::GlobalValue *GV);
   
+  void EmitGlobalDefinition(const ValueDecl *D);
+  llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D);
+  void EmitGlobalFunctionDefinition(const FunctionDecl *D);
+  void EmitGlobalVarDefinition(const VarDecl *D);
+
+  void AddGlobalCtor(llvm::Function * Ctor);
+  void EmitGlobalCtors(void);
+  void EmitAnnotations(void);
+  void EmitStatics(void);
+
 };
 }  // end namespace CodeGen
 }  // end namespace clang

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

==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Tue Jul 29 18:18:29 2008
@@ -66,7 +66,9 @@
         return;
 
       if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-        Builder->EmitFunction(FD);
+        Builder->EmitGlobal(FD);
+      } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+        Builder->EmitGlobal(VD);
       } else if (isa<ObjCClassDecl>(D)){
         //Forward declaration.  Only used for type checking.
       } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)){
@@ -85,8 +87,6 @@
         // Ignore - generated when the implementation decl is CodeGen'd
       } else if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)){
         Builder->EmitObjCMethod(OMD);
-      } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-        Builder->EmitGlobalVar(VD);
       } else if (isa<ObjCClassDecl>(D) || isa<ObjCCategoryDecl>(D)) {
         // Forward declaration.  Only used for type checking.
       } else if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)){





More information about the cfe-commits mailing list