[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