Commit 19447a66 authored by Todd Neal's avatar Todd Neal

[dev.ssa] cmd/compile: store floats in AuxInt

Store floats in AuxInt to reduce allocations.

Change-Id: I101e6322530b4a0b2ea3591593ad022c992e8df8
Reviewed-on: https://go-review.googlesource.com/14320Reviewed-by: default avatarDavid Chase <drchase@google.com>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 991036ae
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"html" "html"
"math"
"os" "os"
"strings" "strings"
...@@ -3006,7 +3007,7 @@ func genValue(v *ssa.Value) { ...@@ -3006,7 +3007,7 @@ func genValue(v *ssa.Value) {
x := regnum(v) x := regnum(v)
p := Prog(v.Op.Asm()) p := Prog(v.Op.Asm())
p.From.Type = obj.TYPE_FCONST p.From.Type = obj.TYPE_FCONST
p.From.Val = v.Aux.(float64) p.From.Val = math.Float64frombits(uint64(v.AuxInt))
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = x p.To.Reg = x
case ssa.OpAMD64MOVQload, ssa.OpAMD64MOVSSload, ssa.OpAMD64MOVSDload, ssa.OpAMD64MOVLload, ssa.OpAMD64MOVWload, ssa.OpAMD64MOVBload, ssa.OpAMD64MOVBQSXload, ssa.OpAMD64MOVBQZXload: case ssa.OpAMD64MOVQload, ssa.OpAMD64MOVSSload, ssa.OpAMD64MOVSDload, ssa.OpAMD64MOVLload, ssa.OpAMD64MOVWload, ssa.OpAMD64MOVBload, ssa.OpAMD64MOVBQSXload, ssa.OpAMD64MOVBQZXload:
......
...@@ -44,7 +44,6 @@ Optimizations (better compiler) ...@@ -44,7 +44,6 @@ Optimizations (better compiler)
- Reuseable slices (e.g. []int of size NumValues()) cached in Func - Reuseable slices (e.g. []int of size NumValues()) cached in Func
- Handle signed division overflow and sign extension earlier - Handle signed division overflow and sign extension earlier
- Implement 64 bit const division with high multiply, maybe in the frontend? - Implement 64 bit const division with high multiply, maybe in the frontend?
- Store bool and float32/float64 in auxInt
Regalloc Regalloc
-------- --------
......
...@@ -126,6 +126,13 @@ func checkFunc(f *Func) { ...@@ -126,6 +126,13 @@ func checkFunc(f *Func) {
if _, ok := v.Aux.(bool); ok { if _, ok := v.Aux.(bool); ok {
f.Fatalf("value %v has a bool Aux value, should be AuxInt", v.LongString()) f.Fatalf("value %v has a bool Aux value, should be AuxInt", v.LongString())
} }
if _, ok := v.Aux.(float32); ok {
f.Fatalf("value %v has a float32 Aux value, should be AuxInt", v.LongString())
}
if _, ok := v.Aux.(float64); ok {
f.Fatalf("value %v has a float64 Aux value, should be AuxInt", v.LongString())
}
for _, arg := range v.Args { for _, arg := range v.Args {
if arg == nil { if arg == nil {
......
...@@ -4,10 +4,7 @@ ...@@ -4,10 +4,7 @@
package ssa package ssa
import ( import "sort"
"math"
"sort"
)
// cse does common-subexpression elimination on the Function. // cse does common-subexpression elimination on the Function.
// Values are just relinked, nothing is deleted. A subsequent deadcode // Values are just relinked, nothing is deleted. A subsequent deadcode
...@@ -55,18 +52,11 @@ func cse(f *Func) { ...@@ -55,18 +52,11 @@ func cse(f *Func) {
arg1op = v.Args[1].Op arg1op = v.Args[1].Op
} }
aux := v.Aux // This assumes that floats are stored in AuxInt
auxInt := v.AuxInt // instead of Aux. If not, then we need to use the
// -0 == 0, but aren't equivalent values so we use // float bits as part of the key, otherwise since 0.0 == -0.0
// Float64bits to distinguish // this would incorrectly treat 0.0 and -0.0 as identical values
if f, ok := aux.(float64); ok { k := key{v.Op, v.Type.String(), v.Aux, v.AuxInt, len(v.Args), bid, arg0op, arg1op}
aux = nil
if auxInt != 0 {
v.Fatalf("float would clobber v.auxInt")
}
auxInt = int64(math.Float64bits(f))
}
k := key{v.Op, v.Type.String(), aux, auxInt, len(v.Args), bid, arg0op, arg1op}
m[k] = append(m[k], v) m[k] = append(m[k], v)
} }
} }
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package ssa package ssa
import "sync" import (
"math"
"sync"
)
// A Func represents a Go func declaration (or function literal) and // A Func represents a Go func declaration (or function literal) and
// its body. This package compiles each Func independently. // its body. This package compiles each Func independently.
...@@ -287,13 +290,11 @@ func (f *Func) ConstIntPtr(line int32, t Type, c int64) *Value { ...@@ -287,13 +290,11 @@ func (f *Func) ConstIntPtr(line int32, t Type, c int64) *Value {
} }
func (f *Func) ConstFloat32(line int32, t Type, c float64) *Value { func (f *Func) ConstFloat32(line int32, t Type, c float64) *Value {
// TODO: cache? // TODO: cache?
// For now stuff FP values into aux interface return f.Entry.NewValue0I(line, OpConst32F, t, int64(math.Float64bits(c)))
return f.Entry.NewValue0A(line, OpConst32F, t, c)
} }
func (f *Func) ConstFloat64(line int32, t Type, c float64) *Value { func (f *Func) ConstFloat64(line int32, t Type, c float64) *Value {
// TODO: cache? // TODO: cache?
// For now stuff FP values into aux interface return f.Entry.NewValue0I(line, OpConst64F, t, int64(math.Float64bits(c)))
return f.Entry.NewValue0A(line, OpConst64F, t, c)
} }
func (f *Func) Logf(msg string, args ...interface{}) { f.Config.Logf(msg, args...) } func (f *Func) Logf(msg string, args ...interface{}) { f.Config.Logf(msg, args...) }
......
...@@ -81,8 +81,8 @@ ...@@ -81,8 +81,8 @@
(Neg32 x) -> (NEGL x) (Neg32 x) -> (NEGL x)
(Neg16 x) -> (NEGW x) (Neg16 x) -> (NEGW x)
(Neg8 x) -> (NEGB x) (Neg8 x) -> (NEGB x)
(Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> {math.Copysign(0, -1)})) (Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
(Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> {math.Copysign(0, -1)})) (Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
(Com64 x) -> (NOTQ x) (Com64 x) -> (NOTQ x)
(Com32 x) -> (NOTL x) (Com32 x) -> (NOTL x)
...@@ -299,8 +299,8 @@ ...@@ -299,8 +299,8 @@
(Const16 [val]) -> (MOVWconst [val]) (Const16 [val]) -> (MOVWconst [val])
(Const32 [val]) -> (MOVLconst [val]) (Const32 [val]) -> (MOVLconst [val])
(Const64 [val]) -> (MOVQconst [val]) (Const64 [val]) -> (MOVQconst [val])
(Const32F {val}) -> (MOVSSconst {val}) (Const32F [val]) -> (MOVSSconst [val])
(Const64F {val}) -> (MOVSDconst {val}) (Const64F [val]) -> (MOVSDconst [val])
(ConstPtr [val]) -> (MOVQconst [val]) (ConstPtr [val]) -> (MOVQconst [val])
(ConstNil) -> (MOVQconst [0]) (ConstNil) -> (MOVQconst [0])
(ConstBool [b]) -> (MOVBconst [b]) (ConstBool [b]) -> (MOVBconst [b])
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package ssa package ssa
import "fmt" import (
"fmt"
"math"
)
func applyRewrite(f *Func, rb func(*Block) bool, rv func(*Value, *Config) bool) { func applyRewrite(f *Func, rb func(*Block) bool, rv func(*Value, *Config) bool) {
// repeat rewrites until we find no more rewrites // repeat rewrites until we find no more rewrites
...@@ -170,3 +173,8 @@ func b2i(b bool) int64 { ...@@ -170,3 +173,8 @@ func b2i(b bool) int64 {
} }
return 0 return 0
} }
// f2i is used in the rules for storing a float in AuxInt.
func f2i(f float64) int64 {
return int64(math.Float64bits(f))
}
...@@ -1560,20 +1560,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool { ...@@ -1560,20 +1560,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
enddae5807662af67143a3ac3ad9c63bae5: enddae5807662af67143a3ac3ad9c63bae5:
; ;
case OpConst32F: case OpConst32F:
// match: (Const32F {val}) // match: (Const32F [val])
// cond: // cond:
// result: (MOVSSconst {val}) // result: (MOVSSconst [val])
{ {
val := v.Aux val := v.AuxInt
v.Op = OpAMD64MOVSSconst v.Op = OpAMD64MOVSSconst
v.AuxInt = 0 v.AuxInt = 0
v.Aux = nil v.Aux = nil
v.resetArgs() v.resetArgs()
v.Aux = val v.AuxInt = val
return true return true
} }
goto end30a68b43982e55971cc58f893ae2c04a goto endfabcef2d57a8f36eaa6041de6f112b89
end30a68b43982e55971cc58f893ae2c04a: endfabcef2d57a8f36eaa6041de6f112b89:
; ;
case OpConst64: case OpConst64:
// match: (Const64 [val]) // match: (Const64 [val])
...@@ -1592,20 +1592,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool { ...@@ -1592,20 +1592,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
endc630434ae7f143ab69d5f482a9b52b5f: endc630434ae7f143ab69d5f482a9b52b5f:
; ;
case OpConst64F: case OpConst64F:
// match: (Const64F {val}) // match: (Const64F [val])
// cond: // cond:
// result: (MOVSDconst {val}) // result: (MOVSDconst [val])
{ {
val := v.Aux val := v.AuxInt
v.Op = OpAMD64MOVSDconst v.Op = OpAMD64MOVSDconst
v.AuxInt = 0 v.AuxInt = 0
v.Aux = nil v.Aux = nil
v.resetArgs() v.resetArgs()
v.Aux = val v.AuxInt = val
return true return true
} }
goto end958041a44a2ee8fc571cbc0832fad285 goto endae6cf7189e464bbde17b98635a20f0ff
end958041a44a2ee8fc571cbc0832fad285: endae6cf7189e464bbde17b98635a20f0ff:
; ;
case OpConst8: case OpConst8:
// match: (Const8 [val]) // match: (Const8 [val])
...@@ -6044,7 +6044,7 @@ func rewriteValueAMD64(v *Value, config *Config) bool { ...@@ -6044,7 +6044,7 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
case OpNeg32F: case OpNeg32F:
// match: (Neg32F x) // match: (Neg32F x)
// cond: // cond:
// result: (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> {math.Copysign(0, -1)})) // result: (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
{ {
x := v.Args[0] x := v.Args[0]
v.Op = OpAMD64PXOR v.Op = OpAMD64PXOR
...@@ -6054,12 +6054,12 @@ func rewriteValueAMD64(v *Value, config *Config) bool { ...@@ -6054,12 +6054,12 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
v.AddArg(x) v.AddArg(x)
v0 := b.NewValue0(v.Line, OpAMD64MOVSSconst, TypeInvalid) v0 := b.NewValue0(v.Line, OpAMD64MOVSSconst, TypeInvalid)
v0.Type = config.Frontend().TypeFloat32() v0.Type = config.Frontend().TypeFloat32()
v0.Aux = math.Copysign(0, -1) v0.AuxInt = f2i(math.Copysign(0, -1))
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
goto end47074133a76e069317ceca46372cafc3 goto end685a5fc899e195b9091afbe2a7146051
end47074133a76e069317ceca46372cafc3: end685a5fc899e195b9091afbe2a7146051:
; ;
case OpNeg64: case OpNeg64:
// match: (Neg64 x) // match: (Neg64 x)
...@@ -6080,7 +6080,7 @@ func rewriteValueAMD64(v *Value, config *Config) bool { ...@@ -6080,7 +6080,7 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
case OpNeg64F: case OpNeg64F:
// match: (Neg64F x) // match: (Neg64F x)
// cond: // cond:
// result: (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> {math.Copysign(0, -1)})) // result: (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
{ {
x := v.Args[0] x := v.Args[0]
v.Op = OpAMD64PXOR v.Op = OpAMD64PXOR
...@@ -6090,12 +6090,12 @@ func rewriteValueAMD64(v *Value, config *Config) bool { ...@@ -6090,12 +6090,12 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
v.AddArg(x) v.AddArg(x)
v0 := b.NewValue0(v.Line, OpAMD64MOVSDconst, TypeInvalid) v0 := b.NewValue0(v.Line, OpAMD64MOVSDconst, TypeInvalid)
v0.Type = config.Frontend().TypeFloat64() v0.Type = config.Frontend().TypeFloat64()
v0.Aux = math.Copysign(0, -1) v0.AuxInt = f2i(math.Copysign(0, -1))
v.AddArg(v0) v.AddArg(v0)
return true return true
} }
goto end9240202f5753ebd23f11f982ece3e06e goto ende85ae82b7a51e75000eb9158d584acb2
end9240202f5753ebd23f11f982ece3e06e: ende85ae82b7a51e75000eb9158d584acb2:
; ;
case OpNeg8: case OpNeg8:
// match: (Neg8 x) // match: (Neg8 x)
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package ssa package ssa
import "fmt" import (
"fmt"
"math"
)
// A Value represents a value in the SSA representation of the program. // A Value represents a value in the SSA representation of the program.
// The ID and Type fields must not be modified. The remainder may be modified // The ID and Type fields must not be modified. The remainder may be modified
...@@ -60,6 +63,15 @@ func (v *Value) LongString() string { ...@@ -60,6 +63,15 @@ func (v *Value) LongString() string {
s += " <" + v.Type.String() + ">" s += " <" + v.Type.String() + ">"
if v.AuxInt != 0 { if v.AuxInt != 0 {
s += fmt.Sprintf(" [%d]", v.AuxInt) s += fmt.Sprintf(" [%d]", v.AuxInt)
switch {
case v.Op == OpConst32F || v.Op == OpConst64F:
s += fmt.Sprintf("(%g)", math.Float64frombits(uint64(v.AuxInt)))
case v.Op == OpConstBool && v.AuxInt == 0:
s += " (false)"
case v.Op == OpConstBool && v.AuxInt == 1:
s += " (true)"
}
} }
if v.Aux != nil { if v.Aux != nil {
if _, ok := v.Aux.(string); ok { if _, ok := v.Aux.(string); ok {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment