diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp --- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp +++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp @@ -21,8 +21,6 @@ // but that's off by default under an option. // - The cost-model could be further looked into (it mainly focuses on inlining // benefits), -// - We are not yet caching analysis results, but profiling and checking where -// extra compile time is spent didn't suggest this to be a problem. // // Ideas: // - With a function specialization attribute for arguments, we could have @@ -281,6 +279,7 @@ SmallPtrSet SpecializedFuncs; SmallPtrSet FullySpecialized; SmallVector ReplacedWithConstant; + DenseMap FunctionMetrics; public: FunctionSpecializer(SCCPSolver &Solver, @@ -390,6 +389,24 @@ // also in the cost model. unsigned NbFunctionsSpecialized = 0; + // Compute the code metrics for function \p F. + CodeMetrics &analyzeFunction(Function *F) { + auto I = FunctionMetrics.insert({F, CodeMetrics()}); + CodeMetrics &Metrics = I.first->second; + if (I.second) { + // The code metrics were not cached. + SmallPtrSet EphValues; + CodeMetrics::collectEphemeralValues(F, &(GetAC)(*F), EphValues); + for (BasicBlock &BB : *F) + Metrics.analyzeBasicBlock(&BB, (GetTTI)(*F), EphValues); + + LLVM_DEBUG(dbgs() << "FnSpecialization: Code size of function " + << F->getName() << " is " << Metrics.NumInsts + << " instructions\n"); + } + return Metrics; + } + /// Clone the function \p F and remove the ssa_copy intrinsics added by /// the SCCPSolver in the cloned version. Function *cloneCandidateFunction(Function *F, ValueToValueMapTy &Mappings) { @@ -528,13 +545,7 @@ /// Compute and return the cost of specializing function \p F. InstructionCost getSpecializationCost(Function *F) { - // Compute the code metrics for the function. - SmallPtrSet EphValues; - CodeMetrics::collectEphemeralValues(F, &(GetAC)(*F), EphValues); - CodeMetrics Metrics; - for (BasicBlock &BB : *F) - Metrics.analyzeBasicBlock(&BB, (GetTTI)(*F), EphValues); - + CodeMetrics &Metrics = analyzeFunction(F); // If the code metrics reveal that we shouldn't duplicate the function, we // shouldn't specialize it. Set the specialization cost to Invalid. // Or if the lines of codes implies that this function is easy to get