[FuncSpec][NFC] Add an alias for InstructionCost.
authorAlexandros Lamprineas <alexandros.lamprineas@arm.com>
Tue, 9 May 2023 10:09:49 +0000 (11:09 +0100)
committerAlexandros Lamprineas <alexandros.lamprineas@arm.com>
Tue, 9 May 2023 10:37:48 +0000 (11:37 +0100)
Split from D145379. I'll rethink the Cost model improvements and
commit separately.

llvm/include/llvm/Transforms/IPO/FunctionSpecialization.h
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp

index 831717c..e37386c 100644 (file)
 using namespace llvm;
 
 namespace llvm {
+// Map of potential specializations for each function. The FunctionSpecializer
+// keeps the discovered specialisation opportunities for the module in a single
+// vector, where the specialisations of each function form a contiguous range.
+// This map's value is the beginning and the end of that range.
+using SpecMap = DenseMap<Function *, std::pair<unsigned, unsigned>>;
+
+// Just a shorter abbreviation to improve indentation.
+using Cost = InstructionCost;
+
 // Specialization signature, used to uniquely designate a specialization within
 // a function.
 struct SpecSig {
@@ -95,23 +104,17 @@ struct Spec {
   SpecSig Sig;
 
   // Profitability of the specialization.
-  InstructionCost Gain;
+  Cost Score;
 
   // List of call sites, matching this specialization.
   SmallVector<CallBase *> CallSites;
 
-  Spec(Function *F, const SpecSig &S, InstructionCost G)
-      : F(F), Sig(S), Gain(G) {}
-  Spec(Function *F, const SpecSig &&S, InstructionCost G)
-      : F(F), Sig(S), Gain(G) {}
+  Spec(Function *F, const SpecSig &S, Cost Score)
+      : F(F), Sig(S), Score(Score) {}
+  Spec(Function *F, const SpecSig &&S, Cost Score)
+      : F(F), Sig(S), Score(Score) {}
 };
 
-// Map of potential specializations for each function. The FunctionSpecializer
-// keeps the discovered specialisation opportunities for the module in a single
-// vector, where the specialisations of each function form a contiguous range.
-// This map's value is the beginning and the end of that range.
-using SpecMap = DenseMap<Function *, std::pair<unsigned, unsigned>>;
-
 class FunctionSpecializer {
 
   /// The IPSCCP Solver.
@@ -170,12 +173,12 @@ private:
 
   /// @brief  Find potential specialization opportunities.
   /// @param F Function to specialize
-  /// @param Cost Cost of specializing a function. Final gain is this cost
-  /// minus benefit
+  /// @param SpecCost Cost of specializing a function. Final score is benefit
+  /// minus this cost.
   /// @param AllSpecs A vector to add potential specializations to.
   /// @param SM  A map for a function's specialisation range
   /// @return True, if any potential specializations were found
-  bool findSpecializations(Function *F, InstructionCost Cost,
+  bool findSpecializations(Function *F, Cost SpecCost,
                            SmallVectorImpl<Spec> &AllSpecs, SpecMap &SM);
 
   bool isCandidateFunction(Function *F);
@@ -187,11 +190,10 @@ private:
   Function *createSpecialization(Function *F, const SpecSig &S);
 
   /// Compute and return the cost of specializing function \p F.
-  InstructionCost getSpecializationCost(Function *F);
+  Cost getSpecializationCost(Function *F);
 
   /// Compute a bonus for replacing argument \p A with constant \p C.
-  InstructionCost getSpecializationBonus(Argument *A, Constant *C,
-                                         const LoopInfo &LI);
+  Cost getSpecializationBonus(Argument *A, Constant *C, const LoopInfo &LI);
 
   /// Determine if it is possible to specialise the function for constant values
   /// of the formal parameter \p A.
index 3549eec..7d08298 100644 (file)
@@ -274,17 +274,17 @@ bool FunctionSpecializer::run() {
     if (!isCandidateFunction(&F))
       continue;
 
-    auto Cost = getSpecializationCost(&F);
-    if (!Cost.isValid()) {
+    Cost SpecCost = getSpecializationCost(&F);
+    if (!SpecCost.isValid()) {
       LLVM_DEBUG(dbgs() << "FnSpecialization: Invalid specialization cost for "
                         << F.getName() << "\n");
       continue;
     }
 
     LLVM_DEBUG(dbgs() << "FnSpecialization: Specialization cost for "
-                      << F.getName() << " is " << Cost << "\n");
+                      << F.getName() << " is " << SpecCost << "\n");
 
-    if (!findSpecializations(&F, Cost, AllSpecs, SM)) {
+    if (!findSpecializations(&F, SpecCost, AllSpecs, SM)) {
       LLVM_DEBUG(
           dbgs() << "FnSpecialization: No possible specializations found for "
                  << F.getName() << "\n");
@@ -304,8 +304,8 @@ bool FunctionSpecializer::run() {
   // Choose the most profitable specialisations, which fit in the module
   // specialization budget, which is derived from maximum number of
   // specializations per specialization candidate function.
-  auto CompareGain = [&AllSpecs](unsigned I, unsigned J) {
-    return AllSpecs[I].Gain > AllSpecs[J].Gain;
+  auto CompareScore = [&AllSpecs](unsigned I, unsigned J) {
+    return AllSpecs[I].Score > AllSpecs[J].Score;
   };
   const unsigned NSpecs =
       std::min(NumCandidates * MaxClones, unsigned(AllSpecs.size()));
@@ -317,11 +317,11 @@ bool FunctionSpecializer::run() {
                       << "FnSpecialization: Specializing the "
                       << NSpecs
                       << " most profitable candidates.\n");
-    std::make_heap(BestSpecs.begin(), BestSpecs.begin() + NSpecs, CompareGain);
+    std::make_heap(BestSpecs.begin(), BestSpecs.begin() + NSpecs, CompareScore);
     for (unsigned I = NSpecs, N = AllSpecs.size(); I < N; ++I) {
       BestSpecs[NSpecs] = I;
-      std::push_heap(BestSpecs.begin(), BestSpecs.end(), CompareGain);
-      std::pop_heap(BestSpecs.begin(), BestSpecs.end(), CompareGain);
+      std::push_heap(BestSpecs.begin(), BestSpecs.end(), CompareScore);
+      std::pop_heap(BestSpecs.begin(), BestSpecs.end(), CompareScore);
     }
   }
 
@@ -329,7 +329,7 @@ bool FunctionSpecializer::run() {
              for (unsigned I = 0; I < NSpecs; ++I) {
                const Spec &S = AllSpecs[BestSpecs[I]];
                dbgs() << "FnSpecialization: Function " << S.F->getName()
-                      << " , gain " << S.Gain << "\n";
+                      << " , score " << S.Score << "\n";
                for (const ArgInfo &Arg : S.Sig.Args)
                  dbgs() << "FnSpecialization:   FormalArg = "
                         << Arg.Formal->getNameOrAsOperand()
@@ -434,7 +434,7 @@ static Function *cloneCandidateFunction(Function *F) {
   return Clone;
 }
 
-bool FunctionSpecializer::findSpecializations(Function *F, InstructionCost Cost,
+bool FunctionSpecializer::findSpecializations(Function *F, Cost SpecCost,
                                               SmallVectorImpl<Spec> &AllSpecs,
                                               SpecMap &SM) {
   // A mapping from a specialisation signature to the index of the respective
@@ -501,17 +501,17 @@ bool FunctionSpecializer::findSpecializations(Function *F, InstructionCost Cost,
       AllSpecs[Index].CallSites.push_back(&CS);
     } else {
       // Calculate the specialisation gain.
-      InstructionCost Gain = 0 - Cost;
+      Cost Score = 0 - SpecCost;
       for (ArgInfo &A : S.Args)
-        Gain +=
+        Score +=
             getSpecializationBonus(A.Formal, A.Actual, Solver.getLoopInfo(*F));
 
       // Discard unprofitable specialisations.
-      if (!ForceSpecialization && Gain <= 0)
+      if (!ForceSpecialization && Score <= 0)
         continue;
 
       // Create a new specialisation entry.
-      auto &Spec = AllSpecs.emplace_back(F, S, Gain);
+      auto &Spec = AllSpecs.emplace_back(F, S, Score);
       if (CS.getFunction() != F)
         Spec.CallSites.push_back(&CS);
       const unsigned Index = AllSpecs.size() - 1;
@@ -555,7 +555,8 @@ bool FunctionSpecializer::isCandidateFunction(Function *F) {
   return true;
 }
 
-Function *FunctionSpecializer::createSpecialization(Function *F, const SpecSig &S) {
+Function *FunctionSpecializer::createSpecialization(Function *F,
+                                                    const SpecSig &S) {
   Function *Clone = cloneCandidateFunction(F);
 
   // The original function does not neccessarily have internal linkage, but the
@@ -578,7 +579,7 @@ Function *FunctionSpecializer::createSpecialization(Function *F, const SpecSig &
 }
 
 /// Compute and return the cost of specializing function \p F.
-InstructionCost FunctionSpecializer::getSpecializationCost(Function *F) {
+Cost FunctionSpecializer::getSpecializationCost(Function *F) {
   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.
@@ -594,8 +595,8 @@ InstructionCost FunctionSpecializer::getSpecializationCost(Function *F) {
   return Metrics.NumInsts * InlineConstants::getInstrCost();
 }
 
-static InstructionCost getUserBonus(User *U, llvm::TargetTransformInfo &TTI,
-                                    const LoopInfo &LI) {
+static Cost getUserBonus(User *U, TargetTransformInfo &TTI,
+                         const LoopInfo &LI) {
   auto *I = dyn_cast_or_null<Instruction>(U);
   // If not an instruction we do not know how to evaluate.
   // Keep minimum possible cost for now so that it doesnt affect
@@ -603,32 +604,31 @@ static InstructionCost getUserBonus(User *U, llvm::TargetTransformInfo &TTI,
   if (!I)
     return std::numeric_limits<unsigned>::min();
 
-  InstructionCost Cost =
+  Cost Bonus =
       TTI.getInstructionCost(U, TargetTransformInfo::TCK_SizeAndLatency);
 
   // Increase the cost if it is inside the loop.
   unsigned LoopDepth = LI.getLoopDepth(I->getParent());
-  Cost *= std::pow((double)AvgLoopIters, LoopDepth);
+  Bonus *= std::pow((double)AvgLoopIters, LoopDepth);
 
   // Traverse recursively if there are more uses.
   // TODO: Any other instructions to be added here?
   if (I->mayReadFromMemory() || I->isCast())
     for (auto *User : I->users())
-      Cost += getUserBonus(User, TTI, LI);
+      Bonus += getUserBonus(User, TTI, LI);
 
-  return Cost;
+  return Bonus;
 }
 
 /// Compute a bonus for replacing argument \p A with constant \p C.
-InstructionCost
-FunctionSpecializer::getSpecializationBonus(Argument *A, Constant *C,
-                                            const LoopInfo &LI) {
+Cost FunctionSpecializer::getSpecializationBonus(Argument *A, Constant *C,
+                                                 const LoopInfo &LI) {
   Function *F = A->getParent();
   auto &TTI = (GetTTI)(*F);
   LLVM_DEBUG(dbgs() << "FnSpecialization: Analysing bonus for constant: "
                     << C->getNameOrAsOperand() << "\n");
 
-  InstructionCost TotalCost = 0;
+  Cost TotalCost = 0;
   for (auto *U : A->users()) {
     TotalCost += getUserBonus(U, TTI, LI);
     LLVM_DEBUG(dbgs() << "FnSpecialization:   User cost ";
@@ -766,7 +766,7 @@ void FunctionSpecializer::updateCallSites(Function *F, const Spec *Begin,
     // Find the best matching specialisation.
     const Spec *BestSpec = nullptr;
     for (const Spec &S : make_range(Begin, End)) {
-      if (!S.Clone || (BestSpec && S.Gain <= BestSpec->Gain))
+      if (!S.Clone || (BestSpec && S.Score <= BestSpec->Score))
         continue;
 
       if (any_of(S.Sig.Args, [CS, this](const ArgInfo &Arg) {