add an assertion to make it clear that PHI nodes are not allowed.
[oota-llvm.git] / lib / Transforms / IPO / Inliner.cpp
index 74af18396d4adfc277fa765531fde28be6997360..ed177478e167448161904cc5b798ceb2905a3067 100644 (file)
@@ -54,11 +54,21 @@ 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];
@@ -76,9 +86,22 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
 /// shouldInline - Return true if the inliner should attempt to inline
 /// at the given CallSite.
 bool Inliner::shouldInline(CallSite CS) {
-  int Cost = getInlineCost(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() 
@@ -145,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();
@@ -162,9 +184,15 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
         // try to do so.
         CallSite CS = CallSites[CSi];
         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
@@ -191,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
@@ -202,7 +237,10 @@ 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.