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>
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)
}
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))
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))
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())
}
}
}
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())
}
}
// 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))
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))
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())
}
}
}
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())
}
}
// 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))
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))
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())
}
}
}
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())
}
}
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)
package gc
import (
- "cmd/compile/internal/ssa"
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
}
// Build an SSA backend function.
- var ssafn *ssa.Func
- if shouldssa(Curfn) {
- ssafn = buildssa(Curfn)
+ ssafn := buildssa(Curfn)
+ if nerrors != 0 {
+ return
}
continpc = nil
}
}
- 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
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)
-}
"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" {
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
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])
}
}
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() }
s.expr(n.Left)
default:
- s.Unimplementedf("unhandled stmt %v", n.Op)
+ s.Fatalf("unhandled stmt %v", n.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
}
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
}
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
}
}
default:
- s.Unimplementedf("unhandled OLITERAL %v", n.Val().Ctype())
+ s.Fatalf("unhandled OLITERAL %v", n.Val().Ctype())
return nil
}
case OCONVNOP:
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:
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)
return s.append(n, false)
default:
- s.Unimplementedf("unhandled expr %v", n.Op)
+ s.Fatalf("unhandled expr %v", n.Op)
return nil
}
}
}
return v
}
- s.Unimplementedf("zero for type %v not implemented", t)
+ s.Fatalf("zero for type %v not implemented", t)
return nil
}
// 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 {
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
return s.call(n, callNormal), true
default:
- s.Unimplementedf("unhandled addr %v", n.Op)
+ s.Fatalf("unhandled addr %v", n.Op)
return nil, false
}
}
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)
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())
// 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] }
}
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
}
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
dowidth(t)
- e.mustImplement = true
-
return n
}
// 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...)
}
}
// 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
// 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)
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])
// 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())
}
}
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())
}
}
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())
}
}
//}
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())
}
}
}
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))
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))
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())
}
}
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())
}
}
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
// 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{})
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
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]
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)
}
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)
}
}
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 }
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.
for _, a := range v.Args {
s += " " + a.Type.SimpleString()
}
- f.Unimplementedf("%s", s)
+ f.Fatalf("%s", s)
}
}
}
}
}
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
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 {
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 {
}
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))
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))
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())
}
}
}
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())
}
}