@@ -643,6 +643,18 @@ FunctionSpecializer::~FunctionSpecializer() {
643643 cleanUpSSA ();
644644}
645645
646+ // / Get the unsigned Value of given Cost object. Assumes the Cost is always
647+ // / non-negative, which is true for both TCK_CodeSize and TCK_Latency, and
648+ // / always Valid.
649+ static unsigned getCostValue (const Cost &C) {
650+ int64_t Value = *C.getValue ();
651+
652+ assert (Value >= 0 && " CodeSize and Latency cannot be negative" );
653+ // It is safe to down cast since we know the arguments cannot be negative and
654+ // Cost is of type int64_t.
655+ return static_cast <unsigned >(Value);
656+ }
657+
646658// / Attempt to specialize functions in the module to enable constant
647659// / propagation across function boundaries.
648660// /
@@ -757,6 +769,11 @@ bool FunctionSpecializer::run() {
757769 SmallVector<Function *> Clones;
758770 for (unsigned I = 0 ; I < NSpecs; ++I) {
759771 Spec &S = AllSpecs[BestSpecs[I]];
772+
773+ // Accumulate the codesize growth for the function, now we are creating the
774+ // specialization.
775+ FunctionGrowth[S.F ] += S.CodeSize ;
776+
760777 S.Clone = createSpecialization (S.F , S.Sig );
761778
762779 // Update the known call sites to call the clone.
@@ -835,18 +852,6 @@ static Function *cloneCandidateFunction(Function *F, unsigned NSpecs) {
835852 return Clone;
836853}
837854
838- // / Get the unsigned Value of given Cost object. Assumes the Cost is always
839- // / non-negative, which is true for both TCK_CodeSize and TCK_Latency, and
840- // / always Valid.
841- static unsigned getCostValue (const Cost &C) {
842- int64_t Value = *C.getValue ();
843-
844- assert (Value >= 0 && " CodeSize and Latency cannot be negative" );
845- // It is safe to down cast since we know the arguments cannot be negative and
846- // Cost is of type int64_t.
847- return static_cast <unsigned >(Value);
848- }
849-
850855bool FunctionSpecializer::findSpecializations (Function *F, unsigned FuncSize,
851856 SmallVectorImpl<Spec> &AllSpecs,
852857 SpecMap &SM) {
@@ -922,16 +927,14 @@ bool FunctionSpecializer::findSpecializations(Function *F, unsigned FuncSize,
922927 }
923928 CodeSize += Visitor.getCodeSizeSavingsFromPendingPHIs ();
924929
930+ unsigned CodeSizeSavings = getCostValue (CodeSize);
931+ unsigned SpecSize = FuncSize - CodeSizeSavings;
932+
925933 auto IsProfitable = [&]() -> bool {
926934 // No check required.
927935 if (ForceSpecialization)
928936 return true ;
929937
930- unsigned CodeSizeSavings = getCostValue (CodeSize);
931- // TODO: We should only accumulate codesize increase of specializations
932- // that are actually created.
933- FunctionGrowth[F] += FuncSize - CodeSizeSavings;
934-
935938 LLVM_DEBUG (
936939 dbgs () << " FnSpecialization: Specialization bonus {Inlining = "
937940 << Score << " (" << (Score * 100 / FuncSize) << " %)}\n " );
@@ -962,7 +965,7 @@ bool FunctionSpecializer::findSpecializations(Function *F, unsigned FuncSize,
962965 if (LatencySavings < MinLatencySavings * FuncSize / 100 )
963966 return false ;
964967 // Maximum codesize growth.
965- if (FunctionGrowth[F] / FuncSize > MaxCodeSizeGrowth)
968+ if (( FunctionGrowth[F] + SpecSize) / FuncSize > MaxCodeSizeGrowth)
966969 return false ;
967970
968971 Score += std::max (CodeSizeSavings, LatencySavings);
@@ -974,7 +977,7 @@ bool FunctionSpecializer::findSpecializations(Function *F, unsigned FuncSize,
974977 continue ;
975978
976979 // Create a new specialisation entry.
977- auto &Spec = AllSpecs.emplace_back (F, S, Score);
980+ auto &Spec = AllSpecs.emplace_back (F, S, Score, SpecSize );
978981 if (CS.getFunction () != F)
979982 Spec.CallSites .push_back (&CS);
980983 const unsigned Index = AllSpecs.size () - 1 ;
0 commit comments