This is a step toward chosing a different position representation.
By introducing an explicit type, it will be easier to make the
transition step-wise while ensuring everything keeps running.
This has been reviewed via https://go-review.googlesource.com/#/c/34025/.
Change-Id: Ibceddcd62d8f346321ac3250e3940e9c436ed684
Reviewed-on: https://go-review.googlesource.com/34132
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
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": "",
package gc
-import "strings"
+import (
+ "cmd/internal/src"
+ "strings"
+)
// Ctype describes the constant kind of an "ideal" (untyped) constant.
type Ctype int8
nr := n.Right
var rv Val
- var lno int32
+ var lno src.Pos
var wr EType
var v Val
var norig *Node
import (
"cmd/internal/obj"
+ "cmd/internal/src"
"fmt"
"sort"
"strings"
// declare constants from grammar
// new_name_list [[type] = expr_list]
func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
- lno := int32(0) // default is to leave line number alone in listtreecopy
+ lno := src.Pos(0) // default is to leave line number alone in listtreecopy
if len(cl) == 0 {
if t != nil {
yyerror("const declaration cannot have type without expression")
type nowritebarrierrecCall struct {
target *Node
depth int
- lineno int32
+ lineno src.Pos
}
func checknowritebarrierrec() {
"cmd/compile/internal/ssa"
"cmd/internal/bio"
"cmd/internal/obj"
+ "cmd/internal/src"
)
const (
// saved and restored by dcopy
Pkg *Pkg
- Name string // object name
- Def *Node // definition: ONAME OTYPE OPACK or OLITERAL
- Block int32 // blocknumber to catch redeclaration
- Lastlineno int32 // last declaration for diagnostic
+ Name string // object name
+ Def *Node // definition: ONAME OTYPE OPACK or OLITERAL
+ Block int32 // blocknumber to catch redeclaration
+ Lastlineno src.Pos // last declaration for diagnostic
Label *Node // corresponding label (ephemeral)
Origpkg *Pkg // original package for . import
}
p.As = as
- p.Lineno = lineno
+ p.Lineno = int32(lineno) // TODO(gri) fix this
return p
}
package gc
-import "fmt"
+import (
+ "cmd/internal/src"
+ "fmt"
+)
// Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
// the ->sym can be re-used in the local package, so peel it off the receiver's type.
}
// Plaster over linenumbers
-func setlnolist(ll Nodes, lno int32) {
+func setlnolist(ll Nodes, lno src.Pos) {
for _, n := range ll.Slice() {
setlno(n, lno)
}
}
-func setlno(n *Node, lno int32) {
+func setlno(n *Node, lno src.Pos) {
if n == nil {
return
}
import (
"cmd/compile/internal/syntax"
"cmd/internal/obj"
+ "cmd/internal/src"
"fmt"
"strings"
)
// lexlineno is the line number _after_ the most recently read rune.
// In particular, it's advanced (or rewound) as newlines are read (or unread).
-var lexlineno int32
+var lexlineno src.Pos
// lineno is the line number at the start of the most recently lexed token.
-var lineno int32
+var lineno src.Pos
func isSpace(c rune) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
"bytes"
"cmd/compile/internal/ssa"
"cmd/internal/obj"
+ "cmd/internal/src"
"cmd/internal/sys"
"flag"
"fmt"
}
}
-func pkgnotused(lineno int32, path string, name string) {
+func pkgnotused(lineno src.Pos, path string, name string) {
// If the package was imported with a name other than the final
// import path element, show it explicitly in the error message.
// Note that this handles both renamed imports and imports of
package gc
import (
+ "cmd/compile/internal/syntax"
+ "cmd/internal/src"
"fmt"
"os"
"strconv"
"strings"
"unicode/utf8"
-
- "cmd/compile/internal/syntax"
)
func parseFile(filename string) {
// noder transforms package syntax's AST into a Nod tree.
type noder struct {
- baseline int32
+ baseline src.Pos
linknames []int // tracks //go:linkname lines
}
xtop = append(xtop, p.decls(file.DeclList)...)
- lexlineno = p.baseline + int32(file.Lines) - 1
+ lexlineno = p.baseline + src.Pos(file.Lines) - 1
lineno = lexlineno
}
yyerror("can only use //go:noescape with external func implementations")
}
f.Func.Pragma = pragma
- lineno = p.baseline + int32(fun.EndLine) - 1
+ lineno = p.baseline + src.Pos(fun.EndLine) - 1
f.Func.Endlineno = lineno
funcbody(f)
l[i] = p.wrapname(expr.ElemList[i], e)
}
n.List.Set(l)
- lineno = p.baseline + int32(expr.EndLine) - 1
+ lineno = p.baseline + src.Pos(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 + int32(expr.EndLine) - 1
+ lineno = p.baseline + src.Pos(expr.EndLine) - 1
return p.setlineno(expr, closurebody(body))
case *syntax.ParenExpr:
return p.nod(expr, OPAREN, p.expr(expr.X), nil)
return p.setlineno(orig, nod(op, left, right))
}
-func (p *noder) setlineno(src syntax.Node, dst *Node) *Node {
- l := int32(src.Line())
+func (p *noder) setlineno(src_ syntax.Node, dst *Node) *Node {
+ l := src.Pos(src_.Line())
if l == 0 {
// TODO(mdempsky): Shouldn't happen. Fix package syntax.
return dst
if n == nil {
return
}
- l := int32(n.Line())
+ l := src.Pos(n.Line())
if l == 0 {
// TODO(mdempsky): Shouldn't happen. Fix package syntax.
return
line := p.baseline
var msg string
if err, ok := err.(syntax.Error); ok {
- line += int32(err.Line) - 1
+ line += src.Pos(err.Line) - 1
msg = err.Msg
} else {
msg = err.Error()
if n <= 0 {
break
}
- lexlineno = p.baseline + int32(line)
+ lexlineno = p.baseline + src.Pos(line)
linehistupdate(text[5:i], n)
case strings.HasPrefix(text, "go:linkname "):
import (
"cmd/compile/internal/ssa"
"cmd/internal/obj"
+ "cmd/internal/src"
"cmd/internal/sys"
"fmt"
"sort"
assertI2I2 = Sysfunc("assertI2I2")
}
- defer func(lno int32) {
+ defer func(lno src.Pos) {
lineno = lno
}(setlineno(fn))
import (
"cmd/compile/internal/ssa"
+ "cmd/internal/src"
"container/heap"
"fmt"
)
}
// lookupVarOutgoing finds the variable's value at the end of block b.
-func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t ssa.Type, var_ *Node, line int32) *ssa.Value {
+func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t ssa.Type, var_ *Node, line src.Pos) *ssa.Value {
for {
if v := s.defvars[b.ID][var_]; v != nil {
return v
import (
"cmd/internal/obj"
+ "cmd/internal/src"
"cmd/internal/sys"
"crypto/md5"
"fmt"
if !n.Name.Needzero {
n.Name.Needzero = true
if debuglive >= 1 {
- Warnl(p.Lineno, "%v: %L is ambiguously live", Curfn.Func.Nname, n)
+ Warnl(src.Pos(p.Lineno), "%v: %L is ambiguously live", Curfn.Func.Nname, n)
}
}
}
}
n := lv.vars[j]
if n.Class != PPARAM {
- yyerrorl(p.Lineno, "internal error: %v %L recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, n, p.Pc)
+ yyerrorl(src.Pos(p.Lineno), "internal error: %v %L recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, n, p.Pc)
}
}
}
"cmd/compile/internal/ssa"
"cmd/internal/obj"
+ "cmd/internal/src"
"cmd/internal/sys"
)
sb *ssa.Value
// line number stack. The current line number is top of stack
- line []int32
+ line []src.Pos
// list of panic calls by function name and line number.
// Used to deduplicate panic calls.
cgoUnsafeArgs bool
noWB bool
- WBLineno int32 // line number of first write barrier. 0=no write barriers
+ WBLineno src.Pos // line number of first write barrier. 0=no write barriers
}
type funcLine struct {
f *Node
- line int32
+ line src.Pos
}
type ssaLabel struct {
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) Warnl(line int32, msg string, args ...interface{}) { s.config.Warnl(line, msg, args...) }
-func (s *state) Debug_checknil() bool { return s.config.Debug_checknil() }
+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 src.Pos, msg string, args ...interface{}) {
+ s.config.Warnl(line, msg, args...)
+}
+func (s *state) Debug_checknil() bool { return s.config.Debug_checknil() }
var (
// dummy node for the memory variable
}
// pushLine pushes a line number on the line number stack.
-func (s *state) pushLine(line int32) {
+func (s *state) pushLine(line src.Pos) {
if line == 0 {
// the frontend may emit node with line number missing,
// use the parent line number in this case.
}
// peekLine peek the top of the line number stack.
-func (s *state) peekLine() int32 {
+func (s *state) peekLine() src.Pos {
return s.line[len(s.line)-1]
}
// If deref is true, rightIsVolatile reports whether right points to volatile (clobbered by a call) storage.
// Include a write barrier if wb is true.
// skip indicates assignments (at the top level) that can be avoided.
-func (s *state) assign(left *Node, right *ssa.Value, wb, deref bool, line int32, skip skipMask, rightIsVolatile bool) {
+func (s *state) assign(left *Node, right *ssa.Value, wb, deref bool, line src.Pos, skip skipMask, rightIsVolatile bool) {
if left.Op == ONAME && isblank(left) {
return
}
}
// exprPtr evaluates n to a pointer and nil-checks it.
-func (s *state) exprPtr(n *Node, bounded bool, lineno int32) *ssa.Value {
+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 {
// insertWBmove inserts the assignment *left = *right including a write barrier.
// t is the type being assigned.
// If right == nil, then we're zeroing *left.
-func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32, rightIsVolatile bool) {
+func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line src.Pos, rightIsVolatile bool) {
// if writeBarrier.enabled {
// typedmemmove(&t, left, right)
// } else {
// insertWBstore inserts the assignment *left = right including a write barrier.
// t is the type being assigned.
-func (s *state) insertWBstore(t *Type, left, right *ssa.Value, line int32, skip skipMask) {
+func (s *state) insertWBstore(t *Type, left, right *ssa.Value, line src.Pos, skip skipMask) {
// store scalar fields
// if writeBarrier.enabled {
// writebarrierptr for pointer fields
}
// SetLineno sets the current source line number.
-func (s *SSAGenState) SetLineno(l int32) {
+func (s *SSAGenState) SetLineno(l src.Pos) {
lineno = l
}
return canSSAType(t.(*Type))
}
-func (e *ssaExport) Line(line int32) string {
+func (e *ssaExport) Line(line src.Pos) string {
return linestr(line)
}
}
// Fatal reports a compiler error and exits.
-func (e *ssaExport) Fatalf(line int32, msg string, args ...interface{}) {
+func (e *ssaExport) Fatalf(line src.Pos, msg string, args ...interface{}) {
lineno = line
Fatalf(msg, args...)
}
// Warnl reports a "warning", which is usually flag-triggered
// logging output for the benefit of tests.
-func (e *ssaExport) Warnl(line int32, fmt_ string, args ...interface{}) {
+func (e *ssaExport) Warnl(line src.Pos, fmt_ string, args ...interface{}) {
Warnl(line, fmt_, args...)
}
import (
"bytes"
"cmd/internal/obj"
+ "cmd/internal/src"
"crypto/md5"
"encoding/binary"
"fmt"
)
type Error struct {
- lineno int32
+ lineno src.Pos
msg string
}
}
}
-func adderr(line int32, format string, args ...interface{}) {
+func adderr(line src.Pos, format string, args ...interface{}) {
errors = append(errors, Error{
lineno: line,
msg: fmt.Sprintf("%v: %s\n", linestr(line), fmt.Sprintf(format, args...)),
}
}
-func linestr(line int32) string {
+func linestr(line src.Pos) string {
return Ctxt.Line(int(line))
}
// It is used to avoid multiple error messages on the same
// line.
var lasterror struct {
- syntax int32 // line of last syntax error
- other int32 // line of last non-syntax error
- msg string // error message of last non-syntax error
+ syntax src.Pos // line of last syntax error
+ other src.Pos // line of last non-syntax error
+ msg string // error message of last non-syntax error
}
-func yyerrorl(line int32, format string, args ...interface{}) {
+func yyerrorl(line src.Pos, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
if strings.HasPrefix(msg, "syntax error") {
hcrash()
}
-func Warnl(line int32, fmt_ string, args ...interface{}) {
+func Warnl(line src.Pos, fmt_ string, args ...interface{}) {
adderr(line, fmt_, args...)
if Debug['m'] != 0 {
flusherrors()
Ctxt.LineHist.Update(int(lexlineno), file, off)
}
-func setlineno(n *Node) int32 {
+func setlineno(n *Node) src.Pos {
lno := lineno
if n != nil {
switch n.Op {
// Copies of iota ONONAME nodes are assigned the current
// value of iota_. If lineno != 0, it sets the line number
// of newly allocated nodes to lineno.
-func treecopy(n *Node, lineno int32) *Node {
+func treecopy(n *Node, lineno src.Pos) *Node {
if n == nil {
return nil
}
return et
}
-func listtreecopy(l []*Node, lineno int32) []*Node {
+func listtreecopy(l []*Node, lineno src.Pos) []*Node {
var out []*Node
for _, n := range l {
out = append(out, treecopy(n, lineno))
package gc
+import "cmd/internal/src"
+
// A Node is a single node in the syntax tree.
// Actually the syntax tree is a syntax DAG, because there is only one
// node with Op=ONAME for a given instance of a variable x.
// Possibly still more uses. If you find any, document them.
Xoffset int64
- Lineno int32
+ Lineno src.Pos
Esc uint16 // EscXXX
Label int32 // largest auto-generated label in this function
- Endlineno int32
- WBLineno int32 // line number of first write barrier
+ Endlineno src.Pos
+ WBLineno src.Pos // line number of first write barrier
Pragma Pragma // go:xxx function annotations
Dupok bool // duplicate definitions ok
import (
"cmd/compile/internal/ssa"
+ "cmd/internal/src"
"fmt"
)
sliceOf *Type
ptrTo *Type
- Sym *Sym // symbol containing name, for named types
- Vargen int32 // unique name for OTYPE/ONAME
- Lineno int32 // line at which this type was declared, implicitly or explicitly
+ Sym *Sym // symbol containing name, for named types
+ Vargen int32 // unique name for OTYPE/ONAME
+ Lineno src.Pos // line at which this type was declared, implicitly or explicitly
Etype EType // kind of type
Noalg bool // suppress hash and eq algorithm generation
// ForwardType contains Type fields specific to forward types.
type ForwardType struct {
Copyto []*Node // where to copy the eventual value to
- Embedlineno int32 // first use of this type as an embedded type
+ Embedlineno src.Pos // first use of this type as an embedded type
}
// ForwardType returns t's extra forward-type-specific fields.
import (
"cmd/internal/obj"
+ "cmd/internal/src"
"fmt"
"math"
"strings"
type mapqueueval struct {
n *Node
- lno int32
+ lno src.Pos
}
// tracks the line numbers at which forward types are first used as map keys
package ssa
-import "fmt"
+import (
+ "cmd/internal/src"
+ "fmt"
+)
// Block represents a basic block in the control flow graph of a function.
type Block struct {
ID ID
// Line number for block's control operation
- Line int32
+ Line src.Pos
// The kind of block this is.
Kind BlockKind
import (
"cmd/internal/obj"
+ "cmd/internal/src"
"crypto/sha1"
"fmt"
"os"
Log() bool
// Fatal reports a compiler error and exits.
- Fatalf(line int32, msg string, args ...interface{})
+ Fatalf(line src.Pos, msg string, args ...interface{})
// Warnl writes compiler messages in the form expected by "errorcheck" tests
- Warnl(line int32, fmt_ string, args ...interface{})
+ Warnl(line src.Pos, fmt_ string, args ...interface{})
// Fowards the Debug flags from gc
Debug_checknil() bool
SplitInt64(LocalSlot) (LocalSlot, LocalSlot) // returns (hi, lo)
// Line returns a string describing the given line number.
- Line(int32) string
+ Line(src.Pos) string
// AllocFrame assigns frame offsets to all live auto variables.
AllocFrame(f *Func)
return f
}
-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) 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) Debug_wb() bool { return c.fe.Debug_wb() }
+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 src.Pos, msg string, args ...interface{}) {
+ c.fe.Fatalf(line, msg, args...)
+}
+func (c *Config) Warnl(line src.Pos, msg string, args ...interface{}) { c.fe.Warnl(line, msg, args...) }
+func (c *Config) Debug_checknil() bool { return c.fe.Debug_checknil() }
+func (c *Config) Debug_wb() bool { return c.fe.Debug_wb() }
func (c *Config) logDebugHashMatch(evname, name string) {
file := c.logfiles[evname]
import (
"cmd/internal/obj"
"cmd/internal/obj/x86"
+ "cmd/internal/src"
"testing"
)
func (d DummyFrontend) SplitArray(s LocalSlot) LocalSlot {
return LocalSlot{s.N, s.Type.ElemType(), s.Off}
}
-func (DummyFrontend) Line(line int32) string {
+func (DummyFrontend) Line(_ src.Pos) string {
return "unknown.go:0"
}
func (DummyFrontend) AllocFrame(f *Func) {
func (d DummyFrontend) Logf(msg string, args ...interface{}) { d.t.Logf(msg, args...) }
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) Warnl(line int32, msg string, args ...interface{}) { d.t.Logf(msg, args...) }
-func (d DummyFrontend) Debug_checknil() bool { return false }
-func (d DummyFrontend) Debug_wb() bool { return false }
+func (d DummyFrontend) Fatalf(_ src.Pos, msg string, args ...interface{}) { d.t.Fatalf(msg, args...) }
+func (d DummyFrontend) Warnl(_ src.Pos, msg string, args ...interface{}) { d.t.Logf(msg, args...) }
+func (d DummyFrontend) Debug_checknil() bool { return false }
+func (d DummyFrontend) Debug_wb() bool { return false }
func (d DummyFrontend) TypeBool() Type { return TypeBool }
func (d DummyFrontend) TypeInt8() Type { return TypeInt8 }
package ssa
import (
+ "cmd/internal/src"
"fmt"
"math"
"strings"
}
// newValue allocates a new Value with the given fields and places it at the end of b.Values.
-func (f *Func) newValue(op Op, t Type, b *Block, line int32) *Value {
+func (f *Func) newValue(op Op, t Type, b *Block, line src.Pos) *Value {
var v *Value
if f.freeValues != nil {
v = f.freeValues
}
// NewValue0 returns a new value in the block with no arguments and zero aux values.
-func (b *Block) NewValue0(line int32, op Op, t Type) *Value {
+func (b *Block) NewValue0(line src.Pos, op Op, t Type) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = 0
v.Args = v.argstorage[:0]
}
// NewValue returns a new value in the block with no arguments and an auxint value.
-func (b *Block) NewValue0I(line int32, op Op, t Type, auxint int64) *Value {
+func (b *Block) NewValue0I(line src.Pos, op Op, t Type, auxint int64) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = auxint
v.Args = v.argstorage[:0]
}
// NewValue returns a new value in the block with no arguments and an aux value.
-func (b *Block) NewValue0A(line int32, op Op, t Type, aux interface{}) *Value {
+func (b *Block) NewValue0A(line src.Pos, op Op, t Type, aux interface{}) *Value {
if _, ok := aux.(int64); ok {
// Disallow int64 aux values. They should be in the auxint field instead.
// Maybe we want to allow this at some point, but for now we disallow it
}
// NewValue returns a new value in the block with no arguments and both an auxint and aux values.
-func (b *Block) NewValue0IA(line int32, op Op, t Type, auxint int64, aux interface{}) *Value {
+func (b *Block) NewValue0IA(line src.Pos, op Op, t Type, auxint int64, aux interface{}) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = auxint
v.Aux = aux
}
// NewValue1 returns a new value in the block with one argument and zero aux values.
-func (b *Block) NewValue1(line int32, op Op, t Type, arg *Value) *Value {
+func (b *Block) NewValue1(line src.Pos, op Op, t Type, arg *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = 0
v.Args = v.argstorage[:1]
}
// NewValue1I returns a new value in the block with one argument and an auxint value.
-func (b *Block) NewValue1I(line int32, op Op, t Type, auxint int64, arg *Value) *Value {
+func (b *Block) NewValue1I(line src.Pos, op Op, t Type, auxint int64, arg *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = auxint
v.Args = v.argstorage[:1]
}
// NewValue1A returns a new value in the block with one argument and an aux value.
-func (b *Block) NewValue1A(line int32, op Op, t Type, aux interface{}, arg *Value) *Value {
+func (b *Block) NewValue1A(line src.Pos, op Op, t Type, aux interface{}, arg *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = 0
v.Aux = aux
}
// NewValue1IA returns a new value in the block with one argument and both an auxint and aux values.
-func (b *Block) NewValue1IA(line int32, op Op, t Type, auxint int64, aux interface{}, arg *Value) *Value {
+func (b *Block) NewValue1IA(line src.Pos, op Op, t Type, auxint int64, aux interface{}, arg *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = auxint
v.Aux = aux
}
// NewValue2 returns a new value in the block with two arguments and zero aux values.
-func (b *Block) NewValue2(line int32, op Op, t Type, arg0, arg1 *Value) *Value {
+func (b *Block) NewValue2(line src.Pos, op Op, t Type, arg0, arg1 *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = 0
v.Args = v.argstorage[:2]
}
// NewValue2I returns a new value in the block with two arguments and an auxint value.
-func (b *Block) NewValue2I(line int32, op Op, t Type, auxint int64, arg0, arg1 *Value) *Value {
+func (b *Block) NewValue2I(line src.Pos, op Op, t Type, auxint int64, arg0, arg1 *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = auxint
v.Args = v.argstorage[:2]
}
// NewValue3 returns a new value in the block with three arguments and zero aux values.
-func (b *Block) NewValue3(line int32, op Op, t Type, arg0, arg1, arg2 *Value) *Value {
+func (b *Block) NewValue3(line src.Pos, op Op, t Type, arg0, arg1, arg2 *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = 0
v.Args = v.argstorage[:3]
}
// NewValue3I returns a new value in the block with three arguments and an auxint value.
-func (b *Block) NewValue3I(line int32, op Op, t Type, auxint int64, arg0, arg1, arg2 *Value) *Value {
+func (b *Block) NewValue3I(line src.Pos, op Op, t Type, auxint int64, arg0, arg1, arg2 *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = auxint
v.Args = v.argstorage[:3]
}
// NewValue4 returns a new value in the block with four arguments and zero aux values.
-func (b *Block) NewValue4(line int32, op Op, t Type, arg0, arg1, arg2, arg3 *Value) *Value {
+func (b *Block) NewValue4(line src.Pos, op Op, t Type, arg0, arg1, arg2, arg3 *Value) *Value {
v := b.Func.newValue(op, t, b, line)
v.AuxInt = 0
v.Args = []*Value{arg0, arg1, arg2, arg3}
}
// constVal returns a constant value for c.
-func (f *Func) constVal(line int32, op Op, t Type, c int64, setAux bool) *Value {
+func (f *Func) constVal(line src.Pos, op Op, t Type, c int64, setAux bool) *Value {
if f.constants == nil {
f.constants = make(map[int64][]*Value)
}
)
// ConstInt returns an int constant representing its argument.
-func (f *Func) ConstBool(line int32, t Type, c bool) *Value {
+func (f *Func) ConstBool(line src.Pos, t Type, c bool) *Value {
i := int64(0)
if c {
i = 1
}
return f.constVal(line, OpConstBool, t, i, true)
}
-func (f *Func) ConstInt8(line int32, t Type, c int8) *Value {
+func (f *Func) ConstInt8(line src.Pos, t Type, c int8) *Value {
return f.constVal(line, OpConst8, t, int64(c), true)
}
-func (f *Func) ConstInt16(line int32, t Type, c int16) *Value {
+func (f *Func) ConstInt16(line src.Pos, t Type, c int16) *Value {
return f.constVal(line, OpConst16, t, int64(c), true)
}
-func (f *Func) ConstInt32(line int32, t Type, c int32) *Value {
+func (f *Func) ConstInt32(line src.Pos, t Type, c int32) *Value {
return f.constVal(line, OpConst32, t, int64(c), true)
}
-func (f *Func) ConstInt64(line int32, t Type, c int64) *Value {
+func (f *Func) ConstInt64(line src.Pos, t Type, c int64) *Value {
return f.constVal(line, OpConst64, t, c, true)
}
-func (f *Func) ConstFloat32(line int32, t Type, c float64) *Value {
+func (f *Func) ConstFloat32(line src.Pos, t Type, c float64) *Value {
return f.constVal(line, OpConst32F, t, int64(math.Float64bits(float64(float32(c)))), true)
}
-func (f *Func) ConstFloat64(line int32, t Type, c float64) *Value {
+func (f *Func) ConstFloat64(line src.Pos, t Type, c float64) *Value {
return f.constVal(line, OpConst64F, t, int64(math.Float64bits(c)), true)
}
-func (f *Func) ConstSlice(line int32, t Type) *Value {
+func (f *Func) ConstSlice(line src.Pos, t Type) *Value {
return f.constVal(line, OpConstSlice, t, constSliceMagic, false)
}
-func (f *Func) ConstInterface(line int32, t Type) *Value {
+func (f *Func) ConstInterface(line src.Pos, t Type) *Value {
return f.constVal(line, OpConstInterface, t, constInterfaceMagic, false)
}
-func (f *Func) ConstNil(line int32, t Type) *Value {
+func (f *Func) ConstNil(line src.Pos, t Type) *Value {
return f.constVal(line, OpConstNil, t, constNilMagic, false)
}
-func (f *Func) ConstEmptyString(line int32, t Type) *Value {
+func (f *Func) ConstEmptyString(line src.Pos, t Type) *Value {
v := f.constVal(line, OpConstString, t, constEmptyStringMagic, false)
v.Aux = ""
return v
import (
"cmd/internal/obj"
+ "cmd/internal/src"
"fmt"
"unsafe"
)
}
type use struct {
- dist int32 // distance from start of the block to a use of a value
- line int32 // line number of the use
- next *use // linked list of uses of a value in nondecreasing dist order
+ dist int32 // distance from start of the block to a use of a value
+ line src.Pos // line number of the use
+ next *use // linked list of uses of a value in nondecreasing dist order
}
type valState struct {
type startReg struct {
r register
- vid ID // pre-regalloc value needed in this register
- line int32 // line number of use of this register
+ vid ID // pre-regalloc value needed in this register
+ line src.Pos // line number of use of this register
}
// freeReg frees up register r. Any current user of r is kicked out.
// allocated register is marked nospill so the assignment cannot be
// undone until the caller allows it by clearing nospill. Returns a
// *Value which is either v or a copy of v allocated to the chosen register.
-func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool, line int32) *Value {
+func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool, line src.Pos) *Value {
vi := &s.values[v.ID]
// Check if v is already in a requested register.
// Adds a use record for id at distance dist from the start of the block.
// All calls to addUse must happen with nonincreasing dist.
-func (s *regAllocState) addUse(id ID, dist int32, line int32) {
+func (s *regAllocState) addUse(id ID, dist int32, line src.Pos) {
r := s.freeUseRecords
if r != nil {
s.freeUseRecords = r.next
}
type contentRecord struct {
- vid ID // pre-regalloc value
- c *Value // cached value
- final bool // this is a satisfied destination
- line int32 // line number of use of the value
+ vid ID // pre-regalloc value
+ c *Value // cached value
+ final bool // this is a satisfied destination
+ line src.Pos // line number of use of the value
}
type dstRecord struct {
loc Location // register or stack slot
vid ID // pre-regalloc value it should contain
splice **Value // place to store reference to the generating instruction
- line int32 // line number of use of this location
+ line src.Pos // line number of use of this location
}
// setup initializes the edge state for shuffling.
// processDest generates code to put value vid into location loc. Returns true
// if progress was made.
-func (e *edgeState) processDest(loc Location, vid ID, splice **Value, line int32) bool {
+func (e *edgeState) processDest(loc Location, vid ID, splice **Value, line src.Pos) bool {
occupant := e.contents[loc]
if occupant.vid == vid {
// Value is already in the correct place.
}
// set changes the contents of location loc to hold the given value and its cached representative.
-func (e *edgeState) set(loc Location, vid ID, c *Value, final bool, line int32) {
+func (e *edgeState) set(loc Location, vid ID, c *Value, final bool, line src.Pos) {
e.s.f.setHome(c, loc)
e.erase(loc)
e.contents[loc] = contentRecord{vid, c, final, line}
}
type liveInfo struct {
- ID ID // ID of value
- dist int32 // # of instructions before next use
- line int32 // line number of next use
+ ID ID // ID of value
+ dist int32 // # of instructions before next use
+ line src.Pos // line number of next use
}
// dblock contains information about desired & avoid registers at the end of a block.
package ssa
+import "cmd/internal/src"
+
// from http://research.swtch.com/sparse
// in turn, from Briggs and Torczon
type sparseEntry struct {
key ID
val int32
- aux int32
+ aux src.Pos
}
type sparseMap struct {
return -1
}
-func (s *sparseMap) set(k ID, v, a int32) {
+func (s *sparseMap) set(k ID, v int32, a src.Pos) {
i := s.sparse[k]
if i < int32(len(s.dense)) && s.dense[i].key == k {
s.dense[i].val = v
package ssa
import (
+ "cmd/internal/src"
"fmt"
"math"
)
Block *Block
// Source line number
- Line int32
+ Line src.Pos
// Use count. Each appearance in Value.Args and Block.Control counts once.
Uses int32
package ssa
-import "fmt"
+import (
+ "cmd/internal/src"
+ "fmt"
+)
// writebarrier expands write barrier ops (StoreWB, MoveWB, etc.) into
// branches and runtime calls, like
// wbcall emits write barrier runtime call in b, returns memory.
// if valIsVolatile, it moves val into temp space before making the call.
-func wbcall(line int32, b *Block, fn interface{}, typ interface{}, ptr, val, mem, sp, sb *Value, valIsVolatile bool) *Value {
+func wbcall(line src.Pos, b *Block, fn interface{}, typ interface{}, ptr, val, mem, sp, sb *Value, valIsVolatile bool) *Value {
config := b.Func.Config
var tmp GCNode
"cmd/internal/obj/ppc64",
"cmd/internal/obj/s390x",
"cmd/internal/obj/x86",
+ "cmd/internal/src",
"cmd/internal/sys",
"cmd/link",
"cmd/link/internal/amd64",
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package src implements source positions.
+package src
+
+// 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