/// 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; } }
/// inlineFuctions - Walk all call sites in all functions supplied by /// client. Inline as many call sites as possible. Delete completely /// inlined functions. void BasicInlinerImpl::inlineFunctions() { // Scan through and identify all call sites ahead of time so that we only // inline call sites in the original functions, not call sites that result // from inlining other functions. std::vector<CallSite> CallSites; for (std::vector<Function *>::iterator FI = Functions.begin(), FE = Functions.end(); FI != FE; ++FI) { Function *F = *FI; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { CallSite CS(cast<Value>(I)); if (CS && CS.getCalledFunction() && !CS.getCalledFunction()->isDeclaration()) CallSites.push_back(CS); } } DEBUG(dbgs() << ": " << CallSites.size() << " call sites.\n"); // Inline call sites. bool Changed = false; do { Changed = false; for (unsigned index = 0; index != CallSites.size() && !CallSites.empty(); ++index) { CallSite CS = CallSites[index]; if (Function *Callee = CS.getCalledFunction()) { // Eliminate calls that are never inlinable. if (Callee->isDeclaration() || CS.getInstruction()->getParent()->getParent() == Callee) { CallSites.erase(CallSites.begin() + index); --index; continue; } InlineCost IC = CA.getInlineCost(CS, NeverInline); if (IC.isAlways()) { DEBUG(dbgs() << " Inlining: cost=always" <<", call: " << *CS.getInstruction()); } else if (IC.isNever()) { DEBUG(dbgs() << " NOT Inlining: cost=never" <<", call: " << *CS.getInstruction()); continue; } else { int Cost = IC.getValue(); if (Cost >= (int) BasicInlineThreshold) { DEBUG(dbgs() << " NOT Inlining: cost = " << Cost << ", call: " << *CS.getInstruction()); continue; } else { DEBUG(dbgs() << " Inlining: cost = " << Cost << ", call: " << *CS.getInstruction()); } } // Inline InlineFunctionInfo IFI(0, TD); if (InlineFunction(CS, IFI)) { Callee->removeDeadConstantUsers(); if (Callee->isDefTriviallyDead()) DeadFunctions.insert(Callee); Changed = true; CallSites.erase(CallSites.begin() + index); --index; } } } } while (Changed); // Remove completely inlined functions from module. for(SmallPtrSet<Function *, 8>::iterator I = DeadFunctions.begin(), E = DeadFunctions.end(); I != E; ++I) { Function *D = *I; Module *M = D->getParent(); M->getFunctionList().remove(D); } }
/// shouldInline - Return true if the inliner should attempt to inline /// at the given CallSite. bool Inliner::shouldInline(CallSite CS) { InlineCost IC = getInlineCost(CS); if (IC.isAlways()) { DEBUG(dbgs() << " Inlining: cost=always" << ", Call: " << *CS.getInstruction() << "\n"); return true; } if (IC.isNever()) { DEBUG(dbgs() << " NOT Inlining: cost=never" << ", Call: " << *CS.getInstruction() << "\n"); return false; } int Cost = IC.getValue(); Function *Caller = CS.getCaller(); int CurrentThreshold = getInlineThreshold(CS); float FudgeFactor = getInlineFudgeFactor(CS); int AdjThreshold = (int)(CurrentThreshold * FudgeFactor); if (Cost >= AdjThreshold) { DEBUG(dbgs() << " NOT Inlining: cost=" << Cost << ", thres=" << AdjThreshold << ", Call: " << *CS.getInstruction() << "\n"); return false; } // Try to detect the case where the current inlining candidate caller // (call it B) is a static function and is an inlining candidate elsewhere, // and the current candidate callee (call it C) is large enough that // inlining it into B would make B too big to inline later. In these // circumstances it may be best not to inline C into B, but to inline B // into its callers. if (Caller->hasLocalLinkage()) { int TotalSecondaryCost = 0; bool outerCallsFound = false; bool allOuterCallsWillBeInlined = true; bool someOuterCallWouldNotBeInlined = false; for (Value::use_iterator I = Caller->use_begin(), E =Caller->use_end(); I != E; ++I) { CallSite CS2(*I); // If this isn't a call to Caller (it could be some other sort // of reference) skip it. if (!CS2 || CS2.getCalledFunction() != Caller) continue; InlineCost IC2 = getInlineCost(CS2); if (IC2.isNever()) allOuterCallsWillBeInlined = false; if (IC2.isAlways() || IC2.isNever()) continue; outerCallsFound = true; int Cost2 = IC2.getValue(); int CurrentThreshold2 = getInlineThreshold(CS2); float FudgeFactor2 = getInlineFudgeFactor(CS2); if (Cost2 >= (int)(CurrentThreshold2 * FudgeFactor2)) allOuterCallsWillBeInlined = false; // See if we have this case. We subtract off the penalty // for the call instruction, which we would be deleting. if (Cost2 < (int)(CurrentThreshold2 * FudgeFactor2) && Cost2 + Cost - (InlineConstants::CallPenalty + 1) >= (int)(CurrentThreshold2 * FudgeFactor2)) { someOuterCallWouldNotBeInlined = true; TotalSecondaryCost += Cost2; } } // If all outer calls to Caller would get inlined, the cost for the last // one is set very low by getInlineCost, in anticipation that Caller will // be removed entirely. We did not account for this above unless there // is only one caller of Caller. if (allOuterCallsWillBeInlined && Caller->use_begin() != Caller->use_end()) TotalSecondaryCost += InlineConstants::LastCallToStaticBonus; if (outerCallsFound && someOuterCallWouldNotBeInlined && TotalSecondaryCost < Cost) { DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction() << " Cost = " << Cost << ", outer Cost = " << TotalSecondaryCost << '\n'); return false; } } DEBUG(dbgs() << " Inlining: cost=" << Cost << ", thres=" << AdjThreshold << ", Call: " << *CS.getInstruction() << '\n'); 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); if (IC.isAlways()) { DEBUG(dbgs() << " Inlining: cost=always" << ", Call: " << *CS.getInstruction() << "\n"); return true; } if (IC.isNever()) { DEBUG(dbgs() << " NOT Inlining: cost=never" << ", Call: " << *CS.getInstruction() << "\n"); return false; } int Cost = IC.getValue(); Function *Caller = CS.getCaller(); int CurrentThreshold = getInlineThreshold(CS); float FudgeFactor = getInlineFudgeFactor(CS); int AdjThreshold = (int)(CurrentThreshold * FudgeFactor); if (Cost >= AdjThreshold) { DEBUG(dbgs() << " NOT Inlining: cost=" << Cost << ", thres=" << AdjThreshold << ", Call: " << *CS.getInstruction() << "\n"); return false; } // Try to detect the case where the current inlining candidate caller (call // it B) is a static or linkonce-ODR function and is an inlining candidate // elsewhere, and the current candidate callee (call it C) is large enough // that inlining it into B would make B too big to inline later. In these // circumstances it may be best not to inline C into B, but to inline B into // its callers. // // This only applies to static and linkonce-ODR functions because those are // expected to be available for inlining in the translation units where they // are used. Thus we will always have the opportunity to make local inlining // decisions. Importantly the linkonce-ODR linkage covers inline functions // and templates in C++. if (Caller->hasLocalLinkage() || Caller->getLinkage() == GlobalValue::LinkOnceODRLinkage) { int TotalSecondaryCost = 0; bool outerCallsFound = false; // This bool tracks what happens if we do NOT inline C into B. bool callerWillBeRemoved = true; // This bool tracks what happens if we DO inline C into B. bool inliningPreventsSomeOuterInline = false; for (Value::use_iterator I = Caller->use_begin(), E =Caller->use_end(); I != E; ++I) { CallSite CS2(*I); // If this isn't a call to Caller (it could be some other sort // of reference) skip it. Such references will prevent the caller // from being removed. if (!CS2 || CS2.getCalledFunction() != Caller) { callerWillBeRemoved = false; continue; } InlineCost IC2 = getInlineCost(CS2); if (IC2.isNever()) callerWillBeRemoved = false; if (IC2.isAlways() || IC2.isNever()) continue; outerCallsFound = true; int Cost2 = IC2.getValue(); int CurrentThreshold2 = getInlineThreshold(CS2); float FudgeFactor2 = getInlineFudgeFactor(CS2); if (Cost2 >= (int)(CurrentThreshold2 * FudgeFactor2)) callerWillBeRemoved = false; // See if we have this case. We subtract off the penalty // for the call instruction, which we would be deleting. if (Cost2 < (int)(CurrentThreshold2 * FudgeFactor2) && Cost2 + Cost - (InlineConstants::CallPenalty + 1) >= (int)(CurrentThreshold2 * FudgeFactor2)) { inliningPreventsSomeOuterInline = true; TotalSecondaryCost += Cost2; } } // If all outer calls to Caller would get inlined, the cost for the last // one is set very low by getInlineCost, in anticipation that Caller will // be removed entirely. We did not account for this above unless there // is only one caller of Caller. if (callerWillBeRemoved && Caller->use_begin() != Caller->use_end()) TotalSecondaryCost += InlineConstants::LastCallToStaticBonus; if (outerCallsFound && inliningPreventsSomeOuterInline && TotalSecondaryCost < Cost) { DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction() << " Cost = " << Cost << ", outer Cost = " << TotalSecondaryCost << '\n'); return false; } } DEBUG(dbgs() << " Inlining: cost=" << Cost << ", thres=" << AdjThreshold << ", Call: " << *CS.getInstruction() << '\n'); return true; }