1
0
mirror of https://github.com/golang/go synced 2024-10-06 00:31:23 -06:00

[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>
This commit is contained in:
Josh Bleecher Snyder 2015-07-22 13:13:53 -07:00
parent 8c954d5780
commit d298209b1c
2 changed files with 19 additions and 3 deletions

View File

@ -6,6 +6,7 @@ package gc
import ( import (
"fmt" "fmt"
"os"
"strings" "strings"
"cmd/compile/internal/ssa" "cmd/compile/internal/ssa"
@ -146,7 +147,10 @@ func buildssa(fn *Node) (ssafn *ssa.Func, usessa bool) {
if e.unimplemented { if e.unimplemented {
return nil, false 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 { type state struct {
@ -1321,6 +1325,12 @@ func genssa(f *ssa.Func, ptxt *obj.Prog, gcargs, gclocals *Sym) {
return 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.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(Rnd(Curfn.Type.Argwid, int64(Widthptr))) // arg size ptxt.To.Val = int32(Rnd(Curfn.Type.Argwid, int64(Widthptr))) // arg size
ptxt.To.Offset = f.FrameSize - 8 // TODO: arch-dependent ptxt.To.Offset = f.FrameSize - 8 // TODO: arch-dependent
@ -1688,7 +1698,7 @@ func genValue(v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = regnum(v) p.To.Reg = regnum(v)
default: default:
v.Unimplementedf("value %s not implemented", v.LongString()) v.Unimplementedf("genValue not implemented: %s", v.LongString())
} }
} }
@ -1810,7 +1820,7 @@ func genBlock(b, next *ssa.Block, branches []branch) []branch {
} }
default: default:
b.Unimplementedf("branch %s not implemented", b.LongString()) b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
} }
return branches return branches
} }
@ -1900,6 +1910,7 @@ func localOffset(v *ssa.Value) int64 {
type ssaExport struct { type ssaExport struct {
log bool log bool
unimplemented bool unimplemented bool
mustImplement bool
} }
// StringSym returns a symbol (a *Sym wrapped in an interface) which // StringSym returns a symbol (a *Sym wrapped in an interface) which
@ -1929,6 +1940,9 @@ func (e *ssaExport) Fatalf(msg string, args ...interface{}) {
// Unimplemented reports that the function cannot be compiled. // Unimplemented reports that the function cannot be compiled.
// It will be removed once SSA work is complete. // It will be removed once SSA work is complete.
func (e *ssaExport) Unimplementedf(msg string, args ...interface{}) { func (e *ssaExport) Unimplementedf(msg string, args ...interface{}) {
if e.mustImplement {
Fatal(msg, args...)
}
const alwaysLog = false // enable to calculate top unimplemented features const alwaysLog = false // enable to calculate top unimplemented features
if !e.unimplemented && (e.log || alwaysLog) { if !e.unimplemented && (e.log || alwaysLog) {
// first implementation failure, print explanation // first implementation failure, print explanation

View File

@ -60,6 +60,8 @@ func NewConfig(arch string, fe Frontend) *Config {
return c return c
} }
func (c *Config) Frontend() Frontend { return c.fe }
// NewFunc returns a new, empty function object // NewFunc returns a new, empty function object
func (c *Config) NewFunc() *Func { func (c *Config) NewFunc() *Func {
// TODO(khr): should this function take name, type, etc. as arguments? // TODO(khr): should this function take name, type, etc. as arguments?