[dev.ssa] cmd/compile: add GOSSAFUNC and GOSSAPKG
These temporary environment variables make it
possible to enable using SSA-generated code
for a particular function or package without
having to rebuild the compiler.
This makes it possible to start bulk testing
SSA generated code.
First, bump up the default stack size
(_StackMin in runtime/stack2.go) to something
large like 32768, because without stackmaps
we can't grow stacks.
Then run something like:
for pkg in `go list std`
do
GOGC=off GOSSAPKG=`basename $pkg` go test -a $pkg
done
When a test fails, you can re-run those tests,
selectively enabling one function after another,
until you find the one that is causing trouble.
Doing this right now yields some interesting results:
* There are several packages for which we generate
some code and whose tests pass. Yay!
* We can generate code for encoding/base64, but
tests there fail, so there's a bug to fix.
* Attempting to build the runtime yields a panic during codegen:
panic: interface conversion: ssa.Location is nil, not *ssa.LocalSlot
* The top unimplemented codegen items are (simplified):
59 genValue not implemented: REPMOVSB
18 genValue not implemented: REPSTOSQ
14 genValue not implemented: SUBQ
9 branch not implemented: If v -> b b. Control: XORQconst <bool> [1]
8 genValue not implemented: MOVQstoreidx8
4 branch not implemented: If v -> b b. Control: SETG <bool>
3 branch not implemented: If v -> b b. Control: SETLE <bool>
2 load flags not implemented: LoadReg8 <flags>
2 genValue not implemented: InvertFlags <flags>
1 store flags not implemented: StoreReg8 <flags>
1 branch not implemented: If v -> b b. Control: SETGE <bool>
Change-Id: Ib64809ac0c917e25bcae27829ae634c70d290c7f
Reviewed-on: https://go-review.googlesource.com/12547
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index d6c0bc7..6871fc4 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -6,6 +6,7 @@
import (
"fmt"
+ "os"
"strings"
"cmd/compile/internal/ssa"
@@ -146,7 +147,10 @@
if e.unimplemented {
return nil, false
}
- return s.f, usessa // TODO: return s.f, true once runtime support is in (gc maps, write barriers, etc.)
+
+ // TODO: enable codegen more broadly once the codegen stabilizes
+ // and runtime support is in (gc maps, write barriers, etc.)
+ return s.f, usessa || name == os.Getenv("GOSSAFUNC") || localpkg.Name == os.Getenv("GOSSAPKG")
}
type state struct {
@@ -1321,6 +1325,12 @@
return
}
+ e := f.Config.Frontend().(*ssaExport)
+ // We're about to emit a bunch of Progs.
+ // Since the only way to get here is to explicitly request it,
+ // just fail on unimplemented instead of trying to unwind our mess.
+ e.mustImplement = true
+
ptxt.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(Rnd(Curfn.Type.Argwid, int64(Widthptr))) // arg size
ptxt.To.Offset = f.FrameSize - 8 // TODO: arch-dependent
@@ -1688,7 +1698,7 @@
p.To.Type = obj.TYPE_REG
p.To.Reg = regnum(v)
default:
- v.Unimplementedf("value %s not implemented", v.LongString())
+ v.Unimplementedf("genValue not implemented: %s", v.LongString())
}
}
@@ -1810,7 +1820,7 @@
}
default:
- b.Unimplementedf("branch %s not implemented", b.LongString())
+ b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
}
return branches
}
@@ -1900,6 +1910,7 @@
type ssaExport struct {
log bool
unimplemented bool
+ mustImplement bool
}
// StringSym returns a symbol (a *Sym wrapped in an interface) which
@@ -1929,6 +1940,9 @@
// Unimplemented reports that the function cannot be compiled.
// It will be removed once SSA work is complete.
func (e *ssaExport) Unimplementedf(msg string, args ...interface{}) {
+ if e.mustImplement {
+ Fatal(msg, args...)
+ }
const alwaysLog = false // enable to calculate top unimplemented features
if !e.unimplemented && (e.log || alwaysLog) {
// first implementation failure, print explanation