add an assertion to make it clear that PHI nodes are not allowed.
[oota-llvm.git] / lib / Transforms / IPO / Inliner.cpp
index cd204a74334bee2e8966595d9f07446b48a25565..ed177478e167448161904cc5b798ceb2905a3067 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "inline"
-#include "Inliner.h"
 #include "llvm/Module.h"
 #include "llvm/Instructions.h"
 #include "llvm/Analysis/CallGraph.h"
 #include "llvm/Support/CallSite.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/IPO/InlinerPass.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -30,15 +30,15 @@ using namespace llvm;
 STATISTIC(NumInlined, "Number of functions inlined");
 STATISTIC(NumDeleted, "Number of functions deleted because all callers found");
 
-namespace {
-  cl::opt<unsigned>             // FIXME: 200 is VERY conservative
-  InlineLimit("inline-threshold", cl::Hidden, cl::init(200),
+static cl::opt<int>
+InlineLimit("inline-threshold", cl::Hidden, cl::init(200),
         cl::desc("Control the amount of inlining to perform (default = 200)"));
-}
 
-char Inliner::ID = 0;
-Inliner::Inliner() 
-  : CallGraphSCCPass((intptr_t)&ID), InlineThreshold(InlineLimit) {}
+Inliner::Inliner(void *ID) 
+  : CallGraphSCCPass(ID), InlineThreshold(InlineLimit) {}
+
+Inliner::Inliner(void *ID, int Threshold) 
+  : CallGraphSCCPass(ID), InlineThreshold(Threshold) {}
 
 /// getAnalysisUsage - For this class, we declare that we require and preserve
 /// the call graph.  If the derived class implements this method, it should
@@ -54,18 +54,27 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
                                  const std::set<Function*> &SCCFunctions,
                                  const TargetData &TD) {
   Function *Callee = CS.getCalledFunction();
+  Function *Caller = CS.getCaller();
+
   if (!InlineFunction(CS, &CG, &TD)) return false;
 
+  // If the inlined function had a higher stack protection level than the
+  // calling function, then bump up the caller's stack protection level.
+  if (Callee->hasFnAttr(Attribute::StackProtectReq))
+    Caller->addFnAttr(Attribute::StackProtectReq);
+  else if (Callee->hasFnAttr(Attribute::StackProtect) &&
+           !Caller->hasFnAttr(Attribute::StackProtectReq))
+    Caller->addFnAttr(Attribute::StackProtect);
+
   // If we inlined the last possible call site to the function, delete the
   // function body now.
-  if (Callee->use_empty() && Callee->hasInternalLinkage() &&
+  if (Callee->use_empty() && Callee->hasLocalLinkage() &&
       !SCCFunctions.count(Callee)) {
     DOUT << "    -> Deleting dead function: " << Callee->getName() << "\n";
+    CallGraphNode *CalleeNode = CG[Callee];
 
     // Remove any call graph edges from the callee to its callees.
-    CallGraphNode *CalleeNode = CG[Callee];
-    while (CalleeNode->begin() != CalleeNode->end())
-      CalleeNode->removeCallEdgeTo((CalleeNode->end()-1)->second);
+    CalleeNode->removeAllCalledFunctions();
 
     // Removing the node for callee from the call graph and delete it.
     delete CG.removeFunctionFromModule(CalleeNode);
@@ -73,6 +82,44 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
   }
   return true;
 }
+        
+/// shouldInline - Return true if the inliner should attempt to inline
+/// at the given CallSite.
+bool Inliner::shouldInline(CallSite CS) {
+  InlineCost IC = getInlineCost(CS);
+  float FudgeFactor = getInlineFudgeFactor(CS);
+  
+  if (IC.isAlways()) {
+    DOUT << "    Inlining: cost=always"
+         << ", Call: " << *CS.getInstruction();
+    return true;
+  }
+  
+  if (IC.isNever()) {
+    DOUT << "    NOT Inlining: cost=never"
+         << ", Call: " << *CS.getInstruction();
+    return false;
+  }
+  
+  int Cost = IC.getValue();
+  int CurrentThreshold = InlineThreshold;
+  Function *Fn = CS.getCaller();
+  if (Fn && !Fn->isDeclaration() 
+      && Fn->hasFnAttr(Attribute::OptimizeForSize)
+      && InlineThreshold != 50) {
+    CurrentThreshold = 50;
+  }
+  
+  if (Cost >= (int)(CurrentThreshold * FudgeFactor)) {
+    DOUT << "    NOT Inlining: cost=" << Cost
+         << ", Call: " << *CS.getInstruction();
+    return false;
+  } else {
+    DOUT << "    Inlining: cost=" << Cost
+         << ", Call: " << *CS.getInstruction();
+    return true;
+  }
+}
 
 bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
   CallGraph &CG = getAnalysis<CallGraph>();
@@ -121,8 +168,7 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
     for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi)
       if (Function *Callee = CallSites[CSi].getCalledFunction()) {
         // Calls to external functions are never inlinable.
-        if (Callee->isDeclaration() ||
-            CallSites[CSi].getInstruction()->getParent()->getParent() ==Callee){
+        if (Callee->isDeclaration()) {
           if (SCC.size() == 1) {
             std::swap(CallSites[CSi], CallSites.back());
             CallSites.pop_back();
@@ -137,17 +183,16 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
         // If the policy determines that we should inline this function,
         // try to do so.
         CallSite CS = CallSites[CSi];
-        int InlineCost = getInlineCost(CS);
-        if (InlineCost >= (int)InlineThreshold) {
-          DOUT << "    NOT Inlining: cost=" << InlineCost
-               << ", Call: " << *CS.getInstruction();
-        } else {
-          DOUT << "    Inlining: cost=" << InlineCost
-               << ", Call: " << *CS.getInstruction();
-
+        if (shouldInline(CS)) {
+          Function *Caller = CS.getCaller();
           // Attempt to inline the function...
           if (InlineCallIfPossible(CS, CG, SCCFunctions, 
                                    getAnalysis<TargetData>())) {
+            // Remove any cached cost info for this caller, as inlining the callee
+            // has increased the size of the caller (which may be the same as the
+            // callee).
+            resetCachedCostInfo(Caller);
+
             // Remove this call site from the list.  If possible, use 
             // swap/pop_back for efficiency, but do not use it if doing so would
             // move a call site to a function in this SCC before the
@@ -174,6 +219,13 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
 // doFinalization - Remove now-dead linkonce functions at the end of
 // processing to avoid breaking the SCC traversal.
 bool Inliner::doFinalization(CallGraph &CG) {
+  return removeDeadFunctions(CG);
+}
+
+  /// removeDeadFunctions - Remove dead functions that are not included in
+  /// DNR (Do Not Remove) list.
+bool Inliner::removeDeadFunctions(CallGraph &CG, 
+                                 SmallPtrSet<const Function *, 16> *DNR) {
   std::set<CallGraphNode*> FunctionsToRemove;
 
   // Scan for all of the functions, looking for ones that should now be removed
@@ -185,12 +237,14 @@ bool Inliner::doFinalization(CallGraph &CG) {
       // them.
       F->removeDeadConstantUsers();
 
-      if ((F->hasLinkOnceLinkage() || F->hasInternalLinkage()) &&
+      if (DNR && DNR->count(F))
+        continue;
+
+      if ((F->hasLinkOnceLinkage() || F->hasLocalLinkage()) &&
           F->use_empty()) {
 
         // Remove any call graph edges from the function to its callees.
-        while (CGN->begin() != CGN->end())
-          CGN->removeCallEdgeTo((CGN->end()-1)->second);
+        CGN->removeAllCalledFunctions();
 
         // Remove any edges from the external node to the function's call graph
         // node.  These edges might have been made irrelegant due to