]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: store floats in AuxInt
authorTodd Neal <todd@tneal.org>
Fri, 4 Sep 2015 11:33:56 +0000 (06:33 -0500)
committerTodd Neal <todd@tneal.org>
Fri, 4 Sep 2015 15:15:21 +0000 (15:15 +0000)
Store floats in AuxInt to reduce allocations.

Change-Id: I101e6322530b4a0b2ea3591593ad022c992e8df8
Reviewed-on: https://go-review.googlesource.com/14320
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/TODO
src/cmd/compile/internal/ssa/check.go
src/cmd/compile/internal/ssa/cse.go
src/cmd/compile/internal/ssa/func.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/rewrite.go
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssa/value.go

index 340b7daa5292797e4453943db975e8a5ae128766..ac8888e14d04393c434f58a063a83a0c0e2025aa 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bytes"
        "fmt"
        "html"
+       "math"
        "os"
        "strings"
 
@@ -3006,7 +3007,7 @@ func genValue(v *ssa.Value) {
                x := regnum(v)
                p := Prog(v.Op.Asm())
                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.Reg = x
        case ssa.OpAMD64MOVQload, ssa.OpAMD64MOVSSload, ssa.OpAMD64MOVSDload, ssa.OpAMD64MOVLload, ssa.OpAMD64MOVWload, ssa.OpAMD64MOVBload, ssa.OpAMD64MOVBQSXload, ssa.OpAMD64MOVBQZXload:
index 8feb1053ae64ce669fb71c4342238b3b30df1b62..fbe4f56760b25477cd5702f8070ccef07ec1cf58 100644 (file)
@@ -44,7 +44,6 @@ Optimizations (better compiler)
 - Reuseable slices (e.g. []int of size NumValues()) cached in Func
 - Handle signed division overflow and sign extension earlier
 - Implement 64 bit const division with high multiply, maybe in the frontend?
-- Store bool and float32/float64 in auxInt
 
 Regalloc
 --------
index a7249a4c54f2dd24a12a4f6956d442f8a97943a0..710b7609c628135b55b9b1b0c50f8659d3b95d76 100644 (file)
@@ -126,6 +126,13 @@ func checkFunc(f *Func) {
                        if _, ok := v.Aux.(bool); ok {
                                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 {
                                if arg == nil {
index 6469ecd72b9f096546f1e457a73fcc988b4ea178..836a7803acb53b5fff80c62d059819608a1c50b9 100644 (file)
@@ -4,10 +4,7 @@
 
 package ssa
 
-import (
-       "math"
-       "sort"
-)
+import "sort"
 
 // cse does common-subexpression elimination on the Function.
 // Values are just relinked, nothing is deleted.  A subsequent deadcode
@@ -55,18 +52,11 @@ func cse(f *Func) {
                                arg1op = v.Args[1].Op
                        }
 
-                       aux := v.Aux
-                       auxInt := v.AuxInt
-                       // -0 == 0, but aren't equivalent values so we use
-                       // Float64bits to distinguish
-                       if f, ok := aux.(float64); ok {
-                               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}
+                       // This assumes that floats are stored in AuxInt
+                       // instead of Aux. If not, then we need to use the
+                       // float bits as part of the key, otherwise since 0.0 == -0.0
+                       // this would incorrectly treat 0.0 and -0.0 as identical values
+                       k := key{v.Op, v.Type.String(), v.Aux, v.AuxInt, len(v.Args), bid, arg0op, arg1op}
                        m[k] = append(m[k], v)
                }
        }
index 09bfff2bfc0de3a853c5ba5cdd76866296dfd1b0..747a5c7f03e0876b21461039e083d56aa2ad0039 100644 (file)
@@ -4,7 +4,10 @@
 
 package ssa
 
-import "sync"
+import (
+       "math"
+       "sync"
+)
 
 // A Func represents a Go func declaration (or function literal) and
 // its body.  This package compiles each Func independently.
@@ -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 {
        // TODO: cache?
-       // For now stuff FP values into aux interface
-       return f.Entry.NewValue0A(line, OpConst32F, t, c)
+       return f.Entry.NewValue0I(line, OpConst32F, t, int64(math.Float64bits(c)))
 }
 func (f *Func) ConstFloat64(line int32, t Type, c float64) *Value {
        // TODO: cache?
-       // For now stuff FP values into aux interface
-       return f.Entry.NewValue0A(line, OpConst64F, t, c)
+       return f.Entry.NewValue0I(line, OpConst64F, t, int64(math.Float64bits(c)))
 }
 
 func (f *Func) Logf(msg string, args ...interface{})           { f.Config.Logf(msg, args...) }
index 8e1a8a09b1798bdb4528bbb99765f27e61c69a43..16bd1df84b6b4b54023ae7b6276e83cd3b782a40 100644 (file)
@@ -81,8 +81,8 @@
 (Neg32 x) -> (NEGL x)
 (Neg16 x) -> (NEGW x)
 (Neg8 x) -> (NEGB x)
-(Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> {math.Copysign(0, -1)}))
-(Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> {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()> [f2i(math.Copysign(0, -1))]))
 
 (Com64 x) -> (NOTQ x)
 (Com32 x) -> (NOTL x)
 (Const16 [val]) -> (MOVWconst [val])
 (Const32 [val]) -> (MOVLconst [val])
 (Const64 [val]) -> (MOVQconst [val])
-(Const32F {val}) -> (MOVSSconst {val})
-(Const64F {val}) -> (MOVSDconst {val})
+(Const32F [val]) -> (MOVSSconst [val])
+(Const64F [val]) -> (MOVSDconst [val])
 (ConstPtr [val]) -> (MOVQconst [val])
 (ConstNil) -> (MOVQconst [0])
 (ConstBool [b]) -> (MOVBconst [b])
index 2742a5cc3bebaf01da014446d4418828e7b077e7..5c47ec66601fac67769cab4771f29ad5512456fd 100644 (file)
@@ -4,7 +4,10 @@
 
 package ssa
 
-import "fmt"
+import (
+       "fmt"
+       "math"
+)
 
 func applyRewrite(f *Func, rb func(*Block) bool, rv func(*Value, *Config) bool) {
        // repeat rewrites until we find no more rewrites
@@ -170,3 +173,8 @@ func b2i(b bool) int64 {
        }
        return 0
 }
+
+// f2i is used in the rules for storing a float in AuxInt.
+func f2i(f float64) int64 {
+       return int64(math.Float64bits(f))
+}
index f449892a8ac87e0687f89099e0f9c3d89a557012..8ad939ead97dcd75bdecee3af4ea3e817580cd2e 100644 (file)
@@ -1560,20 +1560,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
        enddae5807662af67143a3ac3ad9c63bae5:
                ;
        case OpConst32F:
-               // match: (Const32F {val})
+               // match: (Const32F [val])
                // cond:
-               // result: (MOVSSconst {val})
+               // result: (MOVSSconst [val])
                {
-                       val := v.Aux
+                       val := v.AuxInt
                        v.Op = OpAMD64MOVSSconst
                        v.AuxInt = 0
                        v.Aux = nil
                        v.resetArgs()
-                       v.Aux = val
+                       v.AuxInt = val
                        return true
                }
-               goto end30a68b43982e55971cc58f893ae2c04a
-       end30a68b43982e55971cc58f893ae2c04a:
+               goto endfabcef2d57a8f36eaa6041de6f112b89
+       endfabcef2d57a8f36eaa6041de6f112b89:
                ;
        case OpConst64:
                // match: (Const64 [val])
@@ -1592,20 +1592,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
        endc630434ae7f143ab69d5f482a9b52b5f:
                ;
        case OpConst64F:
-               // match: (Const64F {val})
+               // match: (Const64F [val])
                // cond:
-               // result: (MOVSDconst {val})
+               // result: (MOVSDconst [val])
                {
-                       val := v.Aux
+                       val := v.AuxInt
                        v.Op = OpAMD64MOVSDconst
                        v.AuxInt = 0
                        v.Aux = nil
                        v.resetArgs()
-                       v.Aux = val
+                       v.AuxInt = val
                        return true
                }
-               goto end958041a44a2ee8fc571cbc0832fad285
-       end958041a44a2ee8fc571cbc0832fad285:
+               goto endae6cf7189e464bbde17b98635a20f0ff
+       endae6cf7189e464bbde17b98635a20f0ff:
                ;
        case OpConst8:
                // match: (Const8 [val])
@@ -6044,7 +6044,7 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
        case OpNeg32F:
                // match: (Neg32F x)
                // 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]
                        v.Op = OpAMD64PXOR
@@ -6054,12 +6054,12 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
                        v.AddArg(x)
                        v0 := b.NewValue0(v.Line, OpAMD64MOVSSconst, TypeInvalid)
                        v0.Type = config.Frontend().TypeFloat32()
-                       v0.Aux = math.Copysign(0, -1)
+                       v0.AuxInt = f2i(math.Copysign(0, -1))
                        v.AddArg(v0)
                        return true
                }
-               goto end47074133a76e069317ceca46372cafc3
-       end47074133a76e069317ceca46372cafc3:
+               goto end685a5fc899e195b9091afbe2a7146051
+       end685a5fc899e195b9091afbe2a7146051:
                ;
        case OpNeg64:
                // match: (Neg64 x)
@@ -6080,7 +6080,7 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
        case OpNeg64F:
                // match: (Neg64F x)
                // 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]
                        v.Op = OpAMD64PXOR
@@ -6090,12 +6090,12 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
                        v.AddArg(x)
                        v0 := b.NewValue0(v.Line, OpAMD64MOVSDconst, TypeInvalid)
                        v0.Type = config.Frontend().TypeFloat64()
-                       v0.Aux = math.Copysign(0, -1)
+                       v0.AuxInt = f2i(math.Copysign(0, -1))
                        v.AddArg(v0)
                        return true
                }
-               goto end9240202f5753ebd23f11f982ece3e06e
-       end9240202f5753ebd23f11f982ece3e06e:
+               goto ende85ae82b7a51e75000eb9158d584acb2
+       ende85ae82b7a51e75000eb9158d584acb2:
                ;
        case OpNeg8:
                // match: (Neg8 x)
index 04ea17cce914823a0c2ea7aa6591da58f69a1d87..d213b72df3275c76e31d7f63e1496ec494c241e0 100644 (file)
@@ -4,7 +4,10 @@
 
 package ssa
 
-import "fmt"
+import (
+       "fmt"
+       "math"
+)
 
 // 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
@@ -60,6 +63,15 @@ func (v *Value) LongString() string {
        s += " <" + v.Type.String() + ">"
        if v.AuxInt != 0 {
                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 _, ok := v.Aux.(string); ok {