go.tools/ssa: cosmetic changes to ssa.Alloc.
Remove its 'name' field and treat it just like any other ssa.Register: it gets a temp name like "t1". Instead, give it a comment field holding its purpose, e.g, "x" for a source-level vare, or "new", "slicelit", "complit" or "varargs". This improves usability of tools whose UI needs to refer to a particular allocation site. R=gri CC=golang-dev https://golang.org/cl/12273043
This commit is contained in:
parent
8d55039560
commit
5cc33ea5a7
|
|
@ -606,7 +606,7 @@ func NodeDescription(n ast.Node) string {
|
|||
case *ast.SwitchStmt:
|
||||
return "switch statement"
|
||||
case *ast.TypeAssertExpr:
|
||||
return "type assertioh"
|
||||
return "type assertion"
|
||||
case *ast.TypeSpec:
|
||||
return "type specification"
|
||||
case *ast.TypeSwitchStmt:
|
||||
|
|
|
|||
|
|
@ -303,7 +303,9 @@ func (b *builder) builtin(fn *Function, name string, args []ast.Expr, typ types.
|
|||
}
|
||||
|
||||
case "new":
|
||||
return emitNew(fn, deref(typ), pos)
|
||||
alloc := emitNew(fn, deref(typ), pos)
|
||||
alloc.Comment = "new"
|
||||
return alloc
|
||||
|
||||
case "len", "cap":
|
||||
// Special case: len or cap of an array or *array is
|
||||
|
|
@ -367,12 +369,13 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
|
|||
|
||||
case *ast.CompositeLit:
|
||||
t := deref(fn.Pkg.typeOf(e))
|
||||
var v Value
|
||||
var v *Alloc
|
||||
if escaping {
|
||||
v = emitNew(fn, t, e.Lbrace)
|
||||
} else {
|
||||
v = fn.addLocal(t, e.Lbrace)
|
||||
}
|
||||
v.Comment = "complit"
|
||||
b.compLit(fn, v, e, t) // initialize in place
|
||||
return &address{addr: v, expr: e}
|
||||
|
||||
|
|
@ -875,6 +878,7 @@ func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallEx
|
|||
at := types.NewArray(vt, int64(len(varargs)))
|
||||
// Don't set pos for implicit Allocs.
|
||||
a := emitNew(fn, at, token.NoPos)
|
||||
a.Comment = "varargs"
|
||||
for i, arg := range varargs {
|
||||
iaddr := &IndexAddr{
|
||||
X: a,
|
||||
|
|
@ -1186,7 +1190,9 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, typ typ
|
|||
switch t := t.(type) {
|
||||
case *types.Slice:
|
||||
at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts))
|
||||
array = emitNew(fn, at, e.Lbrace)
|
||||
alloc := emitNew(fn, at, e.Lbrace)
|
||||
alloc.Comment = "slicelit"
|
||||
array = alloc
|
||||
case *types.Array:
|
||||
at = t
|
||||
array = addr
|
||||
|
|
|
|||
12
ssa/emit.go
12
ssa/emit.go
|
|
@ -12,12 +12,12 @@ import (
|
|||
// emitNew emits to f a new (heap Alloc) instruction allocating an
|
||||
// object of type typ. pos is the optional source location.
|
||||
//
|
||||
func emitNew(f *Function, typ types.Type, pos token.Pos) Value {
|
||||
return f.emit(&Alloc{
|
||||
typ: types.NewPointer(typ),
|
||||
Heap: true,
|
||||
pos: pos,
|
||||
})
|
||||
func emitNew(f *Function, typ types.Type, pos token.Pos) *Alloc {
|
||||
v := &Alloc{Heap: true}
|
||||
v.setType(types.NewPointer(typ))
|
||||
v.setPos(pos)
|
||||
f.emit(v)
|
||||
return v
|
||||
}
|
||||
|
||||
// emitLoad emits to f an instruction to load the address addr into a
|
||||
|
|
|
|||
|
|
@ -97,11 +97,11 @@ func main() {
|
|||
// # Location: hello.go:8:6
|
||||
// func main():
|
||||
// .0.entry: P:0 S:0
|
||||
// a0 = new [1]interface{} *[1]interface{}
|
||||
// t0 = &a0[0:untyped integer] *interface{}
|
||||
// t1 = make interface{} <- string ("Hello, World!":string) interface{}
|
||||
// *t0 = t1
|
||||
// t2 = slice a0[:] []interface{}
|
||||
// t3 = fmt.Println(t2) (n int, err error)
|
||||
// t0 = new [1]interface{} (varargs) *[1]interface{}
|
||||
// t1 = &t0[0:untyped integer] *interface{}
|
||||
// t2 = make interface{} <- string ("Hello, World!":string) interface{}
|
||||
// *t1 = t2
|
||||
// t3 = slice t0[:] []interface{}
|
||||
// t4 = fmt.Println(t3) (n int, err error)
|
||||
// ret
|
||||
}
|
||||
|
|
|
|||
27
ssa/func.go
27
ssa/func.go
|
|
@ -195,11 +195,9 @@ func (f *Function) addParamObj(obj types.Object) *Parameter {
|
|||
//
|
||||
func (f *Function) addSpilledParam(obj types.Object) {
|
||||
param := f.addParamObj(obj)
|
||||
spill := &Alloc{
|
||||
name: obj.Name() + "~", // "~" means "spilled"
|
||||
typ: types.NewPointer(obj.Type()),
|
||||
pos: obj.Pos(),
|
||||
}
|
||||
spill := &Alloc{Comment: obj.Name()}
|
||||
spill.setType(types.NewPointer(obj.Type()))
|
||||
spill.setPos(obj.Pos())
|
||||
f.objects[obj] = spill
|
||||
f.Locals = append(f.Locals, spill)
|
||||
f.emit(spill)
|
||||
|
|
@ -266,21 +264,12 @@ func (f *Function) createSyntacticParams() {
|
|||
// numberRegisters assigns numbers to all SSA registers
|
||||
// (value-defining Instructions) in f, to aid debugging.
|
||||
// (Non-Instruction Values are named at construction.)
|
||||
// NB: named Allocs retain their existing name.
|
||||
// TODO(adonovan): when we have source position info,
|
||||
// preserve names only for source locals.
|
||||
//
|
||||
func numberRegisters(f *Function) {
|
||||
a, v := 0, 0
|
||||
v := 0
|
||||
for _, b := range f.Blocks {
|
||||
for _, instr := range b.Instrs {
|
||||
switch instr := instr.(type) {
|
||||
case *Alloc:
|
||||
// Allocs may be named at birth.
|
||||
if instr.name == "" {
|
||||
instr.name = fmt.Sprintf("a%d", a)
|
||||
a++
|
||||
}
|
||||
switch instr.(type) {
|
||||
case Value:
|
||||
instr.(interface {
|
||||
setNum(int)
|
||||
|
|
@ -396,7 +385,7 @@ func (f *Function) debugInfo() bool {
|
|||
//
|
||||
func (f *Function) addNamedLocal(obj types.Object) *Alloc {
|
||||
l := f.addLocal(obj.Type(), obj.Pos())
|
||||
l.name = obj.Name()
|
||||
l.Comment = obj.Name()
|
||||
f.objects[obj] = l
|
||||
return l
|
||||
}
|
||||
|
|
@ -409,7 +398,9 @@ func (f *Function) addLocalForIdent(id *ast.Ident) *Alloc {
|
|||
// to function f and returns it. pos is the optional source location.
|
||||
//
|
||||
func (f *Function) addLocal(typ types.Type, pos token.Pos) *Alloc {
|
||||
v := &Alloc{typ: types.NewPointer(typ), pos: pos}
|
||||
v := &Alloc{}
|
||||
v.setType(types.NewPointer(typ))
|
||||
v.setPos(pos)
|
||||
f.Locals = append(f.Locals, v)
|
||||
f.emit(v)
|
||||
return v
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func (v *Alloc) String() string {
|
|||
if v.Heap {
|
||||
op = "new"
|
||||
}
|
||||
return fmt.Sprintf("%s %s", op, deref(v.Type()))
|
||||
return fmt.Sprintf("%s %s (%s)", op, deref(v.Type()), v.Comment)
|
||||
}
|
||||
|
||||
func (v *Phi) String() string {
|
||||
|
|
|
|||
12
ssa/ssa.go
12
ssa/ssa.go
|
|
@ -437,13 +437,10 @@ type Builtin struct {
|
|||
// t1 = new int
|
||||
//
|
||||
type Alloc struct {
|
||||
anInstruction
|
||||
name string
|
||||
typ types.Type
|
||||
Heap bool
|
||||
pos token.Pos
|
||||
referrers []Instruction
|
||||
index int // dense numbering; for lifting
|
||||
Register
|
||||
Comment string
|
||||
Heap bool
|
||||
index int // dense numbering; for lifting
|
||||
}
|
||||
|
||||
// The Phi instruction represents an SSA φ-node, which combines values
|
||||
|
|
@ -1339,7 +1336,6 @@ func (v *Parameter) Pos() token.Pos { return v.pos }
|
|||
func (v *Parameter) Parent() *Function { return v.parent }
|
||||
|
||||
func (v *Alloc) Type() types.Type { return v.typ }
|
||||
func (v *Alloc) Name() string { return v.name }
|
||||
func (v *Alloc) Referrers() *[]Instruction { return &v.referrers }
|
||||
func (v *Alloc) Pos() token.Pos { return v.pos }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue