diff options
Diffstat (limited to 'src/cmd/compile/internal/walk/compare.go')
-rw-r--r-- | src/cmd/compile/internal/walk/compare.go | 35 |
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 993f1392aa1..fef2d710c05 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 { |