mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[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:
parent
0ad9c8c720
commit
8f22b5292f
20 changed files with 756 additions and 1003 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue