diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp index 832fa468dd3f9..7eff04313bdef 100644 --- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp +++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp @@ -110,8 +110,8 @@ namespace { // to the actual transform helper functions. struct ArgInfo { Function *Fn; // The function to perform specialisation on. - Argument *Arg; // The Formal argument being analysed. - Constant *Const; // A corresponding actual constant argument. + Argument *Formal; // The Formal argument being analysed. + Constant *Actual; // A corresponding actual constant argument. InstructionCost Gain; // Profitability: Gain = Bonus - Cost. // Flag if this will be a partial specialization, in which case we will need @@ -120,7 +120,7 @@ struct ArgInfo { bool Partial = false; ArgInfo(Function *F, Argument *A, Constant *C, InstructionCost G) - : Fn(F), Arg(A), Const(C), Gain(G){}; + : Fn(F), Formal(A), Actual(C), Gain(G){}; }; } // Anonymous namespace @@ -289,12 +289,10 @@ class FunctionSpecializer { /// propagation across function boundaries. /// /// \returns true if at least one function is specialized. - bool - specializeFunctions(FuncList &FuncDecls, - FuncList &CurrentSpecializations) { + bool specializeFunctions(FuncList &Candidates, FuncList &WorkList) { bool Changed = false; - for (auto *F : FuncDecls) { - if (!isCandidateFunction(F, CurrentSpecializations)) + for (auto *F : Candidates) { + if (!isCandidateFunction(F)) continue; auto Cost = getSpecializationCost(F); @@ -311,12 +309,12 @@ class FunctionSpecializer { } for (auto &CA : ConstArgs) { - specializeFunction(CA, CurrentSpecializations); + specializeFunction(CA, WorkList); Changed = true; } } - updateSpecializedFuncs(FuncDecls, CurrentSpecializations); + updateSpecializedFuncs(Candidates, WorkList); NumFuncSpecialized += NbFunctionsSpecialized; return Changed; } @@ -401,13 +399,13 @@ class FunctionSpecializer { // be set to false by isArgumentInteresting (that function only adds // values to the Constants list that are deemed profitable). bool IsPartial = true; - SmallVector ActualConstArg; - if (!isArgumentInteresting(&FormalArg, ActualConstArg, IsPartial)) { + SmallVector ActualArgs; + if (!isArgumentInteresting(&FormalArg, ActualArgs, IsPartial)) { LLVM_DEBUG(dbgs() << "FnSpecialization: Argument is not interesting\n"); continue; } - for (auto *ActualArg : ActualConstArg) { + for (auto *ActualArg : ActualArgs) { InstructionCost Gain = ForceFunctionSpecialization ? 1 @@ -437,7 +435,7 @@ class FunctionSpecializer { Worklist.end()); } - if (IsPartial || Worklist.size() < ActualConstArg.size()) + if (IsPartial || Worklist.size() < ActualArgs.size()) for (auto &ActualArg : Worklist) ActualArg.Partial = true; @@ -445,8 +443,8 @@ class FunctionSpecializer { for (auto &C : Worklist) { dbgs() << "- Function = " << C.Fn->getName() << ", "; - dbgs() << "FormalArg = " << C.Arg->getName() << ", "; - dbgs() << "ActualArg = " << C.Const->getName() << ", "; + dbgs() << "FormalArg = " << C.Formal->getName() << ", "; + dbgs() << "ActualArg = " << C.Actual->getName() << ", "; dbgs() << "Gain = " << C.Gain << "\n"; }); @@ -456,7 +454,7 @@ class FunctionSpecializer { return Worklist; } - bool isCandidateFunction(Function *F, FuncList &Specializations) { + bool isCandidateFunction(Function *F) { // Do not specialize the cloned function again. if (SpecializedFuncs.contains(F)) return false; @@ -480,20 +478,20 @@ class FunctionSpecializer { return true; } - void specializeFunction(ArgInfo &AI, FuncList &Specializations) { + void specializeFunction(ArgInfo &AI, FuncList &WorkList) { Function *Clone = cloneCandidateFunction(AI.Fn); - Argument *ClonedArg = Clone->getArg(AI.Arg->getArgNo()); + Argument *ClonedArg = Clone->getArg(AI.Formal->getArgNo()); // Rewrite calls to the function so that they call the clone instead. - rewriteCallSites(AI.Fn, Clone, *ClonedArg, AI.Const); + rewriteCallSites(AI.Fn, Clone, *ClonedArg, AI.Actual); // Initialize the lattice state of the arguments of the function clone, // marking the argument on which we specialized the function constant // with the given value. - Solver.markArgInFuncSpecialization(AI.Fn, ClonedArg, AI.Const); + Solver.markArgInFuncSpecialization(AI.Fn, ClonedArg, AI.Actual); // Mark all the specialized functions - Specializations.push_back(Clone); + WorkList.push_back(Clone); NbFunctionsSpecialized++; // If the function has been completely specialized, the original function @@ -764,23 +762,21 @@ class FunctionSpecializer { } } - void updateSpecializedFuncs(FuncList &FuncDecls, - FuncList &CurrentSpecializations) { - for (auto *SpecializedFunc : CurrentSpecializations) { - SpecializedFuncs.insert(SpecializedFunc); + void updateSpecializedFuncs(FuncList &Candidates, FuncList &WorkList) { + for (auto *F : WorkList) { + SpecializedFuncs.insert(F); // Initialize the state of the newly created functions, marking them // argument-tracked and executable. - if (SpecializedFunc->hasExactDefinition() && - !SpecializedFunc->hasFnAttribute(Attribute::Naked)) - Solver.addTrackedFunction(SpecializedFunc); + if (F->hasExactDefinition() && !F->hasFnAttribute(Attribute::Naked)) + Solver.addTrackedFunction(F); - Solver.addArgumentTrackedFunction(SpecializedFunc); - FuncDecls.push_back(SpecializedFunc); - Solver.markBlockExecutable(&SpecializedFunc->front()); + Solver.addArgumentTrackedFunction(F); + Candidates.push_back(F); + Solver.markBlockExecutable(&F->front()); // Replace the function arguments for the specialized functions. - for (Argument &Arg : SpecializedFunc->args()) + for (Argument &Arg : F->args()) if (!Arg.use_empty() && tryToReplaceWithConstant(&Arg)) LLVM_DEBUG(dbgs() << "FnSpecialization: Replaced constant argument: " << Arg.getName() << "\n"); @@ -890,18 +886,18 @@ bool llvm::runFunctionSpecialization( // Initially resolve the constants in all the argument tracked functions. RunSCCPSolver(FuncDecls); - SmallVector CurrentSpecializations; + SmallVector WorkList; unsigned I = 0; while (FuncSpecializationMaxIters != I++ && - FS.specializeFunctions(FuncDecls, CurrentSpecializations)) { + FS.specializeFunctions(FuncDecls, WorkList)) { // Run the solver for the specialized functions. - RunSCCPSolver(CurrentSpecializations); + RunSCCPSolver(WorkList); // Replace some unresolved constant arguments. constantArgPropagation(FuncDecls, M, Solver); - CurrentSpecializations.clear(); + WorkList.clear(); Changed = true; } diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp index dac21468b4515..12cc6715ecab0 100644 --- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -536,18 +536,18 @@ void SCCPInstVisitor::markArgInFuncSpecialization(Function *F, Argument *A, // For the remaining arguments in the new function, copy the lattice state // over from the old function. - for (auto I = F->arg_begin(), J = A->getParent()->arg_begin(), - E = F->arg_end(); - I != E; ++I, ++J) - if (J != A && ValueState.count(I)) { + for (Argument *OldArg = F->arg_begin(), *NewArg = A->getParent()->arg_begin(), + *End = F->arg_end(); + OldArg != End; ++OldArg, ++NewArg) + if (NewArg != A && ValueState.count(OldArg)) { // Note: This previously looked like this: - // ValueState[J] = ValueState[I]; + // ValueState[NewArg] = ValueState[OldArg]; // This is incorrect because the DenseMap class may resize the underlying - // memory when inserting `J`, which will invalidate the reference to `I`. - // Instead, we make sure `J` exists, then set it to `I` afterwards. - auto &NewValue = ValueState[J]; - NewValue = ValueState[I]; - pushToWorkList(NewValue, J); + // memory when inserting `NewArg`, which will invalidate the reference to + // `OldArg`. Instead, we make sure `NewArg` exists before setting it. + auto &NewValue = ValueState[NewArg]; + NewValue = ValueState[OldArg]; + pushToWorkList(NewValue, NewArg); } }