- Add missing import.
- platform-specific files syswrite() wrapper presents
standard API to syscall.Write, even on Windows where
first arg is a Handle.
Fixesgolang/go#7100
R=gri, minux.ma, alex.brainman
CC=golang-codereviews
https://golang.org/cl/52250043
go/types no longer reports a constant value for a slice,
e.g. []byte("foo").
ssa.Const no longer support slice constants, only
bool/string/numeric and nil.
emitConv emits a Convert instruction for string->[]byte
conversions.
Added regression test for bug 6949.
R=gri
CC=golang-codereviews
https://golang.org/cl/50590043
Tested: by enabling debug info globally in stdlib_test,
the existing sanity checks catch it.
R=gri
CC=golang-codereviews
https://golang.org/cl/50570043
Packages were not being created for all types.Packages,
specifically, indirectly imported packages were missing.
(*Program).CreatePackages now iterates over the type-checker's
package map too.
Also: removed all concurrency from importer. I think it was
incorrect (and hard to fix).
Also: change LoadInitialPackages so that all named packages
are loaded from source. This happens regardless of whether
GCImporter is used to satisfy imports.
Details:
- importer.Config.SourceImports flag determines whether to
load all packages from *.go source.
(Before, this was indicated by Config.Build != nil.)
- importer.Config.Build field effectively defaults to
&go/build.Default. A zero importer.Config is now usable.
- importer.Importer.Config field is now exported.
- LoadPackage renamed to ImportPackage since the resulting
packages may come from GCImporter (and be incomplete).
- doImport and ImportPackage fused.
Fixesgolang/go#7028
R=gri, axwalk
CC=golang-codereviews
https://golang.org/cl/48770043
Also report an error for "cross-interpretation": not supported
due to the interpreter's assumption that host and target
{int,uint,uintptr} are the same. (Too tedious and messy to fix.)
Tested manually:
% cat d.go
package main
const m = ^uintptr(0)
const w = m>>8&1 + m>>16&1 + m>>32&1
func main() { println(m, w) }
% ./ssadump -build=P -run d.go
package main:
const m m = 18446744073709551615:uintptr
const w w = 3:uintptr
18446744073709551615 3
% GOARCH=386 ./ssadump -build=P -run d.go
package main:
const m m = 4294967295:uintptr
const w w = 2:uintptr
Error: Cross-interpretation is not yet supported (target has GOARCH 386, interpreter has amd64).
Fixesgolang/go#7080
R=gri
CC=golang-codereviews
https://golang.org/cl/49070043
(*CallCommon).Signature() now returns non-nil even for
built-ins. Builtins are now created with specialized types for
each use. Added sanity-check.
CallCommon.HasEllipsis field eliminated. It was an incorrect
memoization of Signature().IsVariadic() used only for
printing.
Also: introduce and use newTypeVar utility.
R=gri
CC=golang-codereviews
https://golang.org/cl/46880044
Although such a control-flow path is impossible by
construction, we must avoid no-arg returns (even if
unreachable) in non-void functions.
Tested by adding a sanity-check that ssa.Return has the correct arity.
Also: added ssautil.Switches() test.
Fixesgolang/go#7702
R=gri, axwalk
CC=golang-codereviews
https://golang.org/cl/46520043
New APIs:
(*BasicBlock).{Idom,Dominees,Dominates}
(*Function).DomPreorder
Messy but systematic refactoring of domNode:
- renamed "domInfo".
- embedded directly in BasicBlock, not as pointer. Block field removed.
- Level field removed; was unused.
- Working state of LT algorithm now in its own type.
{semi,parent,ancestor} fields moved into it.
- remaining fields made private; accessors added.
- use 32-bit ints for pre/postorder numbers.
- allocate LT working space (5 copies of fn.Blocks) contiguously.
dom.go is simpler but somewhat more verbose.
Also:
- we always build the domtree now---yet memory usage is down 5%.
- number the Recover block too.
- add sanity check for DomPreorder.
R=gri
CC=golang-dev
https://golang.org/cl/37230043
Cause: emitExtract requires a type for each component of the
receive tuple; blank supplies no such type.
Solution: remove type parameter for emitExtract as it is no
longer needed: since rev b75cc03b4a56 it is always identical
to the tuple.Type().At(index).
+ tests.
Fixesgolang/go#6806.
R=gri, gri
CC=axwalk, golang-dev
https://golang.org/cl/30410043
This removes about 5% of φ-nodes in one large program
and eliminates many zero-value constants.
(This does cause some Idents to no longer map to an ssa.Value.
This is observable in the oracle, whose tests are here updated.)
R=gri, gri
CC=golang-dev
https://golang.org/cl/26980043
Details:
- use relative (non-qualified) names in more places
- Member interface now has Package(), RelString() methods.
- (*Function).DumpTo: add "# Package: " header.
- Added sanity checks for String functions.
R=gri, gri
CC=golang-dev
https://golang.org/cl/26380043
The previous code introduced spurious loop-carried
dependencies for variables local to a loop body (for example).
The SSA renaming pass now treats an Alloc instruction like a
Store of the zero value.
Also:
- added regression test
- improved log messages
- made the Store/Load/Alloc cases look more similar.
R=gri, gri
CC=golang-dev
https://golang.org/cl/26750043
Also, only examine functions defined in *_test.go files.
Added tests for empty and nonempty behaviour of CreateTestMainPackage.
(Required some surgery to interp_test.)
R=gri, gri
CC=golang-dev
https://golang.org/cl/25570044
Added sanity check to ensure Operands/Referrers are complete and dual.
Also: unexport Instruction.setBlock (=> no longer user-implementable).
R=gri
CC=golang-dev
https://golang.org/cl/22150043
Added test for []*map composite literals containing nested
literal subelements. This required implementing
(reflect.Value).Map{Keys,Index} in ssa/interp.
Plus two minor fixes in ssa/interp.
R=gri
CC=golang-dev
https://golang.org/cl/20470043
A DebugRef associates a source expression E with an ssa.Value
V, but until now did not record whether V was the value or the
address of E. So, we would guess from the "pointerness" of
the Value, leading to confusion in some cases, e.g.
type N *N
var n N
n = &n // lvalue and rvalue are both pointers
Now we explicitly record 'IsAddress bool' in DebugRef, and
plumb this everywhere: through (*Function).ValueForExpr and
(*Program).VarValue, all the way to forming the pointer
analysis query.
Also:
- VarValue now treats each reference to a global distinctly,
just like it does for other vars. So:
var g int
func f() {
g = 1 // VarValue(g) == Const(1:int), !isAddress
print(g) // VarValue(g) == Global(g), isAddress
}
- DebugRefs are not emitted for references to predeclared
identifiers (nil, built-in).
- DebugRefs no longer prevent lifting of an Alloc var into a
register; now we update or discard the debug info.
- TestValueForExpr: improve coverage of ssa.EnclosingFunction
by putting expectations in methods and init funcs, not just
normal funcs.
- oracle: fix golden file broken by recent
(*types.Var).IsField change.
R=gri
CC=golang-dev
https://golang.org/cl/16610045
This allows us to run/analyze multiple tests.
Also it causes the production code packages to be properly initialized.
Also:
- cmd/ssadump: improved usage message (add example;
incorporate LoadInitialPackages usage; explain how -run
finds main).
- pointer, oracle, ssa/interp: use CreateTestMainPackage.
- ssa/builder.go: remove 'rundefers' instruction from package init,
which no longer uses 'defer'.
R=gri
CC=golang-dev
https://golang.org/cl/15920047
Motivation:
Previously, we assumed that the set of types for which a
complete method set (containing all synthesized wrapper
functions) is required at runtime was the set of types
used as operands to some *ssa.MakeInterface instruction.
In fact, this is an underapproximation because types can
be derived from other ones via reflection, and some of
these may need methods. The reflect.Type API allows *T to
be derived from T, and these may have different method
sets. Reflection also allows almost any subcomponent of a
type to be accessed (with one exception: given T, defined
'type T struct{S}', you can reach S but not struct{S}).
As a result, the pointer analysis was unable to generate
all necessary constraints before running the solver,
causing a crash when reflection derives types whose
methods are unavailable. (A similar problem would afflict
an ahead-of-time compiler based on ssa. The ssa/interp
interpreter was immune only because it does not require
all wrapper methods to be created before execution
begins.)
Description:
This change causes the SSA builder to record, for each
package, the set of all types with non-empty method sets that
are referenced within that package. This set is accessed via
Packages.TypesWithMethodSets(). Program.TypesWithMethodSets()
returns its union across all packages.
The set of references that matter are:
- types of operands to some MakeInterface instruction (as before)
- types of all exported package members
- all subcomponents of the above, recursively.
This is a conservative approximation to the set of types
whose methods may be called dynamically.
We define the owning package of a type as follows:
- the owner of a named type is the package in which it is defined;
- the owner of a pointer-to-named type is the owner of that named type;
- the owner of all other types is nil.
A package must include the method sets for all types that it
owns, and all subcomponents of that type that are not owned by
another package, recursively. Types with an owner appear in
exactly one package; types with no owner (such as struct{T})
may appear within multiple packages.
(A typical Go compiler would emit multiple copies of these
methods as weak symbols; a typical linker would eliminate
duplicates.)
Also:
- go/types/typemap: implement hash function for *Tuple.
- pointer: generate nodes/constraints for all of
ssa.Program.TypesWithMethodSets().
Add rtti.go regression test.
- Add API test of Package.TypesWithMethodSets().
- Set Function.Pkg to nil (again) for wrapper functions,
since these may be shared by many packages.
- Remove a redundant logging statement.
- Document that ssa CREATE phase is in fact sequential.
Fixesgolang/go#6605
R=gri
CC=golang-dev
https://golang.org/cl/14920056
A function such as this:
func one() (x int) {
defer func() { recover() }()
x = 1
panic("return")
}
that combines named return parameters (NRPs) with deferred calls
that call recover, may return non-zero values despite the
fact it doesn't even contain a return statement. (!)
This requires a change to the SSA API: all functions'
control-flow graphs now have a second entry point, called
Recover, which is the block at which control flow resumes
after a recovered panic. The Recover block simply loads the
NRPs and returns them.
As an optimization, most functions don't need a Recover block,
so it is omitted. In fact it is only needed for functions that
have NRPs and defer a call to another function that _may_ call
recover.
Dataflow analysis of SSA now requires extra work, since every
may-panic instruction has an implicit control-flow edge to
the Recover block. The only dataflow analysis so far implemented
is SSA renaming, for which we make the following simplifying
assumption: the Recover block only loads the NRPs and returns.
This means we don't really need to analyze it, we can just
skip the "lifting" of such NRPs. We also special-case the Recover
block in the dominance computation.
Rejected alternative approaches:
- Specifying a Recover block for every defer instruction (like a
traditional exception handler).
This seemed like excessive generality, since Go programs
only need the same degenerate form of Recover block.
- Adding an instruction to set the Recover block immediately
after the named return values are set up, so that dominance
can be computed without special-casing.
This didn't seem worth the effort.
Interpreter:
- This CL completely reimplements the panic/recover/
defer logic in the interpreter. It's clearer and simpler
and closer to the model in the spec.
- Some runtime panic messages have been changed to be closer
to gc's, since tests depend on it.
- The interpreter now requires that the runtime.runtimeError
type be part of the SSA program. This requires that clients
import this package prior to invoking the interpreter.
This in turn requires (Importer).ImportPackage(path string),
which this CL adds.
- All $GOROOT/test/recover{,1,2,3}.go tests are now passing.
NB, the bug described in coverage.go (defer/recover in a concatenated
init function) remains. Will be fixed in a follow-up.
Fixesgolang/go#6381
R=gri
CC=crawshaw, golang-dev
https://golang.org/cl/13844043
Before, we would concatenate all the init() blocks together,
resulting in incorrect treatment of a recovered panic in one
init block: the implicit return would cause the subsequent ones
to be skipped.
The result is simpler, and closer to what gc does.
The additional functions are visible in the call graph,
so some tests required updating.
R=gri
CC=crawshaw, golang-dev
https://golang.org/cl/14671044