1) We remove context sensitivity from API. The pointer analysis is
not sufficiently context-sensitive for the context information to
be worth exposing. (The actual analysis precision still benefits
from being context-sensitive, though.) Since all clients would
discard the context info, we now do that for them.
2) Make the graph doubly-linked. Edges are now shared by the Nodes
at both ends of the edge so it's possible to navigate more easily
(e.g. to the callers).
3) Graph and Node are now concrete, not interfaces.
Less code in every file!
LGTM=crawshaw
R=crawshaw
CC=golang-codereviews
https://golang.org/cl/66460043
Previously, each {Indirect,}Query would return a set of Pointers, one per context; now it returns (at most) one Pointer combining information from all contexts.
The old API was more faithful to the implementation concepts, but the analysis is not sufficiently context-sensitive that it makes sense: all existing clients simply throw away the context information---so now we do that for them.
(I may remove the context-sensitivity from the callgraph too, but I'll benchmark that first to see if it reduces precision.)
LGTM=crawshaw
R=crawshaw
CC=golang-codereviews
https://golang.org/cl/66130044
Observation: not all alias facts are interesting.
- A channel-peers query also cares about pointers of kind chan.
- An oracle "points-to" query on an expression of kind map
only cares about maps.
- We always care about func, interface and reflect.Value,
since they're needed for sound analysis of dynamic dispatch.
We needn't bother collecting alias information for
uninteresting pointers, and this massively reduces the number
of labels flowing in to the constraint system.
The only constraints that create new labels are addressOf
and offsetAddr; both are now selectively emitted by type.
We compute the set of type kinds to track, based on the
{Indirect,}Query types. (We could enable tracking at an
even finer grain if we want.)
This requires that we can see all the {Indirect,}Query
value types a priori, which is not the case for the PrintCalls
mechanism used in the tests, so I have rewritten the latter
to use {Indirect,}Query instead.
This reduces the solver-phase time for the entire standard
library and tests from >8m to <2m. Similar speedups are
obtained on small and medium-sized programs.
Details:
- shouldTrack inspects the flattened form of a type to see if
it contains fields we must track. It memoizes the result.
- added precondition checks to (*Config).Add{,Indirect}Query.
- added (*ssa.Program).LookupMethod convenience method.
- added Example of how to use the Query mechanism.
- removed code made dead by a recent invariant:
the only pointerlike Const value is nil.
- don't generate constraints for any functions in "reflect".
(we had forgotten to skip synthetic wrappers too).
- write PTA warnings to the log.
- add annotations for more intrinsics.
LGTM=gri, crawshaw
R=crawshaw, gri
CC=golang-codereviews
https://golang.org/cl/62540043
Was: Now:
call.Graph callgraph.Graph
call.GraphNode callgraph.Node
call.Edge callgraph.Edge
Though call.Graph was cute, the original naming was a mistake:
'call' is too useful a var name to waste on a package.
R=gri, crawshaw
CC=golang-codereviews
https://golang.org/cl/53190043