f.vid.put(v.ID)
}
}
- for j := i; j < len(b.Values); j++ {
- b.Values[j] = nil // aid GC
+ // aid GC
+ tail := b.Values[i:]
+ for j := range tail {
+ tail[j] = nil
}
b.Values = b.Values[:i]
}
f.bid.put(b.ID)
}
}
- // zero remainder to help gc
- for j := i; j < len(f.Blocks); j++ {
- f.Blocks[j] = nil
+ // zero remainder to help GC
+ tail := f.Blocks[i:]
+ for j := range tail {
+ tail[j] = nil
}
f.Blocks = f.Blocks[:i]
OpStoreFP
OpStoreSP
- // spill&restore ops for the register allocator. These are
+ // spill and restore ops for the register allocator. These are
// semantically identical to OpCopy - they do not take/return
// stores like regular memory ops do. We can get away with that because
// we know there is no aliasing to spill slots on the stack.
TypeFlags = &Flags{}
)
-// typeIdentical returns whether it two arguments are the same type.
+// typeIdentical reports whether its two arguments are the same type.
func typeIdentical(t, u Type) bool {
if t == TypeMem {
return u == TypeMem
// are a few other pseudo-types, see type.go.
Type Type
- // Auxiliary info for this value. The type of this information depends on the opcode (& type).
+ // Auxiliary info for this value. The type of this information depends on the opcode and type.
Aux interface{}
// Arguments of this value
}
func (v *Value) AddArg(w *Value) {
+ if v.Args == nil {
+ v.resetArgs() // use argstorage
+ }
v.Args = append(v.Args, w)
}
func (v *Value) AddArgs(a ...*Value) {
+ if v.Args == nil {
+ v.resetArgs() // use argstorage
+ }
v.Args = append(v.Args, a...)
}
func (v *Value) SetArg(i int, w *Value) {
}
func (v *Value) RemoveArg(i int) {
copy(v.Args[i:], v.Args[i+1:])
+ v.Args[len(v.Args)-1] = nil // aid GC
v.Args = v.Args[:len(v.Args)-1]
}
func (v *Value) SetArgs1(a *Value) {