@@ -365,6 +365,26 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
365365 }
366366}
367367
368+ bool ExprEngine::isSmall (AnalysisDeclContext *ADC) const {
369+ // When there are no branches in the function, it means that there's no
370+ // exponential complexity introduced by inlining such function.
371+ // Such functions also don't trigger various fundamental problems
372+ // with our inlining mechanism, such as the problem of
373+ // inlined defensive checks. Hence isLinear().
374+ const CFG *Cfg = ADC->getCFG ();
375+ return Cfg->isLinear () || Cfg->size () <= AMgr.options .AlwaysInlineSize ;
376+ }
377+
378+ bool ExprEngine::isLarge (AnalysisDeclContext *ADC) const {
379+ const CFG *Cfg = ADC->getCFG ();
380+ return Cfg->size () >= AMgr.options .MinCFGSizeTreatFunctionsAsLarge ;
381+ }
382+
383+ bool ExprEngine::isHuge (AnalysisDeclContext *ADC) const {
384+ const CFG *Cfg = ADC->getCFG ();
385+ return Cfg->getNumBlockIDs () > AMgr.options .MaxInlinableSize ;
386+ }
387+
368388void ExprEngine::examineStackFrames (const Decl *D, const LocationContext *LCtx,
369389 bool &IsRecursive, unsigned &StackDepth) {
370390 IsRecursive = false ;
@@ -385,8 +405,7 @@ void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx,
385405
386406 // Do not count the small functions when determining the stack depth.
387407 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext (DI);
388- const CFG *CalleeCFG = CalleeADC->getCFG ();
389- if (CalleeCFG->getNumBlockIDs () > AMgr.options .AlwaysInlineSize )
408+ if (!isSmall (CalleeADC))
390409 ++StackDepth;
391410 }
392411 LCtx = LCtx->getParent ();
@@ -833,8 +852,7 @@ static bool isCXXSharedPtrDtor(const FunctionDecl *FD) {
833852// / This checks static properties of the function, such as its signature and
834853// / CFG, to determine whether the analyzer should ever consider inlining it,
835854// / in any context.
836- static bool mayInlineDecl (AnalysisManager &AMgr,
837- AnalysisDeclContext *CalleeADC) {
855+ bool ExprEngine::mayInlineDecl (AnalysisDeclContext *CalleeADC) const {
838856 AnalyzerOptions &Opts = AMgr.getAnalyzerOptions ();
839857 // FIXME: Do not inline variadic calls.
840858 if (CallEvent::isVariadic (CalleeADC->getDecl ()))
@@ -879,7 +897,7 @@ static bool mayInlineDecl(AnalysisManager &AMgr,
879897 return false ;
880898
881899 // Do not inline large functions.
882- if (CalleeCFG-> getNumBlockIDs () > Opts. MaxInlinableSize )
900+ if (isHuge (CalleeADC) )
883901 return false ;
884902
885903 // It is possible that the live variables analysis cannot be
@@ -919,7 +937,7 @@ bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
919937 } else {
920938 // We haven't actually checked the static properties of this function yet.
921939 // Do that now, and record our decision in the function summaries.
922- if (mayInlineDecl (getAnalysisManager (), CalleeADC)) {
940+ if (mayInlineDecl (CalleeADC)) {
923941 Engine.FunctionSummaries ->markMayInline (D);
924942 } else {
925943 Engine.FunctionSummaries ->markShouldNotInline (D);
@@ -940,29 +958,23 @@ bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
940958 return false ;
941959 }
942960
943- const CFG *CalleeCFG = CalleeADC->getCFG ();
944-
945961 // Do not inline if recursive or we've reached max stack frame count.
946962 bool IsRecursive = false ;
947963 unsigned StackDepth = 0 ;
948964 examineStackFrames (D, Pred->getLocationContext (), IsRecursive, StackDepth);
949965 if ((StackDepth >= Opts.InlineMaxStackDepth ) &&
950- ((CalleeCFG->getNumBlockIDs () > Opts.AlwaysInlineSize )
951- || IsRecursive))
966+ (!isSmall (CalleeADC) || IsRecursive))
952967 return false ;
953968
954969 // Do not inline large functions too many times.
955970 if ((Engine.FunctionSummaries ->getNumTimesInlined (D) >
956971 Opts.MaxTimesInlineLarge ) &&
957- CalleeCFG->getNumBlockIDs () >=
958- Opts.MinCFGSizeTreatFunctionsAsLarge ) {
972+ isLarge (CalleeADC)) {
959973 NumReachedInlineCountMax++;
960974 return false ;
961975 }
962976
963- if (HowToInline == Inline_Minimal &&
964- (CalleeCFG->getNumBlockIDs () > Opts.AlwaysInlineSize
965- || IsRecursive))
977+ if (HowToInline == Inline_Minimal && (!isSmall (CalleeADC) || IsRecursive))
966978 return false ;
967979
968980 return true ;
0 commit comments