aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SCCPSolver.cpp
diff options
context:
space:
mode:
authorAlexandros Lamprineas <alexandros.lamprineas@arm.com>2022-03-23 14:51:16 +0000
committerAlexandros Lamprineas <alexandros.lamprineas@arm.com>2022-03-28 12:01:53 +0100
commit8045bf9d0dc5be3a8b8d075fdfe23828f4b7d70e (patch)
tree4925585b8e4222023961658dbfa59ab52f468d46 /llvm/lib/Transforms/Utils/SCCPSolver.cpp
parent4ca111d4cb4c0b425268c86b54fb19c4be2e88dd (diff)
downloadllvm-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.cpp23
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) {