aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/walk/compare.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/walk/compare.go')
-rw-r--r--src/cmd/compile/internal/walk/compare.go35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/walk/compare.go b/src/cmd/compile/internal/walk/compare.go
index 993f1392aa..fef2d710c0 100644
--- a/src/cmd/compile/internal/walk/compare.go
+++ b/src/cmd/compile/internal/walk/compare.go
@@ -8,6 +8,7 @@ import (
"go/constant"
"cmd/compile/internal/base"
+ "cmd/compile/internal/compare"
"cmd/compile/internal/ir"
"cmd/compile/internal/reflectdata"
"cmd/compile/internal/ssagen"
@@ -178,7 +179,7 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
andor = ir.OOROR
}
var expr ir.Node
- compare := func(el, er ir.Node) {
+ comp := func(el, er ir.Node) {
a := ir.NewBinaryExpr(base.Pos, n.Op(), el, er)
if expr == nil {
expr = a
@@ -186,18 +187,26 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
expr = ir.NewLogicalExpr(base.Pos, andor, expr, a)
}
}
+ and := func(cond ir.Node) {
+ if expr == nil {
+ expr = cond
+ } else {
+ expr = ir.NewLogicalExpr(base.Pos, andor, expr, cond)
+ }
+ }
cmpl = safeExpr(cmpl, init)
cmpr = safeExpr(cmpr, init)
if t.IsStruct() {
- for _, f := range t.Fields().Slice() {
- sym := f.Sym
- if sym.IsBlank() {
- continue
+ conds := compare.EqStruct(t, cmpl, cmpr)
+ if n.Op() == ir.OEQ {
+ for _, cond := range conds {
+ and(cond)
+ }
+ } else {
+ for _, cond := range conds {
+ notCond := ir.NewUnaryExpr(base.Pos, ir.ONOT, cond)
+ and(notCond)
}
- compare(
- ir.NewSelectorExpr(base.Pos, ir.OXDOT, cmpl, sym),
- ir.NewSelectorExpr(base.Pos, ir.OXDOT, cmpr, sym),
- )
}
} else {
step := int64(1)
@@ -221,7 +230,7 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
step = 1
}
if step == 1 {
- compare(
+ comp(
ir.NewIndexExpr(base.Pos, cmpl, ir.NewInt(i)),
ir.NewIndexExpr(base.Pos, cmpr, ir.NewInt(i)),
)
@@ -249,7 +258,7 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
rb = ir.NewBinaryExpr(base.Pos, ir.OLSH, rb, ir.NewInt(8*t.Elem().Size()*offset))
cmprw = ir.NewBinaryExpr(base.Pos, ir.OOR, cmprw, rb)
}
- compare(cmplw, cmprw)
+ comp(cmplw, cmprw)
i += step
remains -= step * t.Elem().Size()
}
@@ -270,7 +279,7 @@ func walkCompare(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
func walkCompareInterface(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
n.Y = cheapExpr(n.Y, init)
n.X = cheapExpr(n.X, init)
- eqtab, eqdata := reflectdata.EqInterface(n.X, n.Y)
+ eqtab, eqdata := compare.EqInterface(n.X, n.Y)
var cmp ir.Node
if n.Op() == ir.OEQ {
cmp = ir.NewLogicalExpr(base.Pos, ir.OANDAND, eqtab, eqdata)
@@ -384,7 +393,7 @@ func walkCompareString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
// prepare for rewrite below
n.X = cheapExpr(n.X, init)
n.Y = cheapExpr(n.Y, init)
- eqlen, eqmem := reflectdata.EqString(n.X, n.Y)
+ eqlen, eqmem := compare.EqString(n.X, n.Y)
// quick check of len before full compare for == or !=.
// memequal then tests equality up to length len.
if n.Op() == ir.OEQ {