Move SCCPSolver class to header file so that it can be used by other passes / transformations.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I think it makes sense to expose this more widely in general. But could you share the places where you intend to make use of it?
I think we should restrict the public interface exposed to what really is required for external clients, and keep other details in the .cpp file (e.g. most of the members related to function/argument tracking and the worklists could stay in the .cpp
I have a follow up patch which uses constant parameter propagation. I would need the members related to argument tracking, etc., exposed to the user. I agree that some of the public interfaces can be moved to .cpp file. I intend to do that in a separate patch.
@mivnay It would be helpful to already put up the patch for your intended use case (as a dependent revision), so it's possible to evaluate this in context.
This looks like a fine first step to separate SCCPSolver from SCCP. I agree with @fhahn that the SCCPSolver class should be improved by pulling out implementation details into (separate, hidden) classes, but this is probably best reviewed in separate patches. At least it looks like the public interface of SCCPSolver is already restricted to what is needed by SCCP.
include/llvm/Transforms/Scalar/SCCP.h | ||
---|---|---|
30 ↗ | (On Diff #320744) | Ideally, this include should not be needed. Perhaps keep the definition of struct AnalysisResultsForFn in this file (as it is part of the runIPSCCP interface) and create a similar (but differently named) struct for the implementation detail of the SCCPSolver. |
include/llvm/Transforms/Utils/SCCPSolver.h | ||
14–16 ↗ | (On Diff #320744) | Reflect the new location |
include/llvm/Transforms/Scalar/SCCP.h | ||
---|---|---|
30 ↗ | (On Diff #320744) | struct AnalysisResultsForFn is part of the SCCPSolver.AnalysisResults. runIPSCCP just passes it on to the SCCPSolver via void SCCPSolver::addAnalysis(Function &F, AnalysisResultsForFn A) interface. It would be compilation error to pass a different type. |
This looks good to me. @fhahn are you happy with the suggested approach to tighten up the SCCPSolver class in subsequent patches, when function inlining starts using it?
include/llvm/Transforms/Scalar/SCCP.h | ||
---|---|---|
30 ↗ | (On Diff #320744) | Ah fair enough; I still think we can break this dependency, but we can do that afterwards. |
IMO we should nail down the interface first, rather than starting with exposing/moving everything, to avoid a lot of unnecessary churn. As it is structured now, it is not easy to see what is really needed for D93838
I think it makes sense to expose this more widely in general. But could you share the places where you intend to make use of it?
@fhahn SCCPSolver is hidden inside the SCCP.cpp file. I could just call the interface functions provided in the SCCP.h files and use it in my pass. But, it will be super in-efficient as I will be building the Solver repeatedly with almost same set of already computed lattice values. Wouldn't it be better to expose the utility to other users as you also agreed before?
rather than starting with exposing/moving everything, to avoid a lot of unnecessary churn.
SCCPSolver is a single class. Do you want me to move some of the functions to private / protected mode? If so, isn't it better to do that in a different review where changes are easier to track?
Rebase to get this applied and compiling again.
I am now looking into the feedback what we should be exposing.
Applied clang-format.
Could I get some advice what we would like to expose? I looked at the transformation that uses the solvers, and the functions used are:
addAnalysis addToMustPreserveReturnsInFunctions AddTrackedFunction AddArgumentTrackedFunction getConstant getStructLatticeValueFor getDTU getPredicateInfoFor getTrackedRetVals getMRVFunctionsTracked isBlockExecutable isArgumentTrackedFunction isEdgeFeasible isStructLatticeConstant MarkBlockExecutable markOverdefined mustPreserveReturn removeLatticeValueFor ResolvedUndefsIn TrackValueOfGlobalVariable solve
These are also the only public function of the class, and looks very reasonable to me.
What was exactly the idea of exposing less?
I think the issue here is that quite a number of implementation details are leaking into the header file where they don't belong because they are not part of the public interface. You're right that code using the header file doesn't have access to these by virtue of being private, but this does not make for a very readable header file, IMO.
In this case, SCCPSolver seems to carry quite a bit of state, so it might make sense to split it into two classes, one in the cpp file with all the implementation details, e.g. inheriting from InstVisitor, containing all the DenseMap state, and implementing the private member functions, and one class in the header file which can be a thin wrapper around the first class. Transform/Utils/ValueMapper.h takes a similar approach and might be a good example.
Does that make sense? @fhahn, is that roughly what you had in mind?
This implements the "pointer to implementation" pattern. I.e., we now have class SCCPSolver that is the interface class that holds no state and implementation, which is now contained in a new class SCCPInstVisitor.
pr49582-iterator-invalidation.ll | ||
---|---|---|
1 ↗ | (On Diff #336834) | Ah, ignore this file, this was incorrectly added to my diff and I will remove it. |
Thanks! This seems to be moving in the right direction. Now that SCCPInstVisitor is separate, its declaration can move into SCCPSolver.cpp entirely.
llvm/include/llvm/Transforms/Utils/SCCPSolver.h | ||
---|---|---|
40 | It should be possible to move this class to SCCPSolver.cpp now, with a few modifications to SCCPSolver (see below). | |
429 | This can be a void * or an SCCPInstVisitor * with a forward declaration of SCCPInstVisitor | |
435 | Implementations should go into SCCPSolver.cpp |
Thanks! SCCPSolver.h now only contains interface class SCCPSolver, and have moved SCCPInstVisitor and all implementations to the .cpp file.
The linter was right, I had somehow messed up the struct definition of AnalysisResultsForFn, but that's now fixed.
The other lint diagnostics, the style issues, are probably good to fix too, but will do that as a follow up.
Since this is mostly just moving pre-existing code, I think it's fine to address the style issues in a separate NFC commit. I believe all comments have been addressed, but please wait a day or two before committing in case there is anything else. LGTM.
llvm/lib/Transforms/Utils/SCCPSolver.cpp | ||
---|---|---|
14 | SCCPSolver.h should definitely be included first, to ensure that the includes in SCCPSolver.h are complete. |
Thanks for the update, this is along the lines I had in mind. This might be an incentive to further review what is exposed in SCCPSolver and why.
llvm/include/llvm/Transforms/Utils/SCCPSolver.h | ||
---|---|---|
46 | can this be just a unique_ptr? |
Thanks, I will look into the unique_ptr suggestion and then commit this today. I intend to follow up on this anyway since addressing the style issue would be good I think, and then look into this further. I am quite keen of getting this in now as carrying this large diff around is a bit of a pain.
It should be possible to move this class to SCCPSolver.cpp now, with a few modifications to SCCPSolver (see below).