mirror of https://github.com/golang/go.git
cmd/compile: make ssa compilation unconditional
Rip out the code that allows SSA to be used conditionally. No longer exists: ssa=0 flag GOSSAHASH GOSSAPKG SSATEST GOSSAFUNC now only controls the printing of the IR/html. Still need to rip out all of the old backend. It should no longer be callable after this CL. Update #16357 Change-Id: Ib30cc18fba6ca52232c41689ba610b0a94aa74f5 Reviewed-on: https://go-review.googlesource.com/29155 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
eed061f89c
commit
167e381f40
|
|
@ -684,7 +684,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
p.To.Offset = off
|
||||
case ssa.OpAMD64MOVOconst:
|
||||
if v.AuxInt != 0 {
|
||||
v.Unimplementedf("MOVOconst can only do constant=0")
|
||||
v.Fatalf("MOVOconst can only do constant=0")
|
||||
}
|
||||
r := gc.SSARegNum(v)
|
||||
opregreg(x86.AXORPS, r, r)
|
||||
|
|
@ -705,7 +705,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
}
|
||||
case ssa.OpLoadReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(loadByType(v.Type))
|
||||
|
|
@ -725,7 +725,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
|
||||
case ssa.OpStoreReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("store flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(storeByType(v.Type))
|
||||
|
|
@ -1031,7 +1031,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
p.To.Reg = gc.SSARegNum(v.Args[0])
|
||||
gc.AddAux(&p.To, v)
|
||||
default:
|
||||
v.Unimplementedf("genValue not implemented: %s", v.LongString())
|
||||
v.Fatalf("genValue not implemented: %s", v.LongString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1145,6 +1145,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||
}
|
||||
|
||||
default:
|
||||
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
// nothing to do
|
||||
case ssa.OpLoadReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(loadByType(v.Type))
|
||||
|
|
@ -222,7 +222,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
gc.CheckLoweredPhi(v)
|
||||
case ssa.OpStoreReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("store flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(storeByType(v.Type))
|
||||
|
|
@ -958,7 +958,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
case ssa.OpARMInvertFlags:
|
||||
v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
|
||||
default:
|
||||
v.Unimplementedf("genValue not implemented: %s", v.LongString())
|
||||
v.Fatalf("genValue not implemented: %s", v.LongString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1056,6 +1056,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||
}
|
||||
|
||||
default:
|
||||
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
// nothing to do
|
||||
case ssa.OpLoadReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(loadByType(v.Type))
|
||||
|
|
@ -227,7 +227,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
gc.CheckLoweredPhi(v)
|
||||
case ssa.OpStoreReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("store flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(storeByType(v.Type))
|
||||
|
|
@ -884,7 +884,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
case ssa.OpARM64InvertFlags:
|
||||
v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
|
||||
default:
|
||||
v.Unimplementedf("genValue not implemented: %s", v.LongString())
|
||||
v.Fatalf("genValue not implemented: %s", v.LongString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -982,6 +982,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||
}
|
||||
|
||||
default:
|
||||
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,6 @@ func Main() {
|
|||
flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to `file`")
|
||||
flag.StringVar(&memprofile, "memprofile", "", "write memory profile to `file`")
|
||||
flag.Int64Var(&memprofilerate, "memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
|
||||
flag.BoolVar(&ssaEnabled, "ssa", true, "use SSA backend to generate code")
|
||||
flag.StringVar(&benchfile, "bench", "", "append benchmark times to `file`")
|
||||
obj.Flagparse(usage)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
package gc
|
||||
|
||||
import (
|
||||
"cmd/compile/internal/ssa"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/sys"
|
||||
"fmt"
|
||||
|
|
@ -400,9 +399,9 @@ func compile(fn *Node) {
|
|||
}
|
||||
|
||||
// Build an SSA backend function.
|
||||
var ssafn *ssa.Func
|
||||
if shouldssa(Curfn) {
|
||||
ssafn = buildssa(Curfn)
|
||||
ssafn := buildssa(Curfn)
|
||||
if nerrors != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
continpc = nil
|
||||
|
|
@ -478,12 +477,8 @@ func compile(fn *Node) {
|
|||
}
|
||||
}
|
||||
|
||||
if ssafn != nil {
|
||||
genssa(ssafn, ptxt, gcargs, gclocals)
|
||||
ssafn.Free()
|
||||
} else {
|
||||
genlegacy(ptxt, gcargs, gclocals)
|
||||
}
|
||||
genssa(ssafn, ptxt, gcargs, gclocals)
|
||||
ssafn.Free()
|
||||
}
|
||||
|
||||
type symByName []*Sym
|
||||
|
|
@ -491,70 +486,3 @@ type symByName []*Sym
|
|||
func (a symByName) Len() int { return len(a) }
|
||||
func (a symByName) Less(i, j int) bool { return a[i].Name < a[j].Name }
|
||||
func (a symByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
// genlegacy compiles Curfn using the legacy non-SSA code generator.
|
||||
func genlegacy(ptxt *obj.Prog, gcargs, gclocals *Sym) {
|
||||
Genlist(Curfn.Func.Enter)
|
||||
Genlist(Curfn.Nbody)
|
||||
gclean()
|
||||
checklabels()
|
||||
if nerrors != 0 {
|
||||
return
|
||||
}
|
||||
if Curfn.Func.Endlineno != 0 {
|
||||
lineno = Curfn.Func.Endlineno
|
||||
}
|
||||
|
||||
if Curfn.Type.Results().NumFields() != 0 {
|
||||
Ginscall(throwreturn, 0)
|
||||
}
|
||||
|
||||
ginit()
|
||||
|
||||
// TODO: Determine when the final cgen_ret can be omitted. Perhaps always?
|
||||
cgen_ret(nil)
|
||||
|
||||
if hasdefer {
|
||||
// deferreturn pretends to have one uintptr argument.
|
||||
// Reserve space for it so stack scanner is happy.
|
||||
if Maxarg < int64(Widthptr) {
|
||||
Maxarg = int64(Widthptr)
|
||||
}
|
||||
}
|
||||
|
||||
gclean()
|
||||
if nerrors != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
Pc.As = obj.ARET // overwrite AEND
|
||||
Pc.Lineno = lineno
|
||||
|
||||
fixjmp(ptxt)
|
||||
if Debug['N'] == 0 || Debug['R'] != 0 || Debug['P'] != 0 {
|
||||
regopt(ptxt)
|
||||
nilopt(ptxt)
|
||||
}
|
||||
|
||||
Thearch.Expandchecks(ptxt)
|
||||
|
||||
allocauto(ptxt)
|
||||
|
||||
setlineno(Curfn)
|
||||
if Stksize+Maxarg > 1<<31 {
|
||||
Yyerror("stack frame too large (>2GB)")
|
||||
return
|
||||
}
|
||||
|
||||
// Emit garbage collection symbols.
|
||||
liveness(Curfn, ptxt, gcargs, gclocals)
|
||||
|
||||
Thearch.Defframe(ptxt)
|
||||
|
||||
if Debug['f'] != 0 {
|
||||
frame(0)
|
||||
}
|
||||
|
||||
// Remove leftover instrumentation from the instruction stream.
|
||||
removevardef(ptxt)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,10 @@ import (
|
|||
"cmd/internal/sys"
|
||||
)
|
||||
|
||||
var ssaEnabled = true
|
||||
|
||||
var ssaConfig *ssa.Config
|
||||
var ssaExp ssaExport
|
||||
|
||||
func initssa() *ssa.Config {
|
||||
ssaExp.unimplemented = false
|
||||
ssaExp.mustImplement = true
|
||||
if ssaConfig == nil {
|
||||
ssaConfig = ssa.NewConfig(Thearch.LinkArch.Name, &ssaExp, Ctxt, Debug['N'] == 0)
|
||||
if Thearch.LinkArch.Name == "386" {
|
||||
|
|
@ -33,61 +29,6 @@ func initssa() *ssa.Config {
|
|||
return ssaConfig
|
||||
}
|
||||
|
||||
func shouldssa(fn *Node) bool {
|
||||
switch Thearch.LinkArch.Name {
|
||||
default:
|
||||
// Only available for testing.
|
||||
if os.Getenv("SSATEST") == "" {
|
||||
return false
|
||||
}
|
||||
case "amd64", "amd64p32", "arm", "386", "arm64", "ppc64", "ppc64le", "mips64", "mips64le", "s390x":
|
||||
// Generally available.
|
||||
}
|
||||
if !ssaEnabled {
|
||||
return false
|
||||
}
|
||||
|
||||
// Environment variable control of SSA CG
|
||||
// 1. IF GOSSAFUNC == current function name THEN
|
||||
// compile this function with SSA and log output to ssa.html
|
||||
|
||||
// 2. IF GOSSAHASH == "" THEN
|
||||
// compile this function (and everything else) with SSA
|
||||
|
||||
// 3. IF GOSSAHASH == "n" or "N"
|
||||
// IF GOSSAPKG == current package name THEN
|
||||
// compile this function (and everything in this package) with SSA
|
||||
// ELSE
|
||||
// use the old back end for this function.
|
||||
// This is for compatibility with existing test harness and should go away.
|
||||
|
||||
// 4. IF GOSSAHASH is a suffix of the binary-rendered SHA1 hash of the function name THEN
|
||||
// compile this function with SSA
|
||||
// ELSE
|
||||
// compile this function with the old back end.
|
||||
|
||||
// Plan is for 3 to be removed when the tests are revised.
|
||||
// SSA is now default, and is disabled by setting
|
||||
// GOSSAHASH to n or N, or selectively with strings of
|
||||
// 0 and 1.
|
||||
|
||||
name := fn.Func.Nname.Sym.Name
|
||||
|
||||
funcname := os.Getenv("GOSSAFUNC")
|
||||
if funcname != "" {
|
||||
// If GOSSAFUNC is set, compile only that function.
|
||||
return name == funcname
|
||||
}
|
||||
|
||||
pkg := os.Getenv("GOSSAPKG")
|
||||
if pkg != "" {
|
||||
// If GOSSAPKG is set, compile only that package.
|
||||
return localpkg.Name == pkg
|
||||
}
|
||||
|
||||
return initssa().DebugHashMatch("GOSSAHASH", name)
|
||||
}
|
||||
|
||||
// buildssa builds an SSA function.
|
||||
func buildssa(fn *Node) *ssa.Func {
|
||||
name := fn.Func.Nname.Sym.Name
|
||||
|
|
@ -176,7 +117,7 @@ func buildssa(fn *Node) *ssa.Func {
|
|||
case PFUNC:
|
||||
// local function - already handled by frontend
|
||||
default:
|
||||
s.Unimplementedf("local variable with class %s unimplemented", classnames[n.Class])
|
||||
s.Fatalf("local variable with class %s unimplemented", classnames[n.Class])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,12 +275,9 @@ func (s *state) label(sym *Sym) *ssaLabel {
|
|||
return lab
|
||||
}
|
||||
|
||||
func (s *state) Logf(msg string, args ...interface{}) { s.config.Logf(msg, args...) }
|
||||
func (s *state) Log() bool { return s.config.Log() }
|
||||
func (s *state) Fatalf(msg string, args ...interface{}) { s.config.Fatalf(s.peekLine(), msg, args...) }
|
||||
func (s *state) Unimplementedf(msg string, args ...interface{}) {
|
||||
s.config.Unimplementedf(s.peekLine(), msg, args...)
|
||||
}
|
||||
func (s *state) Logf(msg string, args ...interface{}) { s.config.Logf(msg, args...) }
|
||||
func (s *state) Log() bool { return s.config.Log() }
|
||||
func (s *state) Fatalf(msg string, args ...interface{}) { s.config.Fatalf(s.peekLine(), msg, args...) }
|
||||
func (s *state) Warnl(line int32, msg string, args ...interface{}) { s.config.Warnl(line, msg, args...) }
|
||||
func (s *state) Debug_checknil() bool { return s.config.Debug_checknil() }
|
||||
|
||||
|
|
@ -983,7 +921,7 @@ func (s *state) stmt(n *Node) {
|
|||
s.expr(n.Left)
|
||||
|
||||
default:
|
||||
s.Unimplementedf("unhandled stmt %v", n.Op)
|
||||
s.Fatalf("unhandled stmt %v", n.Op)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1272,7 +1210,7 @@ func (s *state) ssaOp(op Op, t *Type) ssa.Op {
|
|||
etype := s.concreteEtype(t)
|
||||
x, ok := opToSSA[opAndType{op, etype}]
|
||||
if !ok {
|
||||
s.Unimplementedf("unhandled binary op %v %s", op, etype)
|
||||
s.Fatalf("unhandled binary op %v %s", op, etype)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
|
@ -1447,7 +1385,7 @@ func (s *state) ssaShiftOp(op Op, t *Type, u *Type) ssa.Op {
|
|||
etype2 := s.concreteEtype(u)
|
||||
x, ok := shiftOpToSSA[opAndTwoTypes{op, etype1, etype2}]
|
||||
if !ok {
|
||||
s.Unimplementedf("unhandled shift op %v etype=%s/%s", op, etype1, etype2)
|
||||
s.Fatalf("unhandled shift op %v etype=%s/%s", op, etype1, etype2)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
|
@ -1456,7 +1394,7 @@ func (s *state) ssaRotateOp(op Op, t *Type) ssa.Op {
|
|||
etype1 := s.concreteEtype(t)
|
||||
x, ok := opToSSA[opAndType{op, etype1}]
|
||||
if !ok {
|
||||
s.Unimplementedf("unhandled rotate op %v etype=%s", op, etype1)
|
||||
s.Fatalf("unhandled rotate op %v etype=%s", op, etype1)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
|
@ -1554,7 +1492,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||
}
|
||||
|
||||
default:
|
||||
s.Unimplementedf("unhandled OLITERAL %v", n.Val().Ctype())
|
||||
s.Fatalf("unhandled OLITERAL %v", n.Val().Ctype())
|
||||
return nil
|
||||
}
|
||||
case OCONVNOP:
|
||||
|
|
@ -1752,7 +1690,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||
s.newValue1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, x)))
|
||||
}
|
||||
|
||||
s.Unimplementedf("unhandled OCONV %s -> %s", n.Left.Type.Etype, n.Type.Etype)
|
||||
s.Fatalf("unhandled OCONV %s -> %s", n.Left.Type.Etype, n.Type.Etype)
|
||||
return nil
|
||||
|
||||
case ODOTTYPE:
|
||||
|
|
@ -1966,7 +1904,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||
|
||||
case OINDREG:
|
||||
if int(n.Reg) != Thearch.REGSP {
|
||||
s.Unimplementedf("OINDREG of non-SP register %s in expr: %v", obj.Rconv(int(n.Reg)), n)
|
||||
s.Fatalf("OINDREG of non-SP register %s in expr: %v", obj.Rconv(int(n.Reg)), n)
|
||||
return nil
|
||||
}
|
||||
addr := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(n.Type), n.Xoffset, s.sp)
|
||||
|
|
@ -2129,7 +2067,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||
return s.append(n, false)
|
||||
|
||||
default:
|
||||
s.Unimplementedf("unhandled expr %v", n.Op)
|
||||
s.Fatalf("unhandled expr %v", n.Op)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
@ -2510,7 +2448,7 @@ func (s *state) zeroVal(t *Type) *ssa.Value {
|
|||
}
|
||||
return v
|
||||
}
|
||||
s.Unimplementedf("zero for type %v not implemented", t)
|
||||
s.Fatalf("zero for type %v not implemented", t)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -2750,15 +2688,7 @@ func intrinsicInit() {
|
|||
// findIntrinsic returns a function which builds the SSA equivalent of the
|
||||
// function identified by the symbol sym. If sym is not an intrinsic call, returns nil.
|
||||
func findIntrinsic(sym *Sym) intrinsicBuilder {
|
||||
// The test below is not quite accurate -- in the event that
|
||||
// a function is disabled on a per-function basis, for example
|
||||
// because of hash-keyed binary failure search, SSA might be
|
||||
// disabled for that function but it would not be noted here,
|
||||
// and thus an inlining would not occur (in practice, inlining
|
||||
// so far has only been noticed for Bswap32 and the 16-bit count
|
||||
// leading/trailing instructions, but heuristics might change
|
||||
// in the future or on different architectures).
|
||||
if !ssaEnabled || ssa.IntrinsicsDisable {
|
||||
if ssa.IntrinsicsDisable {
|
||||
return nil
|
||||
}
|
||||
if sym == nil || sym.Pkg == nil {
|
||||
|
|
@ -3017,14 +2947,14 @@ func (s *state) addr(n *Node, bounded bool) (*ssa.Value, bool) {
|
|||
aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n})
|
||||
return s.newValue1A(ssa.OpAddr, t, aux, s.sp), false
|
||||
default:
|
||||
s.Unimplementedf("variable address class %v not implemented", classnames[n.Class])
|
||||
s.Fatalf("variable address class %v not implemented", classnames[n.Class])
|
||||
return nil, false
|
||||
}
|
||||
case OINDREG:
|
||||
// indirect off a register
|
||||
// used for storing/loading arguments/returns to/from callees
|
||||
if int(n.Reg) != Thearch.REGSP {
|
||||
s.Unimplementedf("OINDREG of non-SP register %s in addr: %v", obj.Rconv(int(n.Reg)), n)
|
||||
s.Fatalf("OINDREG of non-SP register %s in addr: %v", obj.Rconv(int(n.Reg)), n)
|
||||
return nil, false
|
||||
}
|
||||
return s.entryNewValue1I(ssa.OpOffPtr, t, n.Xoffset, s.sp), true
|
||||
|
|
@ -3067,7 +2997,7 @@ func (s *state) addr(n *Node, bounded bool) (*ssa.Value, bool) {
|
|||
return s.call(n, callNormal), true
|
||||
|
||||
default:
|
||||
s.Unimplementedf("unhandled addr %v", n.Op)
|
||||
s.Fatalf("unhandled addr %v", n.Op)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
|
@ -4086,7 +4016,7 @@ func (s *state) resolveFwdRef(v *ssa.Value, dm *sparseDefState) {
|
|||
addr := s.decladdrs[name]
|
||||
if addr == nil {
|
||||
// TODO: closure args reach here.
|
||||
s.Unimplementedf("unhandled closure arg %v at entry to function %s", name, b.Func.Name)
|
||||
s.Fatalf("unhandled closure arg %v at entry to function %s", name, b.Func.Name)
|
||||
}
|
||||
if _, ok := addr.Aux.(*ssa.ArgSymbol); !ok {
|
||||
s.Fatalf("variable live at start of function %s is not an argument %v", b.Func.Name, name)
|
||||
|
|
@ -4220,10 +4150,6 @@ func genssa(f *ssa.Func, ptxt *obj.Prog, gcargs, gclocals *Sym) {
|
|||
var s SSAGenState
|
||||
|
||||
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
|
||||
|
||||
// Remember where each block starts.
|
||||
s.bstart = make([]*obj.Prog, f.NumBlocks())
|
||||
|
|
@ -4634,9 +4560,7 @@ func fieldIdx(n *Node) int {
|
|||
|
||||
// ssaExport exports a bunch of compiler services for the ssa backend.
|
||||
type ssaExport struct {
|
||||
log bool
|
||||
unimplemented bool
|
||||
mustImplement bool
|
||||
log bool
|
||||
}
|
||||
|
||||
func (s *ssaExport) TypeBool() ssa.Type { return Types[TBOOL] }
|
||||
|
|
@ -4664,8 +4588,7 @@ func (*ssaExport) StringData(s string) interface{} {
|
|||
}
|
||||
|
||||
func (e *ssaExport) Auto(t ssa.Type) ssa.GCNode {
|
||||
n := temp(t.(*Type)) // Note: adds new auto to Curfn.Func.Dcl list
|
||||
e.mustImplement = true // This modifies the input to SSA, so we want to make sure we succeed from here!
|
||||
n := temp(t.(*Type)) // Note: adds new auto to Curfn.Func.Dcl list
|
||||
return n
|
||||
}
|
||||
|
||||
|
|
@ -4787,8 +4710,6 @@ func (e *ssaExport) namedAuto(name string, typ ssa.Type) ssa.GCNode {
|
|||
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
|
||||
|
||||
dowidth(t)
|
||||
e.mustImplement = true
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
|
|
@ -4802,8 +4723,7 @@ func (e *ssaExport) Line(line int32) string {
|
|||
|
||||
// Log logs a message from the compiler.
|
||||
func (e *ssaExport) Logf(msg string, args ...interface{}) {
|
||||
// If e was marked as unimplemented, anything could happen. Ignore.
|
||||
if e.log && !e.unimplemented {
|
||||
if e.log {
|
||||
fmt.Printf(msg, args...)
|
||||
}
|
||||
}
|
||||
|
|
@ -4814,26 +4734,8 @@ func (e *ssaExport) Log() bool {
|
|||
|
||||
// Fatal reports a compiler error and exits.
|
||||
func (e *ssaExport) Fatalf(line int32, msg string, args ...interface{}) {
|
||||
// If e was marked as unimplemented, anything could happen. Ignore.
|
||||
if !e.unimplemented {
|
||||
lineno = line
|
||||
Fatalf(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Unimplemented reports that the function cannot be compiled.
|
||||
// It will be removed once SSA work is complete.
|
||||
func (e *ssaExport) Unimplementedf(line int32, msg string, args ...interface{}) {
|
||||
if e.mustImplement {
|
||||
lineno = line
|
||||
Fatalf(msg, args...)
|
||||
}
|
||||
const alwaysLog = false // enable to calculate top unimplemented features
|
||||
if !e.unimplemented && (e.log || alwaysLog) {
|
||||
// first implementation failure, print explanation
|
||||
fmt.Printf("SSA unimplemented: "+msg+"\n", args...)
|
||||
}
|
||||
e.unimplemented = true
|
||||
lineno = line
|
||||
Fatalf(msg, args...)
|
||||
}
|
||||
|
||||
// Warnl reports a "warning", which is usually flag-triggered
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
// nothing to do
|
||||
case ssa.OpLoadReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
r := gc.SSARegNum(v)
|
||||
|
|
@ -232,7 +232,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
gc.CheckLoweredPhi(v)
|
||||
case ssa.OpStoreReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("store flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
r := gc.SSARegNum(v.Args[0])
|
||||
|
|
@ -744,7 +744,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
// Closure pointer is R22 (mips.REGCTXT).
|
||||
gc.CheckLoweredGetClosurePtr(v)
|
||||
default:
|
||||
v.Unimplementedf("genValue not implemented: %s", v.LongString())
|
||||
v.Fatalf("genValue not implemented: %s", v.LongString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -823,6 +823,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||
p.From.Reg = gc.SSARegNum(b.Control)
|
||||
}
|
||||
default:
|
||||
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -925,7 +925,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
v.Fatalf("Flag* ops should never make it to codegen %v", v.LongString())
|
||||
|
||||
default:
|
||||
v.Unimplementedf("genValue not implemented: %s", v.LongString())
|
||||
v.Fatalf("genValue not implemented: %s", v.LongString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1045,6 +1045,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||
//}
|
||||
|
||||
default:
|
||||
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
}
|
||||
case ssa.OpLoadReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(loadByType(v.Type))
|
||||
|
|
@ -483,7 +483,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
p.To.Reg = gc.SSARegNum(v)
|
||||
case ssa.OpStoreReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("store flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(storeByType(v.Type))
|
||||
|
|
@ -800,7 +800,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
clear.To.Reg = gc.SSARegNum(v.Args[0])
|
||||
}
|
||||
default:
|
||||
v.Unimplementedf("genValue not implemented: %s", v.LongString())
|
||||
v.Fatalf("genValue not implemented: %s", v.LongString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -880,6 +880,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||
s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
|
||||
}
|
||||
default:
|
||||
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,10 +189,9 @@ func (b *Block) swapSuccessors() {
|
|||
b.Likely *= -1
|
||||
}
|
||||
|
||||
func (b *Block) Logf(msg string, args ...interface{}) { b.Func.Logf(msg, args...) }
|
||||
func (b *Block) Log() bool { return b.Func.Log() }
|
||||
func (b *Block) Fatalf(msg string, args ...interface{}) { b.Func.Fatalf(msg, args...) }
|
||||
func (b *Block) Unimplementedf(msg string, args ...interface{}) { b.Func.Unimplementedf(msg, args...) }
|
||||
func (b *Block) Logf(msg string, args ...interface{}) { b.Func.Logf(msg, args...) }
|
||||
func (b *Block) Log() bool { return b.Func.Log() }
|
||||
func (b *Block) Fatalf(msg string, args ...interface{}) { b.Func.Fatalf(msg, args...) }
|
||||
|
||||
type BranchPrediction int8
|
||||
|
||||
|
|
|
|||
|
|
@ -85,10 +85,6 @@ type Logger interface {
|
|||
// Fatal reports a compiler error and exits.
|
||||
Fatalf(line int32, msg string, args ...interface{})
|
||||
|
||||
// Unimplemented reports that the function cannot be compiled.
|
||||
// It will be removed once SSA work is complete.
|
||||
Unimplementedf(line int32, msg string, args ...interface{})
|
||||
|
||||
// Warnl writes compiler messages in the form expected by "errorcheck" tests
|
||||
Warnl(line int32, fmt_ string, args ...interface{})
|
||||
|
||||
|
|
@ -218,7 +214,7 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config
|
|||
c.hasGReg = true
|
||||
c.noDuffDevice = true
|
||||
default:
|
||||
fe.Unimplementedf(0, "arch %s not implemented", arch)
|
||||
fe.Fatalf(0, "arch %s not implemented", arch)
|
||||
}
|
||||
c.ctxt = ctxt
|
||||
c.optimize = optimize
|
||||
|
|
@ -294,11 +290,8 @@ func (c *Config) NewFunc() *Func {
|
|||
func (c *Config) Logf(msg string, args ...interface{}) { c.fe.Logf(msg, args...) }
|
||||
func (c *Config) Log() bool { return c.fe.Log() }
|
||||
func (c *Config) Fatalf(line int32, msg string, args ...interface{}) { c.fe.Fatalf(line, msg, args...) }
|
||||
func (c *Config) Unimplementedf(line int32, msg string, args ...interface{}) {
|
||||
c.fe.Unimplementedf(line, msg, args...)
|
||||
}
|
||||
func (c *Config) Warnl(line int32, msg string, args ...interface{}) { c.fe.Warnl(line, msg, args...) }
|
||||
func (c *Config) Debug_checknil() bool { return c.fe.Debug_checknil() }
|
||||
func (c *Config) Warnl(line int32, msg string, args ...interface{}) { c.fe.Warnl(line, msg, args...) }
|
||||
func (c *Config) Debug_checknil() bool { return c.fe.Debug_checknil() }
|
||||
|
||||
func (c *Config) logDebugHashMatch(evname, name string) {
|
||||
file := c.logfiles[evname]
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func decomposeBuiltIn(f *Func) {
|
|||
case t.IsFloat():
|
||||
// floats are never decomposed, even ones bigger than IntSize
|
||||
case t.Size() > f.Config.IntSize:
|
||||
f.Unimplementedf("undecomposed named type %s %s", name, t)
|
||||
f.Fatalf("undecomposed named type %s %s", name, t)
|
||||
default:
|
||||
newNames = append(newNames, name)
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ func decomposeBuiltInPhi(v *Value) {
|
|||
case v.Type.IsFloat():
|
||||
// floats are never decomposed, even ones bigger than IntSize
|
||||
case v.Type.Size() > v.Block.Func.Config.IntSize:
|
||||
v.Unimplementedf("undecomposed type %s", v.Type)
|
||||
v.Fatalf("undecomposed type %s", v.Type)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,11 +66,8 @@ func (d DummyFrontend) Logf(msg string, args ...interface{}) { d.t.Logf(msg, arg
|
|||
func (d DummyFrontend) Log() bool { return true }
|
||||
|
||||
func (d DummyFrontend) Fatalf(line int32, msg string, args ...interface{}) { d.t.Fatalf(msg, args...) }
|
||||
func (d DummyFrontend) Unimplementedf(line int32, msg string, args ...interface{}) {
|
||||
d.t.Fatalf(msg, args...)
|
||||
}
|
||||
func (d DummyFrontend) Warnl(line int32, msg string, args ...interface{}) { d.t.Logf(msg, args...) }
|
||||
func (d DummyFrontend) Debug_checknil() bool { return false }
|
||||
func (d DummyFrontend) Warnl(line int32, msg string, args ...interface{}) { d.t.Logf(msg, args...) }
|
||||
func (d DummyFrontend) Debug_checknil() bool { return false }
|
||||
|
||||
func (d DummyFrontend) TypeBool() Type { return TypeBool }
|
||||
func (d DummyFrontend) TypeInt8() Type { return TypeInt8 }
|
||||
|
|
|
|||
|
|
@ -407,9 +407,6 @@ func (f *Func) ConstEmptyString(line int32, t Type) *Value {
|
|||
func (f *Func) Logf(msg string, args ...interface{}) { f.Config.Logf(msg, args...) }
|
||||
func (f *Func) Log() bool { return f.Config.Log() }
|
||||
func (f *Func) Fatalf(msg string, args ...interface{}) { f.Config.Fatalf(f.Entry.Line, msg, args...) }
|
||||
func (f *Func) Unimplementedf(msg string, args ...interface{}) {
|
||||
f.Config.Unimplementedf(f.Entry.Line, msg, args...)
|
||||
}
|
||||
|
||||
func (f *Func) Free() {
|
||||
// Clear values.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ func checkLower(f *Func) {
|
|||
for _, a := range v.Args {
|
||||
s += " " + a.Type.SimpleString()
|
||||
}
|
||||
f.Unimplementedf("%s", s)
|
||||
f.Fatalf("%s", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ func (s *regAllocState) allocReg(mask regMask, v *Value) register {
|
|||
}
|
||||
}
|
||||
if maxuse == -1 {
|
||||
s.f.Unimplementedf("couldn't find register to spill")
|
||||
s.f.Fatalf("couldn't find register to spill")
|
||||
}
|
||||
s.freeReg(r)
|
||||
return r
|
||||
|
|
@ -505,7 +505,7 @@ func (s *regAllocState) init(f *Func) {
|
|||
case "s390x":
|
||||
// nothing to do, R10 & R11 already reserved
|
||||
default:
|
||||
s.f.Config.fe.Unimplementedf(0, "arch %s not implemented", s.f.Config.arch)
|
||||
s.f.Config.fe.Fatalf(0, "arch %s not implemented", s.f.Config.arch)
|
||||
}
|
||||
}
|
||||
if s.f.Config.nacl {
|
||||
|
|
|
|||
|
|
@ -228,9 +228,6 @@ func (v *Value) Log() bool { return v.Block.Log() }
|
|||
func (v *Value) Fatalf(msg string, args ...interface{}) {
|
||||
v.Block.Func.Config.Fatalf(v.Line, msg, args...)
|
||||
}
|
||||
func (v *Value) Unimplementedf(msg string, args ...interface{}) {
|
||||
v.Block.Func.Config.Unimplementedf(v.Line, msg, args...)
|
||||
}
|
||||
|
||||
// isGenericIntConst returns whether v is a generic integer constant.
|
||||
func (v *Value) isGenericIntConst() bool {
|
||||
|
|
|
|||
|
|
@ -630,7 +630,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
}
|
||||
case ssa.OpLoadReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(loadByType(v.Type))
|
||||
|
|
@ -650,7 +650,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
|
||||
case ssa.OpStoreReg:
|
||||
if v.Type.IsFlags() {
|
||||
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
||||
v.Fatalf("store flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := gc.Prog(storeByType(v.Type))
|
||||
|
|
@ -886,7 +886,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
case ssa.Op386FCHS:
|
||||
v.Fatalf("FCHS in non-387 mode")
|
||||
default:
|
||||
v.Unimplementedf("genValue not implemented: %s", v.LongString())
|
||||
v.Fatalf("genValue not implemented: %s", v.LongString())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1005,6 +1005,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
|||
}
|
||||
|
||||
default:
|
||||
b.Unimplementedf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue