[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