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

Daniel Dunbar daniel at zuster.org
Mon Mar 9 11:47:55 PDT 2009


Mike,

Can you explain what motivated this commit? I do not like the road
this is going down; and without test cases or motivation I can't
necessarily understand how to rework CodeGenModule appropriately.

 - Daniel

On Sun, Mar 8, 2009 at 11:40 PM, Mike Stump <mrs at apple.com> wrote:
> Author: mrs
> Date: Mon Mar  9 01:40:26 2009
> New Revision: 66408
>
> URL: http://llvm.org/viewvc/llvm-project?rev=66408&view=rev
> Log:
> Be sure to never create two functions with the same name, instead arrange to
> reuse the prior one.
>
> 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=66408&r1=66407&r2=66408&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Mar  9 01:40:26 2009
> @@ -788,7 +788,8 @@
>
>  llvm::GlobalValue *
>  CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D,
> -                                             const llvm::Type *Ty) {
> +                                             const llvm::Type *Ty,
> +                                             bool ReplaceExisting) {
>   bool DoSetAttributes = true;
>   if (!Ty) {
>     Ty = getTypes().ConvertType(D->getType());
> @@ -801,10 +802,13 @@
>       DoSetAttributes = false;
>     }
>   }
> -  llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
> -                                             llvm::Function::ExternalLinkage,
> -                                             getMangledName(D),
> -                                             &getModule());
> +  const char *Name = getMangledName(D);
> +  llvm::Function *F = getModule().getFunction(Name);
> +  if (ReplaceExisting || !F || !F->hasExternalLinkage())
> +    F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
> +                               llvm::Function::ExternalLinkage,
> +                               Name,
> +                               &getModule());
>   if (DoSetAttributes)
>     SetFunctionAttributes(D, F);
>   return F;
> @@ -838,33 +842,33 @@
>   llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)];
>   if (!Entry) {
>     Entry = EmitForwardFunctionDefinition(D, Ty);
> -  } else {
> -    // If the types mismatch then we have to rewrite the definition.
> -    if (Entry->getType() != llvm::PointerType::getUnqual(Ty)) {
> -      // 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::GlobalValue *NewFn = EmitForwardFunctionDefinition(D, Ty);
> -      NewFn->takeName(Entry);
> -
> -      // Replace uses of F with the Function we will endow with a body.
> -      llvm::Constant *NewPtrForOldDecl =
> -        llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
> -      Entry->replaceAllUsesWith(NewPtrForOldDecl);
> -
> -      // Ok, delete the old function now, which is dead.
> -      assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
> -      Entry->eraseFromParent();
> -
> -      Entry = NewFn;
> -    }
> +  }
> +
> +  // If the types mismatch then we have to rewrite the definition.
> +  if (Entry->getType() != llvm::PointerType::getUnqual(Ty)) {
> +    // 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::GlobalValue *NewFn = EmitForwardFunctionDefinition(D, Ty, true);
> +    NewFn->takeName(Entry);
> +
> +    // Replace uses of F with the Function we will endow with a body.
> +    llvm::Constant *NewPtrForOldDecl =
> +      llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
> +    Entry->replaceAllUsesWith(NewPtrForOldDecl);
> +
> +    // Ok, delete the old function now, which is dead.
> +    assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
> +    Entry->eraseFromParent();
> +
> +    Entry = NewFn;
>   }
>
>   llvm::Function *Fn = cast<llvm::Function>(Entry);
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=66408&r1=66407&r2=66408&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Mar  9 01:40:26 2009
> @@ -312,14 +312,17 @@
>
>   void EmitGlobalDefinition(const ValueDecl *D);
>
> -  /// EmitForwardFunctionDefinition - Create a new function for the
> -  /// given decl and set attributes as appropriate.
> +  /// EmitForwardFunctionDefinition - Create a new function for the given decl
> +  /// and set attributes as appropriate if ReplaceExisting is true, or if the
> +  /// same named declaration doesn't already exist in the module table,
> +  /// otherwise return the existing function from the module table.
>   ///
> -  /// \arg Ty - If non-null the LLVM function type to use for the
> -  /// decl; it is the callers responsibility to make sure this is
> -  /// compatible with the correct type.
> +  /// \arg Ty - If non-null the LLVM function type to use for the decl; it is
> +  /// the callers responsibility to make sure this is compatible with the
> +  /// correct type.
>   llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D,
> -                                                   const llvm::Type *Ty);
> +                                                   const llvm::Type *Ty,
> +                                                   bool ReplaceExisting=false);
>
>   void EmitGlobalFunctionDefinition(const FunctionDecl *D);
>   void EmitGlobalVarDefinition(const VarDecl *D);
> @@ -337,19 +340,19 @@
>   void EmitAliases(void);
>   void EmitAnnotations(void);
>
> -  /// EmitDeferred - Emit any needed decls for which code generation
> -  /// was deferred.
> +  /// 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.
> +  /// EmitLLVMUsed - Emit the llvm.used metadata used to force references to
> +  /// global which may otherwise be optimized out.
>   void EmitLLVMUsed(void);
>
>   void BindRuntimeGlobals();
>
> -  /// MayDeferGeneration - Determine if the given decl can be emitted
> -  /// lazily; this is only relevant for definitions. The given decl
> -  /// must be either a function or var decl.
> +  /// MayDeferGeneration - Determine if the given decl can be emitted lazily;
> +  /// this is only relevant for definitions. The given decl must be either a
> +  /// function or var decl.
>   bool MayDeferGeneration(const ValueDecl *D);
>  };
>  }  // end namespace CodeGen
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list