[cfe-commits] r73273 - in /cfe/trunk: lib/CodeGen/CGCall.cpp lib/CodeGen/CGExpr.cpp test/CodeGen/always_inline.c
Chris Lattner
sabre at nondot.org
Fri Jun 12 17:26:38 PDT 2009
Author: lattner
Date: Fri Jun 12 19:26:38 2009
New Revision: 73273
URL: http://llvm.org/viewvc/llvm-project?rev=73273&view=rev
Log:
Fix PR4372, another case where non-prototyped functions can prevent
always_inline from working.
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGen/always_inline.c
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=73273&r1=73272&r2=73273&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Jun 12 19:26:38 2009
@@ -682,10 +682,12 @@
// location that we would like to return into.
QualType RetTy = CallInfo.getReturnType();
const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
- if (CGM.ReturnTypeUsesSret(CallInfo)) {
- // Create a temporary alloca to hold the result of the call. :(
+
+
+ // If the call returns a temporary with struct return, create a temporary
+ // alloca to hold the result.
+ if (CGM.ReturnTypeUsesSret(CallInfo))
Args.push_back(CreateTempAlloca(ConvertTypeForMem(RetTy)));
- }
assert(CallInfo.arg_size() == CallArgs.size() &&
"Mismatch between function signature & arguments.");
@@ -747,6 +749,35 @@
break;
}
}
+
+ // If the callee is a bitcast of a function to a varargs pointer to function
+ // type, check to see if we can remove the bitcast. This handles some cases
+ // with unprototyped functions.
+ if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Callee))
+ if (llvm::Function *CalleeF = dyn_cast<llvm::Function>(CE->getOperand(0))) {
+ const llvm::PointerType *CurPT=cast<llvm::PointerType>(Callee->getType());
+ const llvm::FunctionType *CurFT =
+ cast<llvm::FunctionType>(CurPT->getElementType());
+ const llvm::FunctionType *ActualFT = CalleeF->getFunctionType();
+
+ if (CE->getOpcode() == llvm::Instruction::BitCast &&
+ ActualFT->getReturnType() == CurFT->getReturnType() &&
+ ActualFT->getNumParams() == CurFT->getNumParams()) {
+ bool ArgsMatch = true;
+ for (unsigned i = 0, e = ActualFT->getNumParams(); i != e; ++i)
+ if (ActualFT->getParamType(i) != CurFT->getParamType(i)) {
+ ArgsMatch = false;
+ break;
+ }
+
+ // Strip the cast if we can get away with it. This is a nice cleanup,
+ // but also allows us to inline the function at -O0 if it is marked
+ // always_inline.
+ if (ArgsMatch)
+ Callee = CalleeF;
+ }
+ }
+
llvm::BasicBlock *InvokeDest = getInvokeDest();
CodeGen::AttributeListType AttributeList;
@@ -765,7 +796,8 @@
}
CS.setAttributes(Attrs);
- if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee->stripPointerCasts()))
+ if (const llvm::Function *F =
+ dyn_cast<llvm::Function>(Callee->stripPointerCasts()))
CS.setCallingConv(F->getCallingConv());
// If the call doesn't return, finish the basic block and clear the
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=73273&r1=73272&r2=73273&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Jun 12 19:26:38 2009
@@ -1156,10 +1156,9 @@
}
}
- if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E)) {
+ if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E))
if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(TargetDecl))
return EmitCXXOperatorMemberCallExpr(CE, MD);
- }
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
return EmitCall(Callee, E->getCallee()->getType(),
Modified: cfe/trunk/test/CodeGen/always_inline.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/always_inline.c?rev=73273&r1=73272&r2=73273&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/always_inline.c (original)
+++ cfe/trunk/test/CodeGen/always_inline.c Fri Jun 12 19:26:38 2009
@@ -1,5 +1,6 @@
// RUN: clang -emit-llvm -S -o %t %s &&
-// RUN: grep '@f0' %t | count 0 &&
+// RUN: not grep '@f0' %t &&
+// RUN: not grep 'call ' %t &&
// RUN: clang -mllvm -disable-llvm-optzns -emit-llvm -S -o %t %s &&
// RUN: grep '@f0' %t | count 2
@@ -11,3 +12,9 @@
int f1() {
return f0();
}
+
+// PR4372
+inline int f2() __attribute__((always_inline));
+int f2() { return 7; }
+int f3(void) { return f2(); }
+
More information about the cfe-commits
mailing list