[cfe-commits] r65032 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/functions.c
Daniel Dunbar
daniel at zuster.org
Wed Feb 18 23:15:40 PST 2009
Author: ddunbar
Date: Thu Feb 19 01:15:39 2009
New Revision: 65032
URL: http://llvm.org/viewvc/llvm-project?rev=65032&view=rev
Log:
Don't emit K&R unprototyped function definitions as varargs.
- <rdar://problem/6584606> clang/x86-64 - too many reg saves
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/test/CodeGen/functions.c
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=65032&r1=65031&r2=65032&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Feb 19 01:15:39 2009
@@ -773,8 +773,10 @@
}
llvm::GlobalValue *
-CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) {
- const llvm::Type *Ty = getTypes().ConvertType(D->getType());
+CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D,
+ const llvm::Type *Ty) {
+ if (!Ty)
+ Ty = getTypes().ConvertType(D->getType());
llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
llvm::Function::ExternalLinkage,
getMangledName(D),
@@ -791,28 +793,40 @@
// Lookup the entry, lazily creating it if necessary.
llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)];
if (!Entry)
- Entry = EmitForwardFunctionDefinition(D);
+ Entry = EmitForwardFunctionDefinition(D, 0);
return llvm::ConstantExpr::getBitCast(Entry, PTy);
}
void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
+ const llvm::FunctionType *Ty =
+ cast<llvm::FunctionType>(getTypes().ConvertType(D->getType()));
+
+ // As a special case, make sure that definitions of K&R function
+ // "type foo()" aren't declared as varargs (which forces the backend
+ // to do unnecessary work).
+ if (Ty->isVarArg() && Ty->getNumParams() == 0 && Ty->isVarArg())
+ Ty = llvm::FunctionType::get(Ty->getReturnType(),
+ std::vector<const llvm::Type*>(),
+ false);
+
llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)];
if (!Entry) {
- Entry = EmitForwardFunctionDefinition(D);
+ Entry = EmitForwardFunctionDefinition(D, Ty);
} else {
// If the types mismatch then we have to rewrite the definition.
- const llvm::Type *Ty = getTypes().ConvertType(D->getType());
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).
+ // 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);
+ // 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.
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=65032&r1=65031&r2=65032&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Feb 19 01:15:39 2009
@@ -322,7 +322,16 @@
void EmitGlobal(const ValueDecl *D);
void EmitGlobalDefinition(const ValueDecl *D);
- llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D);
+
+ /// EmitForwardFunctionDefinition - Create a new function for the
+ /// given decl and set attributes as appropriate.
+ ///
+ /// \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);
+
void EmitGlobalFunctionDefinition(const FunctionDecl *D);
void EmitGlobalVarDefinition(const VarDecl *D);
void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
Modified: cfe/trunk/test/CodeGen/functions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/functions.c?rev=65032&r1=65031&r2=65032&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/functions.c (original)
+++ cfe/trunk/test/CodeGen/functions.c Thu Feb 19 01:15:39 2009
@@ -1,4 +1,5 @@
-// RUN: clang %s -emit-llvm -o -
+// RUN: clang %s -emit-llvm -o %t &&
+
int g();
int foo(int i) {
@@ -17,3 +18,14 @@
int a(int);
int a() {return 1;}
+
+// RUN: grep 'define void @f0()' %t &&
+void f0() {}
+
+void f1();
+// RUN: grep 'call void (...)\* bitcast (void ()\* @f1' %t &&
+void f2(void) {
+ f1(1, 2, 3);
+}
+// RUN: grep 'define void @f1()' %t
+void f1() {}
More information about the cfe-commits
mailing list