[llvm-commits] [poolalloc] r107805 - /poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp

John Criswell criswell at uiuc.edu
Wed Jul 7 13:05:25 PDT 2010


Author: criswell
Date: Wed Jul  7 15:05:25 2010
New Revision: 107805

URL: http://llvm.org/viewvc/llvm-project?rev=107805&view=rev
Log:
Modified code so that it is permissible to not find any targets of an indirect
function call.
This can happen when a function pointer is loaded from an undef or NULL pointer
value.
This fixes PR#7580.

Modified:
    poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp

Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=107805&r1=107804&r2=107805&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Wed Jul  7 15:05:25 2010
@@ -654,13 +654,24 @@
 
   const Type* Int32Type = Type::getInt32Ty(CS.getInstruction()->getContext());
 
-  // If the called function is casted from one function type to another, peer
-  // into the cast instruction and pull out the actual function being called.
-  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(CS.getCalledValue()))
-    if (CE->getOpcode() == Instruction::BitCast &&
-        isa<Function>(CE->getOperand(0)))
-      CF = cast<Function>(CE->getOperand(0));
+  //
+  // Get the value that is called at this call site.  Strip away any pointer
+  // casts that do not change the representation of the data (i.e., are
+  // lossless casts).
+  //
+  Value * CalledValue = CS.getCalledValue()->stripPointerCasts();
+
+  //
+  // The CallSite::getCalledFunction() method is not guaranteed to strip off
+  // pointer casts.  If no called function was found, manually strip pointer
+  // casts off of the called value and see if we get a function.  If so, this
+  // is a direct call, and we want to update CF accordingly.
+  //
+  if (!CF) CF = dyn_cast<Function>(CalledValue);
 
+  //
+  // Do not change any inline assembly code.
+  //
   if (isa<InlineAsm>(TheCall->getOperand(0))) {
     errs() << "INLINE ASM: ignoring.  Hoping that's safe.\n";
     return;
@@ -669,9 +680,9 @@
   //
   // Ignore calls to NULL pointers or undefined values.
   //
-  if ((isa<ConstantPointerNull>(CS.getCalledValue())) ||
-      (isa<UndefValue>(CS.getCalledValue()))) {
-    errs() << "WARNING: Ignoring call using NULL function pointer.\n";
+  if ((isa<ConstantPointerNull>(CalledValue)) ||
+      (isa<UndefValue>(CalledValue))) {
+    errs() << "WARNING: Ignoring call using NULL/Undef function pointer.\n";
     return;
   }
 
@@ -783,10 +794,15 @@
     }
 
     //
-    // Do an assert unless we're bugpointing something.
+    // If we still haven't been able to find a target function of the call site
+    // to transform, do nothing.
+    //
+    // One may be tempted to think that we should always have at least one
+    // target, but this is not true.  There are perfectly acceptable (but
+    // strange) programs for which no function targets exist.  Function
+    // pointers loaded from undef values, for example, will have no targets.
     //
-    if ((UsingBugpoint) && (!CF)) return;
-    assert (CF && "No call graph info");
+    if (!CF) return;
 
     // Get the common graph for the set of functions this call may invoke.
     if (UsingBugpoint && (!(Graphs.hasDSGraph(*CF)))) return;





More information about the llvm-commits mailing list