This is an archive of the discontinued LLVM Phabricator instance.

SCCP: Refactor SCCPSolver
ClosedPublic

Authored by SjoerdMeijer on Dec 23 2020, 7:05 AM.

Details

Summary

Move SCCPSolver class to header file so that it can be used by other passes / transformations.

Diff Detail

Event Timeline

mivnay created this revision.Dec 23 2020, 7:05 AM
mivnay requested review of this revision.Dec 23 2020, 7:05 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 23 2020, 7:05 AM
fhahn added a subscriber: fhahn.Dec 23 2020, 7:45 AM

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 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.

New file and header?

dmgreen edited reviewers, added: efriedma, fhahn, nikic; removed: eli.friedman.Dec 23 2020, 9:44 AM

@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.

@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.

Sorry for the delayed response. Please refer to the patch D93838 for full context.

mivnay updated this revision to Diff 320744.Feb 2 2021, 4:09 AM
mivnay added a reviewer: sanwou01.

Move SCCPSolver to new header and .cpp file.

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

mivnay updated this revision to Diff 321653.Feb 4 2021, 9:08 PM
mivnay marked an inline comment as done.Feb 4 2021, 9:17 PM
mivnay added inline comments.
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.

fhahn added a comment.Feb 11 2021, 7:58 AM

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?

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

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?

IMO we should nail down the interface first, rather than starting with exposing/moving everything, to avoid a lot of unnecessary churn.

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?

SjoerdMeijer commandeered this revision.Mar 31 2021, 3:48 AM
SjoerdMeijer edited reviewers, added: mivnay; removed: SjoerdMeijer.

Taking over this work.

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?

Ah okay, thanks, got it! Makes perfect sense to me.
I will start looking into that.

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.

SjoerdMeijer added inline comments.Apr 12 2021, 8:09 AM
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

SjoerdMeijer updated this revision to Diff 336908.EditedApr 12 2021, 11:14 AM

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.

And a little rebase.

sanwou01 accepted this revision.Apr 13 2021, 6:34 AM

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.

This revision is now accepted and ready to land.Apr 13 2021, 6:34 AM

Thanks for reviewing!

fhahn accepted this revision.Apr 14 2021, 6:35 AM

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.

This revision was landed with ongoing or failed builds.Apr 14 2021, 6:59 AM
This revision was automatically updated to reflect the committed changes.