Blocks dominated by "if false" should be retained in the
initial SSA form so they remain visible to subsequent source
code analysis tools.
In any case, true compilers already need a stronger version of
this optimization so they can simplify CFGs such as this:
const x, y = ...
switch x {case y:...}
where a branch is constant but the comparison of constants
does not occur within an expression.
LGTM=gri
R=gri
CC=golang-codereviews, pcc
https://golang.org/cl/101250043
The SSA builder shouldn't be in the business of
interprocedural optimization, especially in the presence of
concurrency.
This causes the instruction count to increase by 0.03%.
LGTM=gri
R=gri, pcc
CC=golang-codereviews
https://golang.org/cl/105020045
It was making the unsound assumption that cgn==nil => v is one
of {Global,Function,Const,Capture} to avoid checking v's type,
which is what it now does. This caused more expensive
constraints to be generated, which is suboptimal though not
wrong exactly.
In one benchmark, this change reduces the number of complex
constraints by about 23% of loads and 53% of stores, and
increases the number of (simple) copy constraints by about 5%.
LGTM=crawshaw
R=crawshaw
CC=golang-codereviews
https://golang.org/cl/106940043
Files that import "C" are not valid Go source files and
require preprocessing. Until now, the loader has simply
hard-coded CGO_ENABLED=0 (in effect) which causes go/build to
use build tags select pure Go implementations where they exist
(e.g. in $GOROOT). Where they don't (e.g. arbitrary user
code) this leads to masses of spurious type errors.
(Reported by Guillaume Charmes, private correspondence.)
This change causes the loader to invoke the cgo preprocessor
on such files and to load the preprocessed files instead,
using the original names. This means that the syntax offset
position information is garbage, although thanks to //line
directives, the line numbers at least should be good.
See comment in cgo.go for details.
This CL changes the loader's default behaviour and may make it slower.
CGO_ENABLED=0 enables the old behaviour.
Tested via stdlib_test, which now loads all standard packages
using cgo, and also exercises CGO_ENABLED=0 for "net" and "os/user".
LGTM=gri
R=gri, rsc
CC=golang-codereviews, guillaume.charmes
https://golang.org/cl/86140043
Also:
- extend Parent() to all Values and add to interface:
(Builtin/Const/Global => nil; Function => Enclosing)
- hide Function.Enclosing since it's now redundant wrt Parent()
- make (*Function).String robust for synthetics without pkg object
LGTM=gri
R=gri
CC=golang-codereviews, khr
https://golang.org/cl/87580044
This optimization reduces solve time (typically >90% of the
total) by about 78% when analysing real programs. It also
makes the solver 100% deterministic since all iterations are
ordered.
Also:
- remove unnecessary nodeid parameter to solve() method.
- don't add a fieldInfo for singleton tuples (cosmetic fix).
- inline+simplify "worklist" type.
- replace "constraintset" type by a slice.
LGTM=crawshaw
R=crawshaw
CC=golang-codereviews
https://golang.org/cl/95240043
Until now, the same Function was used to represent a method
(T)func() and the "method expression" function func(T) formed
from it. So the SSA code for this:
var buf bytes.Buffer
f := Buffer.Bytes
f(buf)
buf.Bytes()
would involve an implicit cast (ChangeType) on line 2.
However, compilers based on go/ssa may want to use different
calling conventions for them, like gccgo does (see issue
7839). This change decouples them by using an anonymous
function called a "thunk", rather like this:
f := func(r *bytes.Buffer) []byte { return r.Bytes() }
Thunks are similar to method wrappers; both are created by
makeWrapper.
"Interface method wrappers" were a special case of thunks for
direct calls (no indirection/fields) of interface methods.
They are now subsumed by thunks and have been deleted. Now
that only the needed thunks are built, we don't need to
populate the concrete method sets of interface types at all,
so (*Program).Method and LookupMethod return nil for them.
This results in a slight reduction in function count (>1%) and
instruction count (<<1%).
Details:
go/ssa:
- API: ChangeType no longer supports func/method conversions.
- API: (*Program).FuncValue now returns nil for abstract
(interface) methods.
- API: (*Function).RelString simplified.
"$bound" is now a suffix not a prefix, and the receiver
type is rendered package-relative.
- API: Function.Object is now defined for all wrappers too.
- API: (*Program).Method and LookupMethod return nil for
abstract methods.
- emitConv no longer permits (non-identical)
Signature->Signature conversions. Added assertion.
- add and use isInterface helper
- sanity: we check packages after Build, not Create, otherwise
cross-package refs might fail.
go/pointer:
- update tests for new function strings.
- pointer_test: don't add non-pointerlike probes to analysis.
(The error was checked, but too late, causing a panic.)
- fixed a minor bug: if a test probe print(x) was the sole
reference to x, no nodes were generated for x.
- (reflect.Type).MethodByName: updated due to ssa API changes.
Also, fixed incorrect testdata/funcreflect.go expectation
for MethodByName on interfaces.
oracle:
- fix for new FuncValue semantics.
- a "pointsto" query on an I.f thunk now returns an error.
Fixesgolang/go#7839
LGTM=gri
R=gri
CC=golang-codereviews, pcc
https://golang.org/cl/93780044
- Replaced check.initDependencies with check.initOrder;
this is the only semantic change, it affects only the
value of Info.InitOrder.
- Added additional init order test cases and adjusted
existing tests.
- Moved orderedSetObjects from resolver.go to ordering.go.
Fixesgolang/go#7964.
LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/91450043
Programs such as this cause the PtrTo solver to attempt to
enumerate an infinite set of types {T, *T, ..., *******T, etc}.
t := reflect.TypeOf(T{})
for {
t = reflect.PtrTo(t)
}
The fix is to bound the depth of reflectively created types at
about 4 map/chan/slice/pointer constructors.
+ test.
LGTM=gri
R=gri
CC=crawshaw, golang-codereviews
https://golang.org/cl/102030044
go/types doesn't correctly round the largest possible
float32 literal values and fails. Instead of relying
on Rat.Float64 and float32 conversion, we need a
Rat.Float32 implementation with correct rounding.
LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/96540045
Very long instructions caused the printf width spec to go
negative, which causes right-padding, often several lines'
worth.
Also: print the basic block comment once on the RHS. It's too
verbose to print it each time we mention the block.
LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/97490046
The previous implementation would cause the graph to contain
many duplicate edges resulting in very large cross products,
so that for some inputs (and random map iteration orders) the
running time of DeleteSyntheticNodes was many minutes---more
than the pointer analysis!
Duplicate edges can arise from an interface call that
dispatches to several different wrapper functions each
wrapping the same declared method.
For example, in the callgraph for go/types, a call to
Object.Pos() dispatches to the synthetic functions (*Type).Pos
and (*Var).Pos, each of which wrap (*object).Pos(). After
DeleteSyntheticNodes, Object.Pos() appeared to call
(*object).Pos() twice.
This change builds the set of all edges and avoids adding
edges already in the set.
Also, document findings.
LGTM=crawshaw
R=crawshaw
CC=golang-codereviews
https://golang.org/cl/96100043
Method expressions T.f are reported as having type (T)func(T),
i.e. T appears twice, as a receiver and a regular parameter.
LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/96780044
During block optimization, degenerate conditional logic such
as "false && x" may result in single-predecessor blocks
containing φ-nodes. (Ideally such φ-nodes would be replaced
by their sole operand, but that requires Referrers information
which isn't computed until later.) It is obviously not safe
to fuse such blocks, so now we don't.
Fixesgolang/go#7840
LGTM=gri
R=gri
CC=golang-codereviews, pcc
https://golang.org/cl/90620043
GccgoInstallation.InitFromDriver currently parses
the output of gccgo -### to get the gcc version,
target triple, and library paths. At least with
Ubuntu's stock libgo5 package, the search path for
.gox files derived from the version is incorrect.
gccgo uses the DEFAULT_TARGET_VERSION macro when
constructing the search path; this value can be
retrieved from gccgo via the "-dumpversion" flag.
Fixesgolang/go#7772.
LGTM=iant, gri
R=golang-codereviews, iant, gri
CC=golang-codereviews
https://golang.org/cl/88150043
Otherwise on Windows the enumerated package "net\\http" will
be distinct from the imported package "net/http" leading to
strange errors. (A similar bug was fixed in go/ssa/stdlib_test.go.)
Fixesgolang/go#7189
LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/86170043
Side-effect: Because interfaces are now type-checked in reverse order,
cycle errors in interface declarations appear at the "end" rather than
at the "beginning" of the cycle in the source code. This is harmless.
Eventually we may want to do dependency order determination and thus
cycle detection for all types before fully type-checking them, which
might simplify some code and also produce consistently positioned cycle
errors again.
Fixesgolang/go#7158.
LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/83640043