[dev.ssa] cmd/compiler/internal/ssa: Add auxint field

Add an additional int64 auxiliary field to Value.

There are two main reasons for doing this:
1) Ints in interfaces require allocation, and we store ints in Aux a lot.
2) I'd like to have both *gc.Sym and int offsets included in lots
   of operations (e.g. MOVQloadidx8).  It will be more efficient to
   store them as separate fields instead of a pointer to a sym/int pair.

It also simplifies a bunch of code.

This is just the refactoring.  I'll start using this some more in a
subsequent changelist.

Change-Id: I1ca797ff572553986cf90cab3ac0a0c1d01ad241
Reviewed-on: https://go-review.googlesource.com/10929
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
Keith Randall 2015-06-11 21:29:25 -07:00
parent 0ad9c8c720
commit 8f22b5292f
20 changed files with 756 additions and 1003 deletions

View file

@ -4,6 +4,8 @@
package ssa
import "log"
// A Func represents a Go func declaration (or function literal) and
// its body. This package compiles each Func independently.
type Func struct {
@ -42,8 +44,41 @@ func (f *Func) NewBlock(kind BlockKind) *Block {
return b
}
// NewValue returns a new value in the block with no arguments.
func (b *Block) NewValue(line int32, op Op, t Type, aux interface{}) *Value {
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
Block: b,
}
v.Args = v.argstorage[:0]
b.Values = append(b.Values, v)
return v
}
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
AuxInt: auxint,
Block: b,
}
v.Args = v.argstorage[:0]
b.Values = append(b.Values, v)
return v
}
// 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 {
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
// to prevent errors like using NewValue1A instead of NewValue1I.
log.Fatalf("aux field has int64 type op=%s type=%s aux=%v", op, t, aux)
}
v := &Value{
ID: b.Func.vid.get(),
Op: op,
@ -56,8 +91,52 @@ func (b *Block) NewValue(line int32, op Op, t Type, aux interface{}) *Value {
return v
}
// NewValue1 returns a new value in the block with one argument.
func (b *Block) NewValue1(line int32, op Op, t Type, aux interface{}, arg *Value) *Value {
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
AuxInt: auxint,
Aux: aux,
Block: b,
}
v.Args = v.argstorage[:0]
b.Values = append(b.Values, v)
return v
}
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
Block: b,
}
v.Args = v.argstorage[:1]
v.Args[0] = arg
b.Values = append(b.Values, v)
return v
}
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
AuxInt: auxint,
Block: b,
}
v.Args = v.argstorage[:1]
v.Args[0] = arg
b.Values = append(b.Values, v)
return v
}
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
@ -71,13 +150,28 @@ func (b *Block) NewValue1(line int32, op Op, t Type, aux interface{}, arg *Value
return v
}
// NewValue2 returns a new value in the block with two arguments.
func (b *Block) NewValue2(line int32, op Op, t Type, aux interface{}, arg0, arg1 *Value) *Value {
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
AuxInt: auxint,
Aux: aux,
Block: b,
}
v.Args = v.argstorage[:1]
v.Args[0] = arg
b.Values = append(b.Values, v)
return v
}
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
Aux: aux,
Block: b,
}
v.Args = v.argstorage[:2]
@ -87,13 +181,12 @@ func (b *Block) NewValue2(line int32, op Op, t Type, aux interface{}, arg0, arg1
return v
}
// NewValue3 returns a new value in the block with three arguments.
func (b *Block) NewValue3(line int32, op Op, t Type, aux interface{}, arg0, arg1, arg2 *Value) *Value {
// 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 {
v := &Value{
ID: b.Func.vid.get(),
Op: op,
Type: t,
Aux: aux,
Block: b,
}
v.Args = []*Value{arg0, arg1, arg2}
@ -104,5 +197,5 @@ func (b *Block) NewValue3(line int32, op Op, t Type, aux interface{}, arg0, arg1
// ConstInt returns an int constant representing its argument.
func (f *Func) ConstInt(line int32, t Type, c int64) *Value {
// TODO: cache?
return f.Entry.NewValue(line, OpConst, t, c)
return f.Entry.NewValue0I(line, OpConst, t, c)
}