Commit 991036ae authored by Todd Neal's avatar Todd Neal

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

Store bools in AuxInt to reduce allocations.

Change-Id: Ibd26db67fca5e1e2803f53d7ef094897968b704b
Reviewed-on: https://go-review.googlesource.com/14276Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent d9f2cafb
......@@ -302,6 +302,11 @@ func (s *state) newValue0A(op ssa.Op, t ssa.Type, aux interface{}) *ssa.Value {
return s.curBlock.NewValue0A(s.peekLine(), op, t, aux)
}
// newValue0I adds a new value with no arguments and an auxint value to the current block.
func (s *state) newValue0I(op ssa.Op, t ssa.Type, auxint int64) *ssa.Value {
return s.curBlock.NewValue0I(s.peekLine(), op, t, auxint)
}
// newValue1 adds a new value with one argument to the current block.
func (s *state) newValue1(op ssa.Op, t ssa.Type, arg *ssa.Value) *ssa.Value {
return s.curBlock.NewValue1(s.peekLine(), op, t, arg)
......@@ -337,16 +342,21 @@ func (s *state) newValue3I(op ssa.Op, t ssa.Type, aux int64, arg0, arg1, arg2 *s
return s.curBlock.NewValue3I(s.peekLine(), op, t, aux, arg0, arg1, arg2)
}
// entryNewValue adds a new value with no arguments to the entry block.
// entryNewValue0 adds a new value with no arguments to the entry block.
func (s *state) entryNewValue0(op ssa.Op, t ssa.Type) *ssa.Value {
return s.f.Entry.NewValue0(s.peekLine(), op, t)
}
// entryNewValue adds a new value with no arguments and an aux value to the entry block.
// entryNewValue0A adds a new value with no arguments and an aux value to the entry block.
func (s *state) entryNewValue0A(op ssa.Op, t ssa.Type, aux interface{}) *ssa.Value {
return s.f.Entry.NewValue0A(s.peekLine(), op, t, aux)
}
// entryNewValue0I adds a new value with no arguments and an auxint value to the entry block.
func (s *state) entryNewValue0I(op ssa.Op, t ssa.Type, auxint int64) *ssa.Value {
return s.f.Entry.NewValue0I(s.peekLine(), op, t, auxint)
}
// entryNewValue1 adds a new value with one argument to the entry block.
func (s *state) entryNewValue1(op ssa.Op, t ssa.Type, arg *ssa.Value) *ssa.Value {
return s.f.Entry.NewValue1(s.peekLine(), op, t, arg)
......@@ -635,7 +645,7 @@ func (s *state) stmt(n *Node) {
if n.Left != nil {
cond = s.expr(n.Left)
} else {
cond = s.entryNewValue0A(ssa.OpConstBool, Types[TBOOL], true)
cond = s.entryNewValue0I(ssa.OpConstBool, Types[TBOOL], 1) // 1 = true
}
b = s.endBlock()
b.Kind = ssa.BlockIf
......@@ -1103,7 +1113,11 @@ func (s *state) expr(n *Node) *ssa.Value {
case CTSTR:
return s.entryNewValue0A(ssa.OpConstString, n.Type, n.Val().U)
case CTBOOL:
return s.entryNewValue0A(ssa.OpConstBool, n.Type, n.Val().U)
if n.Val().U.(bool) {
return s.entryNewValue0I(ssa.OpConstBool, n.Type, 1) // 1 = true
} else {
return s.entryNewValue0I(ssa.OpConstBool, n.Type, 0) // 0 = false
}
case CTNIL:
t := n.Type
switch {
......@@ -1882,7 +1896,7 @@ func (s *state) zeroVal(t *Type) *ssa.Value {
case t.IsPtr():
return s.entryNewValue0(ssa.OpConstNil, t)
case t.IsBoolean():
return s.entryNewValue0A(ssa.OpConstBool, t, false) // TODO: store bools as 0/1 in AuxInt?
return s.entryNewValue0I(ssa.OpConstBool, t, 0) // 0 = false
case t.IsInterface():
return s.entryNewValue0(ssa.OpConstInterface, t)
case t.IsSlice():
......
......@@ -122,6 +122,11 @@ func checkFunc(f *Func) {
}
for _, v := range b.Values {
if _, ok := v.Aux.(bool); ok {
f.Fatalf("value %v has a bool Aux value, should be AuxInt", v.LongString())
}
for _, arg := range v.Args {
if arg == nil {
f.Fatalf("value %v has nil arg", v.LongString())
......
......@@ -17,7 +17,7 @@ func TestDeadLoop(t *testing.T) {
// dead loop
Bloc("deadblock",
// dead value in dead block
Valu("deadval", OpConstBool, TypeBool, 0, true),
Valu("deadval", OpConstBool, TypeBool, 1, nil),
If("deadval", "deadblock", "exit")))
CheckFunc(fun.f)
......@@ -63,7 +63,7 @@ func TestNeverTaken(t *testing.T) {
c := testConfig(t)
fun := Fun(c, "entry",
Bloc("entry",
Valu("cond", OpConstBool, TypeBool, 0, false),
Valu("cond", OpConstBool, TypeBool, 0, nil),
Valu("mem", OpArg, TypeMem, 0, ".mem"),
If("cond", "then", "else")),
Bloc("then",
......@@ -99,7 +99,7 @@ func TestNestedDeadBlocks(t *testing.T) {
fun := Fun(c, "entry",
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("cond", OpConstBool, TypeBool, 0, false),
Valu("cond", OpConstBool, TypeBool, 0, nil),
If("cond", "b2", "b4")),
Bloc("b2",
If("cond", "b3", "b4")),
......
......@@ -14,7 +14,7 @@ func TestDeadStore(t *testing.T) {
Bloc("entry",
Valu("start", OpArg, TypeMem, 0, ".mem"),
Valu("sb", OpSB, TypeInvalid, 0, nil),
Valu("v", OpConstBool, TypeBool, 0, true),
Valu("v", OpConstBool, TypeBool, 1, nil),
Valu("addr1", OpAddr, ptrType, 0, nil, "sb"),
Valu("addr2", OpAddr, ptrType, 0, nil, "sb"),
Valu("addr3", OpAddr, ptrType, 0, nil, "sb"),
......@@ -49,7 +49,7 @@ func TestDeadStorePhi(t *testing.T) {
Bloc("entry",
Valu("start", OpArg, TypeMem, 0, ".mem"),
Valu("sb", OpSB, TypeInvalid, 0, nil),
Valu("v", OpConstBool, TypeBool, 0, true),
Valu("v", OpConstBool, TypeBool, 1, nil),
Valu("addr", OpAddr, ptrType, 0, nil, "sb"),
Goto("loop")),
Bloc("loop",
......@@ -76,7 +76,7 @@ func TestDeadStoreTypes(t *testing.T) {
Bloc("entry",
Valu("start", OpArg, TypeMem, 0, ".mem"),
Valu("sb", OpSB, TypeInvalid, 0, nil),
Valu("v", OpConstBool, TypeBool, 0, true),
Valu("v", OpConstBool, TypeBool, 1, nil),
Valu("addr1", OpAddr, t1, 0, nil, "sb"),
Valu("addr2", OpAddr, t2, 0, nil, "sb"),
Valu("store1", OpStore, TypeMem, 1, nil, "addr1", "v", "start"),
......
......@@ -44,7 +44,7 @@ func genFwdBack(size int) []bloc {
blocs = append(blocs,
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
Goto(blockn(0)),
),
)
......@@ -74,7 +74,7 @@ func genManyPred(size int) []bloc {
blocs = append(blocs,
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
Goto(blockn(0)),
),
)
......@@ -85,15 +85,15 @@ func genManyPred(size int) []bloc {
switch i % 3 {
case 0:
blocs = append(blocs, Bloc(blockn(i),
Valu("a", OpConstBool, TypeBool, 0, true),
Valu("a", OpConstBool, TypeBool, 1, nil),
Goto(blockn(i+1))))
case 1:
blocs = append(blocs, Bloc(blockn(i),
Valu("a", OpConstBool, TypeBool, 0, true),
Valu("a", OpConstBool, TypeBool, 1, nil),
If("p", blockn(i+1), blockn(0))))
case 2:
blocs = append(blocs, Bloc(blockn(i),
Valu("a", OpConstBool, TypeBool, 0, true),
Valu("a", OpConstBool, TypeBool, 1, nil),
If("p", blockn(i+1), blockn(size))))
}
}
......@@ -112,7 +112,7 @@ func genMaxPred(size int) []bloc {
blocs = append(blocs,
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
Goto(blockn(0)),
),
)
......@@ -137,14 +137,14 @@ func genMaxPredValue(size int) []bloc {
blocs = append(blocs,
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
Goto(blockn(0)),
),
)
for i := 0; i < size; i++ {
blocs = append(blocs, Bloc(blockn(i),
Valu("a", OpConstBool, TypeBool, 0, true),
Valu("a", OpConstBool, TypeBool, 1, nil),
If("p", blockn(i+1), "exit")))
}
......@@ -267,7 +267,7 @@ func TestDominatorsMultPredFwd(t *testing.T) {
fun := Fun(c, "entry",
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
If("p", "a", "c")),
Bloc("a",
If("p", "b", "c")),
......@@ -295,7 +295,7 @@ func TestDominatorsDeadCode(t *testing.T) {
fun := Fun(c, "entry",
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, false),
Valu("p", OpConstBool, TypeBool, 0, nil),
If("p", "b3", "b5")),
Bloc("b2", Exit("mem")),
Bloc("b3", Goto("b2")),
......@@ -320,7 +320,7 @@ func TestDominatorsMultPredRev(t *testing.T) {
Goto("first")),
Bloc("first",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
Goto("a")),
Bloc("a",
If("p", "b", "first")),
......@@ -349,7 +349,7 @@ func TestDominatorsMultPred(t *testing.T) {
fun := Fun(c, "entry",
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
If("p", "a", "c")),
Bloc("a",
If("p", "b", "c")),
......@@ -377,7 +377,7 @@ func TestPostDominators(t *testing.T) {
fun := Fun(c, "entry",
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
If("p", "a", "c")),
Bloc("a",
If("p", "b", "c")),
......@@ -404,7 +404,7 @@ func TestInfiniteLoop(t *testing.T) {
fun := Fun(c, "entry",
Bloc("entry",
Valu("mem", OpArg, TypeMem, 0, ".mem"),
Valu("p", OpConstBool, TypeBool, 0, true),
Valu("p", OpConstBool, TypeBool, 1, nil),
Goto("a")),
Bloc("a",
Goto("b")),
......
......@@ -303,8 +303,7 @@
(Const64F {val}) -> (MOVSDconst {val})
(ConstPtr [val]) -> (MOVQconst [val])
(ConstNil) -> (MOVQconst [0])
(ConstBool {b}) && !b.(bool) -> (MOVBconst [0])
(ConstBool {b}) && b.(bool) -> (MOVBconst [1])
(ConstBool [b]) -> (MOVBconst [b])
(Addr {sym} base) -> (LEAQ {sym} base)
......
......@@ -24,18 +24,18 @@
(AddPtr (ConstPtr [c]) (ConstPtr [d])) -> (ConstPtr [c+d])
(Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d])
(MulPtr (ConstPtr [c]) (ConstPtr [d])) -> (ConstPtr [c*d])
(IsInBounds (Const32 [c]) (Const32 [d])) -> (ConstBool {inBounds32(c,d)})
(IsInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool {inBounds64(c,d)})
(IsInBounds (ConstPtr [c]) (ConstPtr [d])) && config.PtrSize == 4 -> (ConstBool {inBounds32(c,d)})
(IsInBounds (ConstPtr [c]) (ConstPtr [d])) && config.PtrSize == 8 -> (ConstBool {inBounds64(c,d)})
(Eq64 x x) -> (ConstBool {true})
(Eq32 x x) -> (ConstBool {true})
(Eq16 x x) -> (ConstBool {true})
(Eq8 x x) -> (ConstBool {true})
(Neq64 x x) -> (ConstBool {false})
(Neq32 x x) -> (ConstBool {false})
(Neq16 x x) -> (ConstBool {false})
(Neq8 x x) -> (ConstBool {false})
(IsInBounds (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(inBounds32(c,d))])
(IsInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(inBounds64(c,d))])
(IsInBounds (ConstPtr [c]) (ConstPtr [d])) && config.PtrSize == 4 -> (ConstBool [b2i(inBounds32(c,d))])
(IsInBounds (ConstPtr [c]) (ConstPtr [d])) && config.PtrSize == 8 -> (ConstBool [b2i(inBounds64(c,d))])
(Eq64 x x) -> (ConstBool [1])
(Eq32 x x) -> (ConstBool [1])
(Eq16 x x) -> (ConstBool [1])
(Eq8 x x) -> (ConstBool [1])
(Neq64 x x) -> (ConstBool [0])
(Neq32 x x) -> (ConstBool [0])
(Neq16 x x) -> (ConstBool [0])
(Neq8 x x) -> (ConstBool [0])
// simplifications
(Or64 x x) -> x
......@@ -177,5 +177,5 @@
(If (IsNonNil (GetG)) yes no) -> (First nil yes no)
(If (Not cond) yes no) -> (If cond no yes)
(If (ConstBool {c}) yes no) && c.(bool) -> (First nil yes no)
(If (ConstBool {c}) yes no) && !c.(bool) -> (First nil no yes)
(If (ConstBool [c]) yes no) && c == 1 -> (First nil yes no)
(If (ConstBool [c]) yes no) && c == 0 -> (First nil no yes)
......@@ -162,3 +162,11 @@ func isPowerOfTwo(n int64) bool {
func is32Bit(n int64) bool {
return n == int64(int32(n))
}
// b2i translates a boolean value to 0 or 1 for assigning to auxInt.
func b2i(b bool) int64 {
if b {
return 1
}
return 0
}
......@@ -1624,41 +1624,20 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
end200524c722ed14ca935ba47f8f30327d:
;
case OpConstBool:
// match: (ConstBool {b})
// cond: !b.(bool)
// result: (MOVBconst [0])
{
b := v.Aux
if !(!b.(bool)) {
goto end876159ea073d2dcefcc251667c1a7780
}
v.Op = OpAMD64MOVBconst
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AuxInt = 0
return true
}
goto end876159ea073d2dcefcc251667c1a7780
end876159ea073d2dcefcc251667c1a7780:
;
// match: (ConstBool {b})
// cond: b.(bool)
// result: (MOVBconst [1])
// match: (ConstBool [b])
// cond:
// result: (MOVBconst [b])
{
b := v.Aux
if !(b.(bool)) {
goto end0dacad3f7cad53905aad5303391447f6
}
b := v.AuxInt
v.Op = OpAMD64MOVBconst
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AuxInt = 1
v.AuxInt = b
return true
}
goto end0dacad3f7cad53905aad5303391447f6
end0dacad3f7cad53905aad5303391447f6:
goto end6d919011283330dcbcb3826f0adc6793
end6d919011283330dcbcb3826f0adc6793:
;
case OpConstNil:
// match: (ConstNil)
......
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