Adjust cmd/compile accordingly.
This will make it easier to replace the underlying implementation.
Change-Id: I33645850bb18c839b24785b6222a9e028617addb
Reviewed-on: https://go-review.googlesource.com/34133
Reviewed-by: David Lazar <lazard@golang.org>
"cmd/compile/internal/syntax.token %q": "",
"cmd/compile/internal/syntax.token %s": "",
"cmd/internal/obj.As %v": "",
- "cmd/internal/src.Pos %d": "",
"error %v": "",
"float64 %.2f": "",
"float64 %.3f": "",
p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg()
gc.AddAux(&p.To, v)
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line.Line()==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
case ssa.OpAMD64MOVLatomicload, ssa.OpAMD64MOVQatomicload:
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = arm.REGTMP
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line.Line()==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
case ssa.OpARMLoweredZero:
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = arm64.REGTMP
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
case ssa.OpVarDef:
package gc
-import "fmt"
+import (
+ "cmd/internal/src"
+ "fmt"
+)
// AlgKind describes the kind of algorithms used for comparing and
// hashing a Type.
fmt.Printf("genhash %v %v\n", sym, t)
}
- lineno = 1 // less confusing than end of input
+ lineno = src.MakePos(1) // less confusing than end of input
dclcontext = PEXTERN
markdcl()
fmt.Printf("geneq %v %v\n", sym, t)
}
- lineno = 1 // less confusing than end of input
+ lineno = src.MakePos(1) // less confusing than end of input
dclcontext = PEXTERN
markdcl()
func fileLine(n *Node) (file string, line int) {
if n != nil {
- file, line = Ctxt.LineHist.AbsFileLine(int(n.Lineno))
+ file, line = Ctxt.LineHist.AbsFileLine(int(n.Lineno.Line()))
}
return
}
// redeclare emits a diagnostic about symbol s being redeclared somewhere.
func redeclare(s *Sym, where string) {
- if s.Lastlineno == 0 {
+ if !s.Lastlineno.IsKnown() {
var tmp string
if s.Origpkg != nil {
tmp = s.Origpkg.Path
// declare constants from grammar
// new_name_list [[type] = expr_list]
func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
- lno := src.Pos(0) // default is to leave line number alone in listtreecopy
+ var lno src.Pos // default is to leave line number alone in listtreecopy
if len(cl) == 0 {
if t != nil {
yyerror("const declaration cannot have type without expression")
if t.IsPtr() || t.IsUnsafePtr() {
yyerror("embedded type cannot be a pointer")
- } else if t.Etype == TFORW && t.ForwardType().Embedlineno == 0 {
+ } else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
t.ForwardType().Embedlineno = lineno
}
}
visitBottomUp(xtop, func(list []*Node, recursive bool) {
// Functions with write barriers have depth 0.
for _, n := range list {
- if n.Func.WBLineno != 0 && n.Func.Pragma&Yeswritebarrierrec == 0 {
+ if n.Func.WBLineno.IsKnown() && n.Func.Pragma&Yeswritebarrierrec == 0 {
c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBLineno}
}
}
// yeswritebarrierrec function.
continue
}
- if n.Func.WBLineno == 0 {
+ if !n.Func.WBLineno.IsKnown() {
c.curfn = n
c.visitcodelist(n.Nbody)
}
fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
}
- if n.Lineno != 0 {
- fmt.Fprintf(s, " l(%d)", n.Lineno)
+ if n.Lineno.IsKnown() {
+ fmt.Fprintf(s, " l(%d)", n.Lineno.Line())
}
if c == 0 && n.Xoffset != BADWIDTH {
Clearp(pc)
p.Link = pc
- if lineno == 0 && Debug['K'] != 0 {
- Warn("prog: line 0")
+ if !lineno.IsKnown() && Debug['K'] != 0 {
+ Warn("prog: unknown position (line 0)")
}
p.As = as
- p.Lineno = int32(lineno) // TODO(gri) fix this
+ p.Lineno = int32(lineno.Line()) // TODO(gri) fix this
return p
}
}
// don't clobber names, unless they're freshly synthesized
- if n.Op != ONAME || n.Lineno == 0 {
+ if n.Op != ONAME || !n.Lineno.IsKnown() {
n.Lineno = lno
}
blockgen = 1
dclcontext = PEXTERN
nerrors = 0
- lexlineno = 1
+ lexlineno = src.MakePos(1)
timings.Start("fe", "loadsys")
loadsys()
// Instead of converting EOF into '\n' in getc and count it as an extra line
// for the line history to work, and which then has to be corrected elsewhere,
// just add a line here.
- lexlineno++
+ lexlineno = src.MakePos(lexlineno.Line() + 1)
linehistpop()
}
timings.Stop()
- timings.AddEvent(int64(lexlineno-lexlineno0), "lines")
+ timings.AddEvent(int64(lexlineno.Line()-lexlineno0.Line()), "lines")
testdclstack()
mkpackage(localpkg.Name) // final import not used checks
}
defer src.Close()
- p := noder{baseline: lexlineno}
+ p := noder{baseline: lexlineno.Line()}
file, _ := syntax.Parse(src, p.error, p.pragma, 0) // errors are tracked via p.error
p.file(file)
// noder transforms package syntax's AST into a Nod tree.
type noder struct {
- baseline src.Pos
+ baseline int32
linknames []int // tracks //go:linkname lines
}
xtop = append(xtop, p.decls(file.DeclList)...)
- lexlineno = p.baseline + src.Pos(file.Lines) - 1
+ lexlineno = src.MakePos(p.baseline + int32(file.Lines) - 1)
lineno = lexlineno
}
yyerror("can only use //go:noescape with external func implementations")
}
f.Func.Pragma = pragma
- lineno = p.baseline + src.Pos(fun.EndLine) - 1
+ lineno = src.MakePos(p.baseline + int32(fun.EndLine) - 1)
f.Func.Endlineno = lineno
funcbody(f)
l[i] = p.wrapname(expr.ElemList[i], e)
}
n.List.Set(l)
- lineno = p.baseline + src.Pos(expr.EndLine) - 1
+ lineno = src.MakePos(p.baseline + int32(expr.EndLine) - 1)
return n
case *syntax.KeyValueExpr:
return p.nod(expr, OKEY, p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
case *syntax.FuncLit:
closurehdr(p.typeExpr(expr.Type))
body := p.stmts(expr.Body)
- lineno = p.baseline + src.Pos(expr.EndLine) - 1
+ lineno = src.MakePos(p.baseline + int32(expr.EndLine) - 1)
return p.setlineno(expr, closurebody(body))
case *syntax.ParenExpr:
return p.nod(expr, OPAREN, p.expr(expr.X), nil)
}
func (p *noder) setlineno(src_ syntax.Node, dst *Node) *Node {
- l := src.Pos(src_.Line())
+ l := src_.Line()
if l == 0 {
// TODO(mdempsky): Shouldn't happen. Fix package syntax.
return dst
}
- dst.Lineno = p.baseline + l - 1
+ dst.Lineno = src.MakePos(p.baseline + int32(l) - 1)
return dst
}
if n == nil {
return
}
- l := src.Pos(n.Line())
+ l := n.Line()
if l == 0 {
// TODO(mdempsky): Shouldn't happen. Fix package syntax.
return
}
- lineno = p.baseline + l - 1
+ lineno = src.MakePos(p.baseline + int32(l) - 1)
}
func (p *noder) error(err error) {
line := p.baseline
var msg string
if err, ok := err.(syntax.Error); ok {
- line += src.Pos(err.Line) - 1
+ line += int32(err.Line) - 1
msg = err.Msg
} else {
msg = err.Error()
}
- yyerrorl(line, "%s", msg)
+ yyerrorl(src.MakePos(line), "%s", msg)
}
func (p *noder) pragma(pos, line int, text string) syntax.Pragma {
if n <= 0 {
break
}
- lexlineno = p.baseline + src.Pos(line)
+ lexlineno = src.MakePos(p.baseline + int32(line))
linehistupdate(text[5:i], n)
case strings.HasPrefix(text, "go:linkname "):
package gc
import (
+ "cmd/internal/src"
"fmt"
)
n.Left = orderexpr(n.Left, order, nil)
n.Left = ordersafeexpr(n.Left, order)
- tmp1 := treecopy(n.Left, 0)
+ tmp1 := treecopy(n.Left, src.Pos{})
if tmp1.Op == OINDEXMAP {
tmp1.Etype = 0 // now an rvalue not an lvalue
}
if !n.Name.Needzero {
n.Name.Needzero = true
if debuglive >= 1 {
- Warnl(src.Pos(p.Lineno), "%v: %L is ambiguously live", Curfn.Func.Nname, n)
+ Warnl(src.MakePos(p.Lineno), "%v: %L is ambiguously live", Curfn.Func.Nname, n)
}
}
}
}
n := lv.vars[j]
if n.Class != PPARAM {
- yyerrorl(src.Pos(p.Lineno), "internal error: %v %L recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, n, p.Pc)
+ yyerrorl(src.MakePos(p.Lineno), "internal error: %v %L recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, n, p.Pc)
}
}
}
package gc
import (
+ "cmd/internal/src"
"fmt"
"strings"
)
*np = n
}
- n = treecopy(n, 0)
+ n = treecopy(n, src.Pos{})
makeaddable(n)
var f *Node
if flag_msan {
s.noWB = true
}
defer func() {
- if s.WBLineno != 0 {
+ if s.WBLineno.IsKnown() {
fn.Func.WBLineno = s.WBLineno
}
}()
// pushLine pushes a line number on the line number stack.
func (s *state) pushLine(line src.Pos) {
- if line == 0 {
+ if !line.IsKnown() {
// the frontend may emit node with line number missing,
// use the parent line number in this case.
line = s.peekLine()
if Debug['K'] != 0 {
- Warn("buildssa: line 0")
+ Warn("buildssa: unknown position (line 0)")
}
}
s.line = append(s.line, line)
func (s *state) exprPtr(n *Node, bounded bool, lineno src.Pos) *ssa.Value {
p := s.expr(n)
if bounded || n.NonNil {
- if s.f.Config.Debug_checknil() && lineno > 1 {
+ if s.f.Config.Debug_checknil() && lineno.Line() > 1 {
s.f.Config.Warnl(lineno, "removed nil check")
}
return p
if s.noWB {
s.Error("write barrier prohibited")
}
- if s.WBLineno == 0 {
+ if !s.WBLineno.IsKnown() {
s.WBLineno = left.Line
}
if s.noWB {
s.Error("write barrier prohibited")
}
- if s.WBLineno == 0 {
+ if !s.WBLineno.IsKnown() {
s.WBLineno = left.Line
}
s.storeTypeScalars(t, left, right, skip)
type byLineno []Error
func (x byLineno) Len() int { return len(x) }
-func (x byLineno) Less(i, j int) bool { return x[i].lineno < x[j].lineno }
+func (x byLineno) Less(i, j int) bool { return x[i].lineno.Before(x[j].lineno) }
func (x byLineno) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
// flusherrors sorts errors seen so far by line number, prints them to stdout,
}
func linestr(line src.Pos) string {
- return Ctxt.Line(int(line))
+ return Ctxt.Line(int(line.Line()))
}
// lasterror keeps track of the most recently issued error.
if Debug['i'] != 0 {
fmt.Printf("import %s at line %v\n", file, linestr(lexlineno))
}
- Ctxt.LineHist.Push(int(lexlineno), file)
+ Ctxt.LineHist.Push(int(lexlineno.Line()), file)
}
func linehistpop() {
if Debug['i'] != 0 {
fmt.Printf("end of import at line %v\n", linestr(lexlineno))
}
- Ctxt.LineHist.Pop(int(lexlineno))
+ Ctxt.LineHist.Pop(int(lexlineno.Line()))
}
func linehistupdate(file string, off int) {
if Debug['i'] != 0 {
fmt.Printf("line %s at line %v\n", file, linestr(lexlineno))
}
- Ctxt.LineHist.Update(int(lexlineno), file, off)
+ Ctxt.LineHist.Update(int(lexlineno.Line()), file, off)
}
func setlineno(n *Node) src.Pos {
default:
lineno = n.Lineno
- if lineno == 0 {
+ if !lineno.IsKnown() {
if Debug['K'] != 0 {
- Warn("setlineno: line 0")
+ Warn("setlineno: unknown position (line 0)")
}
lineno = lno
}
m.Left = treecopy(n.Left, lineno)
m.Right = treecopy(n.Right, lineno)
m.List.Set(listtreecopy(n.List.Slice(), lineno))
- if lineno != 0 {
+ if lineno.IsKnown() {
m.Lineno = lineno
}
if m.Name != nil && n.Op != ODCLFIELD {
// so that all the copies of this const definition
// don't have the same iota value.
m := *n
- if lineno != 0 {
+ if lineno.IsKnown() {
m.Lineno = lineno
}
m.SetIota(iota_)
fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
}
- lexlineno++
+ lexlineno = src.MakePos(lexlineno.Line() + 1)
lineno = lexlineno
if genwrapper_linehistdone == 0 {
// All the wrappers can share the same linehist entry.
// Double-check use of type as embedded type.
lno := lineno
- if embedlineno != 0 {
+ if embedlineno.IsKnown() {
lineno = embedlineno
if t.IsPtr() || t.IsUnsafePtr() {
yyerror("embedded type cannot be a pointer")
if n.Op == ONONAME {
if !n.Diag {
n.Diag = true
- if n.Lineno != 0 {
+ if n.Lineno.IsKnown() {
lineno = n.Lineno
}
)
func (n *Node) Line() string {
- return Ctxt.LineHist.LineString(int(n.Lineno))
+ return Ctxt.LineHist.LineString(int(n.Lineno.Line()))
}
var atExitFuncs []func()
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REGTMP
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
case ssa.OpMIPSFPFlagTrue,
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = mips.REGTMP
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
case ssa.OpVarDef:
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = ppc64.REGTMP
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
gc.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = s390x.REGTMP
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
case ssa.OpS390XMVC:
package ssa
import (
+ "cmd/internal/src"
"fmt"
"log"
"os"
fi, err := os.Create(fname)
if err != nil {
- f.Config.Warnl(0, "Unable to create after-phase dump file %s", fname)
+ f.Config.Warnl(src.Pos{}, "Unable to create after-phase dump file %s", fname)
return
}
c.hasGReg = true
c.noDuffDevice = true
default:
- fe.Fatalf(0, "arch %s not implemented", arch)
+ fe.Fatalf(src.Pos{}, "arch %s not implemented", arch)
}
c.ctxt = ctxt
c.optimize = optimize
if ev != "" {
v, err := strconv.ParseInt(ev, 10, 64)
if err != nil {
- fe.Fatalf(0, "Environment variable GO_SSA_PHI_LOC_CUTOFF (value '%s') did not parse as a number", ev)
+ fe.Fatalf(src.Pos{}, "Environment variable GO_SSA_PHI_LOC_CUTOFF (value '%s') did not parse as a number", ev)
}
c.sparsePhiCutoff = uint64(v) // convert -1 to maxint, for never use sparse
}
func (c *Config) NewFunc() *Func {
// TODO(khr): should this function take name, type, etc. as arguments?
if c.curFunc != nil {
- c.Fatalf(0, "NewFunc called without previous Free")
+ c.Fatalf(src.Pos{}, "NewFunc called without previous Free")
}
f := &Func{Config: c, NamedValues: map[LocalSlot][]*Value{}}
c.curFunc = f
var ok error
file, ok = os.Create(tmpfile)
if ok != nil {
- c.Fatalf(0, "Could not open hash-testing logfile %s", tmpfile)
+ c.Fatalf(src.Pos{}, "Could not open hash-testing logfile %s", tmpfile)
}
}
c.logfiles[evname] = file
package ssa
+import "cmd/internal/src"
+
// dse does dead-store elimination on the Function.
// Dead stores are those which are unconditionally followed by
// another store to the same location, with no intervening load.
if sz > 0x7fffffff { // work around sparseMap's int32 value type
sz = 0x7fffffff
}
- shadowed.set(v.Args[0].ID, int32(sz), 0)
+ shadowed.set(v.Args[0].ID, int32(sz), src.Pos{})
}
}
// walk to previous store
// the parser can be used instead of Fun.
import (
+ "cmd/internal/src"
"fmt"
"reflect"
"testing"
blocks[bloc.name] = b
for _, valu := range bloc.valus {
// args are filled in the second pass.
- values[valu.name] = b.NewValue0IA(0, valu.op, valu.t, valu.auxint, valu.aux)
+ values[valu.name] = b.NewValue0IA(src.Pos{}, valu.op, valu.t, valu.auxint, valu.aux)
}
}
// Connect the blocks together and specify control values.
Bloc("entry",
Valu("mem", OpInitMem, TypeMem, 0, nil),
Exit("mem")))
- v1 := f.f.ConstBool(0, TypeBool, false)
- v2 := f.f.ConstBool(0, TypeBool, true)
+ v1 := f.f.ConstBool(src.Pos{}, TypeBool, false)
+ v2 := f.f.ConstBool(src.Pos{}, TypeBool, true)
f.f.freeValue(v1)
f.f.freeValue(v2)
- v3 := f.f.ConstBool(0, TypeBool, false)
- v4 := f.f.ConstBool(0, TypeBool, true)
+ v3 := f.f.ConstBool(src.Pos{}, TypeBool, false)
+ v4 := f.f.ConstBool(src.Pos{}, TypeBool, true)
if v3.AuxInt != 0 {
t.Errorf("expected %s to have auxint of 0\n", v3.LongString())
}
import (
"bytes"
+ "cmd/internal/src"
"fmt"
"html"
"io"
func NewHTMLWriter(path string, logger Logger, funcname string) *HTMLWriter {
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
- logger.Fatalf(0, "%v", err)
+ logger.Fatalf(src.Pos{}, "%v", err)
}
html := HTMLWriter{File: out, Logger: logger}
html.start(funcname)
func (w *HTMLWriter) Printf(msg string, v ...interface{}) {
if _, err := fmt.Fprintf(w.File, msg, v...); err != nil {
- w.Fatalf(0, "%v", err)
+ w.Fatalf(src.Pos{}, "%v", err)
}
}
func (w *HTMLWriter) WriteString(s string) {
if _, err := w.File.WriteString(s); err != nil {
- w.Fatalf(0, "%v", err)
+ w.Fatalf(src.Pos{}, "%v", err)
}
}
// This is a redundant implicit nil check.
// Logging in the style of the former compiler -- and omit line 1,
// which is usually in generated code.
- if f.Config.Debug_checknil() && v.Line > 1 {
+ if f.Config.Debug_checknil() && v.Line.Line() > 1 {
f.Config.Warnl(v.Line, "removed nil check")
}
v.reset(OpUnknown)
for i := len(b.Values) - 1; i >= 0; i-- {
v := b.Values[i]
if opcodeTable[v.Op].nilCheck && unnecessary.contains(v.Args[0].ID) {
- if f.Config.Debug_checknil() && int(v.Line) > 1 {
+ if f.Config.Debug_checknil() && v.Line.Line() > 1 {
f.Config.Warnl(v.Line, "removed nil check")
}
v.reset(OpUnknown)
case "s390x":
// nothing to do, R10 & R11 already reserved
default:
- s.f.Config.fe.Fatalf(0, "arch %s not implemented", s.f.Config.arch)
+ s.f.Config.fe.Fatalf(src.Pos{}, "arch %s not implemented", s.f.Config.arch)
}
}
if s.f.Config.nacl {
// Live registers can be sources.
for _, x := range srcReg {
- e.set(&e.s.registers[x.r], x.v.ID, x.c, false, 0) // don't care the line number of the source
+ e.set(&e.s.registers[x.r], x.v.ID, x.c, false, src.Pos{}) // don't care the line number of the source
}
// So can all of the spill locations.
for _, spillID := range stacklive {
v := e.s.orig[spillID]
spill := e.s.values[v.ID].spill
- e.set(e.s.f.getHome(spillID), v.ID, spill, false, 0) // don't care the line number of the source
+ e.set(e.s.f.getHome(spillID), v.ID, spill, false, src.Pos{}) // don't care the line number of the source
}
// Figure out all the destinations we need.
return true
}
// match: (NilCheck (Load (OffPtr [c] (SP)) mem) mem)
- // cond: mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")
+ // cond: mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")
// result: (Invalid)
for {
v_0 := v.Args[0]
if mem != v.Args[1] {
break
}
- if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")) {
+ if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")) {
break
}
v.reset(OpInvalid)
return true
}
// match: (NilCheck (OffPtr (Load (OffPtr [c] (SP)) mem)) mem)
- // cond: mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")
+ // cond: mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize() + config.RegSize && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")
// result: (Invalid)
for {
v_0 := v.Args[0]
if mem != v.Args[1] {
break
}
- if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")) {
+ if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")) {
break
}
v.reset(OpInvalid)
return c > 0 // higher score comes later.
}
if x.Line != y.Line { // Favor in-order line stepping
- return x.Line > y.Line
+ return x.Line.After(y.Line)
}
if x.Op != OpPhi {
if c := len(x.Args) - len(y.Args); c != 0 {
s.dense[i].val |= 1 << v
return
}
- s.dense = append(s.dense, sparseEntry{k, 1 << v, 0})
+ s.dense = append(s.dense, sparseEntry{k, 1 << v, src.Pos{}})
s.sparse[k] = int32(len(s.dense)) - 1
}
package ssa
-import "fmt"
+import (
+ "cmd/internal/src"
+ "fmt"
+)
type stackAllocState struct {
f *Func
return new(stackAllocState)
}
if s.f != nil {
- f.Config.Fatalf(0, "newStackAllocState called without previous free")
+ f.Config.Fatalf(src.Pos{}, "newStackAllocState called without previous free")
}
return s
}
p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg()
gc.AddAux(&p.To, v)
- if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+ if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
gc.Warnl(v.Line, "generated nil check")
}
case ssa.Op386FCHS:
// Package src implements source positions.
package src
+// Implementation note: This is a thin abstraction over
+// the historic representation of source positions via
+// global line numbers. The abstraction will make it
+// easier to replace this implementation, eventually.
+
// A Pos represents a source position.
-// It is an index into the global line table, which
-// maps a Pos to a file name and source line number.
-type Pos int32
+// The zero value for a Pos is a valid unknown position.
+type Pos struct {
+ // line is an index into the global line table, which maps
+ // the corresponding Pos to a file name and source line number.
+ line int32
+}
+
+// MakePos creates a new Pos from a line index.
+// It requires intimate knowledge of the underlying
+// implementation and should be used with caution.
+func MakePos(line int32) Pos { return Pos{line} }
+
+func (p Pos) IsKnown() bool { return p.line != 0 }
+func (p Pos) Line() int32 { return p.line }
+func (p Pos) Before(q Pos) bool { return p.line < q.line }
+func (p Pos) After(q Pos) bool { return p.line > q.line }