* Finegrainify namespacification
authorChris Lattner <sabre@nondot.org>
Thu, 20 Nov 2003 21:21:31 +0000 (21:21 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 20 Nov 2003 21:21:31 +0000 (21:21 +0000)
* Implement FuncResolve/2003-11-20-BogusResolveWarning.ll
   ... which eliminates a large number of annoying warnings.  I know misha
   will miss them though!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10123 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/FunctionResolution.cpp

index 1a5c1faf394de7cb5016fecb3fa150d62f82ebd3..8361930e94437f6504edcada7213887eab6b6caa 100644 (file)
 #include "llvm/Pass.h"
 #include "llvm/iOther.h"
 #include "llvm/Constants.h"
+#include "llvm/Support/CallSite.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Assembly/Writer.h"
 #include "Support/Statistic.h"
 #include <algorithm>
-
-namespace llvm {
+using namespace llvm;
 
 namespace {
   Statistic<>NumResolved("funcresolve", "Number of varargs functions resolved");
@@ -45,7 +45,7 @@ namespace {
   RegisterOpt<FunctionResolvingPass> X("funcresolve", "Resolve Functions");
 }
 
-Pass *createFunctionResolvingPass() {
+Pass *llvm::createFunctionResolvingPass() {
   return new FunctionResolvingPass();
 }
 
@@ -134,6 +134,26 @@ static bool ResolveGlobalVariables(Module &M,
   return Changed;
 }
 
+// Check to see if all of the callers of F ignore the return value.
+static bool CallersAllIgnoreReturnValue(Function &F) {
+  if (F.getReturnType() == Type::VoidTy) return true;
+  for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) {
+    if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(*I)) {
+      for (Value::use_iterator I = CPR->use_begin(), E = CPR->use_end();
+           I != E; ++I) {
+        CallSite CS = CallSite::get(*I);
+        if (!CS.getInstruction() || !CS.getInstruction()->use_empty())
+          return false;
+      }
+    } else {
+      CallSite CS = CallSite::get(*I);
+      if (!CS.getInstruction() || !CS.getInstruction()->use_empty())
+        return false;
+    }
+  }
+  return true;
+}
+
 static bool ProcessGlobalsWithSameName(Module &M, TargetData &TD,
                                        std::vector<GlobalValue*> &Globals) {
   assert(!Globals.empty() && "Globals list shouldn't be empty here!");
@@ -159,7 +179,7 @@ static bool ProcessGlobalsWithSameName(Module &M, TargetData &TD,
         
         Concrete = Globals[i];
       } else if (Concrete) {
-        if (Concrete->isExternal()) // If we have multiple external symbols...x
+        if (Concrete->isExternal()) // If we have multiple external symbols...
           if (F->getFunctionType()->getNumParams() > 
               cast<Function>(Concrete)->getFunctionType()->getNumParams())
             Concrete = F;  // We are more concrete than "Concrete"!
@@ -205,10 +225,11 @@ static bool ProcessGlobalsWithSameName(Module &M, TargetData &TD,
     if (Concrete && Globals.size() == 2) {
       GlobalValue *Other = Globals[Globals[0] == Concrete];
       // If the non-concrete global is a function which takes (...) arguments,
-      // and the return values match, do not warn.
+      // and the return values match (or was never used), do not warn.
       if (Function *ConcreteF = dyn_cast<Function>(Concrete))
         if (Function *OtherF = dyn_cast<Function>(Other))
-          if (ConcreteF->getReturnType() == OtherF->getReturnType() &&
+          if ((ConcreteF->getReturnType() == OtherF->getReturnType() ||
+               CallersAllIgnoreReturnValue(*OtherF)) &&
               OtherF->getFunctionType()->isVarArg() &&
               OtherF->getFunctionType()->getParamTypes().empty())
             DontPrintWarning = true;
@@ -335,5 +356,3 @@ bool FunctionResolvingPass::run(Module &M) {
 
   return Changed;
 }
-
-} // End llvm namespace