diff options
author | Alexandros Lamprineas <alexandros.lamprineas@arm.com> | 2022-03-23 14:51:16 +0000 |
---|---|---|
committer | Alexandros Lamprineas <alexandros.lamprineas@arm.com> | 2022-03-28 12:01:53 +0100 |
commit | 8045bf9d0dc5be3a8b8d075fdfe23828f4b7d70e (patch) | |
tree | 4925585b8e4222023961658dbfa59ab52f468d46 /llvm/lib/Transforms/Utils/SCCPSolver.cpp | |
parent | 4ca111d4cb4c0b425268c86b54fb19c4be2e88dd (diff) | |
download | llvm-8045bf9d0dc5be3a8b8d075fdfe23828f4b7d70e.zip llvm-8045bf9d0dc5be3a8b8d075fdfe23828f4b7d70e.tar.gz llvm-8045bf9d0dc5be3a8b8d075fdfe23828f4b7d70e.tar.bz2 |
[FuncSpec] Support function specialization across multiple arguments.
The current implementation of Function Specialization does not allow
specializing more than one arguments per function call, which is a
limitation I am lifting with this patch.
My main challenge was to choose the most suitable ADT for storing the
specializations. We need an associative container for binding all the
actual arguments of a specialization to the function call. We also
need a consistent iteration order across executions. Lastly we want
to be able to sort the entries by Gain and reject the least profitable
ones.
MapVector fits the bill but not quite; erasing elements is expensive
and using stable_sort messes up the indices to the underlying vector.
I am therefore using the underlying vector directly after calculating
the Gain.
Differential Revision: https://reviews.llvm.org/D119880
Diffstat (limited to 'llvm/lib/Transforms/Utils/SCCPSolver.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SCCPSolver.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp index 88dd5e6..607928c 100644 --- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -450,7 +450,8 @@ public: return TrackingIncomingArguments; } - void markArgInFuncSpecialization(Function *F, const ArgInfo &Arg); + void markArgInFuncSpecialization(Function *F, + const SmallVectorImpl<ArgInfo> &Args); void markFunctionUnreachable(Function *F) { for (auto &BB : *F) @@ -524,21 +525,24 @@ Constant *SCCPInstVisitor::getConstant(const ValueLatticeElement &LV) const { return nullptr; } -void SCCPInstVisitor::markArgInFuncSpecialization(Function *F, - const ArgInfo &Arg) { - assert(F->arg_size() == Arg.Formal->getParent()->arg_size() && +void SCCPInstVisitor::markArgInFuncSpecialization( + Function *F, const SmallVectorImpl<ArgInfo> &Args) { + assert(!Args.empty() && "Specialization without arguments"); + assert(F->arg_size() == Args[0].Formal->getParent()->arg_size() && "Functions should have the same number of arguments"); + auto Iter = Args.begin(); Argument *NewArg = F->arg_begin(); - Argument *OldArg = Arg.Formal->getParent()->arg_begin(); + Argument *OldArg = Args[0].Formal->getParent()->arg_begin(); for (auto End = F->arg_end(); NewArg != End; ++NewArg, ++OldArg) { LLVM_DEBUG(dbgs() << "SCCP: Marking argument " << NewArg->getNameOrAsOperand() << "\n"); - if (OldArg == Arg.Formal) { + if (OldArg == Iter->Formal) { // Mark the argument constants in the new function. - markConstant(NewArg, Arg.Actual); + markConstant(NewArg, Iter->Actual); + ++Iter; } else if (ValueState.count(OldArg)) { // For the remaining arguments in the new function, copy the lattice state // over from the old function. @@ -1717,8 +1721,9 @@ SmallPtrSetImpl<Function *> &SCCPSolver::getArgumentTrackedFunctions() { return Visitor->getArgumentTrackedFunctions(); } -void SCCPSolver::markArgInFuncSpecialization(Function *F, const ArgInfo &Arg) { - Visitor->markArgInFuncSpecialization(F, Arg); +void SCCPSolver::markArgInFuncSpecialization( + Function *F, const SmallVectorImpl<ArgInfo> &Args) { + Visitor->markArgInFuncSpecialization(F, Args); } void SCCPSolver::markFunctionUnreachable(Function *F) { |