[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