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:
Alan Donovan 2013-08-01 14:06:10 -04:00
parent 8d55039560
commit 5cc33ea5a7
7 changed files with 36 additions and 43 deletions

View File

@ -606,7 +606,7 @@ func NodeDescription(n ast.Node) string {
case *ast.SwitchStmt: case *ast.SwitchStmt:
return "switch statement" return "switch statement"
case *ast.TypeAssertExpr: case *ast.TypeAssertExpr:
return "type assertioh" return "type assertion"
case *ast.TypeSpec: case *ast.TypeSpec:
return "type specification" return "type specification"
case *ast.TypeSwitchStmt: case *ast.TypeSwitchStmt:

View File

@ -303,7 +303,9 @@ func (b *builder) builtin(fn *Function, name string, args []ast.Expr, typ types.
} }
case "new": case "new":
return emitNew(fn, deref(typ), pos) alloc := emitNew(fn, deref(typ), pos)
alloc.Comment = "new"
return alloc
case "len", "cap": case "len", "cap":
// Special case: len or cap of an array or *array is // 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: case *ast.CompositeLit:
t := deref(fn.Pkg.typeOf(e)) t := deref(fn.Pkg.typeOf(e))
var v Value var v *Alloc
if escaping { if escaping {
v = emitNew(fn, t, e.Lbrace) v = emitNew(fn, t, e.Lbrace)
} else { } else {
v = fn.addLocal(t, e.Lbrace) v = fn.addLocal(t, e.Lbrace)
} }
v.Comment = "complit"
b.compLit(fn, v, e, t) // initialize in place b.compLit(fn, v, e, t) // initialize in place
return &address{addr: v, expr: e} 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))) at := types.NewArray(vt, int64(len(varargs)))
// Don't set pos for implicit Allocs. // Don't set pos for implicit Allocs.
a := emitNew(fn, at, token.NoPos) a := emitNew(fn, at, token.NoPos)
a.Comment = "varargs"
for i, arg := range varargs { for i, arg := range varargs {
iaddr := &IndexAddr{ iaddr := &IndexAddr{
X: a, X: a,
@ -1186,7 +1190,9 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, typ typ
switch t := t.(type) { switch t := t.(type) {
case *types.Slice: case *types.Slice:
at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts)) 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: case *types.Array:
at = t at = t
array = addr array = addr

View File

@ -12,12 +12,12 @@ import (
// emitNew emits to f a new (heap Alloc) instruction allocating an // emitNew emits to f a new (heap Alloc) instruction allocating an
// object of type typ. pos is the optional source location. // object of type typ. pos is the optional source location.
// //
func emitNew(f *Function, typ types.Type, pos token.Pos) Value { func emitNew(f *Function, typ types.Type, pos token.Pos) *Alloc {
return f.emit(&Alloc{ v := &Alloc{Heap: true}
typ: types.NewPointer(typ), v.setType(types.NewPointer(typ))
Heap: true, v.setPos(pos)
pos: pos, f.emit(v)
}) return v
} }
// emitLoad emits to f an instruction to load the address addr into a // emitLoad emits to f an instruction to load the address addr into a

View File

@ -97,11 +97,11 @@ func main() {
// # Location: hello.go:8:6 // # Location: hello.go:8:6
// func main(): // func main():
// .0.entry: P:0 S:0 // .0.entry: P:0 S:0
// a0 = new [1]interface{} *[1]interface{} // t0 = new [1]interface{} (varargs) *[1]interface{}
// t0 = &a0[0:untyped integer] *interface{} // t1 = &t0[0:untyped integer] *interface{}
// t1 = make interface{} <- string ("Hello, World!":string) interface{} // t2 = make interface{} <- string ("Hello, World!":string) interface{}
// *t0 = t1 // *t1 = t2
// t2 = slice a0[:] []interface{} // t3 = slice t0[:] []interface{}
// t3 = fmt.Println(t2) (n int, err error) // t4 = fmt.Println(t3) (n int, err error)
// ret // ret
} }

View File

@ -195,11 +195,9 @@ func (f *Function) addParamObj(obj types.Object) *Parameter {
// //
func (f *Function) addSpilledParam(obj types.Object) { func (f *Function) addSpilledParam(obj types.Object) {
param := f.addParamObj(obj) param := f.addParamObj(obj)
spill := &Alloc{ spill := &Alloc{Comment: obj.Name()}
name: obj.Name() + "~", // "~" means "spilled" spill.setType(types.NewPointer(obj.Type()))
typ: types.NewPointer(obj.Type()), spill.setPos(obj.Pos())
pos: obj.Pos(),
}
f.objects[obj] = spill f.objects[obj] = spill
f.Locals = append(f.Locals, spill) f.Locals = append(f.Locals, spill)
f.emit(spill) f.emit(spill)
@ -266,21 +264,12 @@ func (f *Function) createSyntacticParams() {
// numberRegisters assigns numbers to all SSA registers // numberRegisters assigns numbers to all SSA registers
// (value-defining Instructions) in f, to aid debugging. // (value-defining Instructions) in f, to aid debugging.
// (Non-Instruction Values are named at construction.) // (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) { func numberRegisters(f *Function) {
a, v := 0, 0 v := 0
for _, b := range f.Blocks { for _, b := range f.Blocks {
for _, instr := range b.Instrs { for _, instr := range b.Instrs {
switch instr := instr.(type) { switch instr.(type) {
case *Alloc:
// Allocs may be named at birth.
if instr.name == "" {
instr.name = fmt.Sprintf("a%d", a)
a++
}
case Value: case Value:
instr.(interface { instr.(interface {
setNum(int) setNum(int)
@ -396,7 +385,7 @@ func (f *Function) debugInfo() bool {
// //
func (f *Function) addNamedLocal(obj types.Object) *Alloc { func (f *Function) addNamedLocal(obj types.Object) *Alloc {
l := f.addLocal(obj.Type(), obj.Pos()) l := f.addLocal(obj.Type(), obj.Pos())
l.name = obj.Name() l.Comment = obj.Name()
f.objects[obj] = l f.objects[obj] = l
return 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. // to function f and returns it. pos is the optional source location.
// //
func (f *Function) addLocal(typ types.Type, pos token.Pos) *Alloc { 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.Locals = append(f.Locals, v)
f.emit(v) f.emit(v)
return v return v

View File

@ -77,7 +77,7 @@ func (v *Alloc) String() string {
if v.Heap { if v.Heap {
op = "new" 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 { func (v *Phi) String() string {

View File

@ -437,13 +437,10 @@ type Builtin struct {
// t1 = new int // t1 = new int
// //
type Alloc struct { type Alloc struct {
anInstruction Register
name string Comment string
typ types.Type Heap bool
Heap bool index int // dense numbering; for lifting
pos token.Pos
referrers []Instruction
index int // dense numbering; for lifting
} }
// The Phi instruction represents an SSA φ-node, which combines values // 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 *Parameter) Parent() *Function { return v.parent }
func (v *Alloc) Type() types.Type { return v.typ } 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) Referrers() *[]Instruction { return &v.referrers }
func (v *Alloc) Pos() token.Pos { return v.pos } func (v *Alloc) Pos() token.Pos { return v.pos }