diff options
author | Keith Randall <khr@golang.org> | 2016-01-25 09:21:17 -0800 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2016-01-29 17:49:45 +0000 |
commit | d8a65672f8605d9d51fd90996162ab8d79a4aa32 (patch) | |
tree | 96ac1829ad346811c93749995d5fe765c6655b8b /src/cmd/compile/internal/ssa/shortcircuit_test.go | |
parent | 9d6e605cf7c2b8b9c279e687d06bc92a8ade6fcc (diff) | |
download | go-d8a65672f8605d9d51fd90996162ab8d79a4aa32.tar.gz go-d8a65672f8605d9d51fd90996162ab8d79a4aa32.zip |
[dev.ssa] cmd/compile: optimization for && and || expressions
Compiling && and || expressions often leads to control
flow of the following form:
p:
If a goto b else c
b: <- p ...
x = phi(a, ...)
If x goto t else u
Note that if we take the edge p->b, then we are guaranteed
to take the edge b->t also. So in this situation, we might
as well go directly from p to t.
Change-Id: I6974f1e6367119a2ddf2014f9741fdb490edcc12
Reviewed-on: https://go-review.googlesource.com/18910
Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/shortcircuit_test.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/shortcircuit_test.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/shortcircuit_test.go b/src/cmd/compile/internal/ssa/shortcircuit_test.go new file mode 100644 index 0000000000..d518dfbabf --- /dev/null +++ b/src/cmd/compile/internal/ssa/shortcircuit_test.go @@ -0,0 +1,50 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +import "testing" + +func TestShortCircuit(t *testing.T) { + c := testConfig(t) + + fun := Fun(c, "entry", + Bloc("entry", + Valu("mem", OpInitMem, TypeMem, 0, ".mem"), + Valu("arg1", OpArg, TypeInt64, 0, nil), + Valu("arg2", OpArg, TypeInt64, 0, nil), + Valu("arg3", OpArg, TypeInt64, 0, nil), + Goto("b1")), + Bloc("b1", + Valu("cmp1", OpLess64, TypeBool, 0, nil, "arg1", "arg2"), + If("cmp1", "b2", "b3")), + Bloc("b2", + Valu("cmp2", OpLess64, TypeBool, 0, nil, "arg2", "arg3"), + Goto("b3")), + Bloc("b3", + Valu("phi2", OpPhi, TypeBool, 0, nil, "cmp1", "cmp2"), + If("phi2", "b4", "b5")), + Bloc("b4", + Valu("cmp3", OpLess64, TypeBool, 0, nil, "arg3", "arg1"), + Goto("b5")), + Bloc("b5", + Valu("phi3", OpPhi, TypeBool, 0, nil, "phi2", "cmp3"), + If("phi3", "b6", "b7")), + Bloc("b6", + Exit("mem")), + Bloc("b7", + Exit("mem"))) + + CheckFunc(fun.f) + shortcircuit(fun.f) + CheckFunc(fun.f) + + for _, b := range fun.f.Blocks { + for _, v := range b.Values { + if v.Op == OpPhi { + t.Errorf("phi %s remains", v) + } + } + } +} |