Commit 28fbbf41 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile/internal/gc: remove OCMPIFACE and OCMPSTR

Interface and string comparisons don't need separate Ops any more than
struct or array comparisons do.

Removing them requires shuffling some code around in walk (and a
little in order), but overall allows simplifying things a bit.

Passes toolstash-check.

Change-Id: I084b8a6c089b768dc76d220379f4daed8a35db15
Reviewed-on: https://go-review.googlesource.com/c/141637
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarRobert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent f64fd66f
......@@ -1058,9 +1058,7 @@ func idealkind(n *Node) Ctype {
OLT,
ONE,
ONOT,
OOROR,
OCMPSTR,
OCMPIFACE:
OOROR:
return CTBOOL
// shifts (beware!).
......
......@@ -1146,8 +1146,6 @@ var opprec = []int{
OGE: 4,
OGT: 4,
ONE: 4,
OCMPSTR: 4,
OCMPIFACE: 4,
OSEND: 3,
OANDAND: 2,
OOROR: 1,
......@@ -1507,11 +1505,6 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
n1.exprfmt(s, nprec, mode)
}
case OCMPSTR, OCMPIFACE:
n.Left.exprfmt(s, nprec, mode)
mode.Fprintf(s, " %#v ", n.SubOp())
n.Right.exprfmt(s, nprec+1, mode)
default:
mode.Fprintf(s, "<node %v>", n.Op)
}
......
......@@ -1319,12 +1319,6 @@ func (w *exportWriter) expr(n *Node) {
w.pos(n.Pos)
w.exprList(n.List)
case OCMPSTR, OCMPIFACE:
w.op(n.SubOp())
w.pos(n.Pos)
w.expr(n.Left)
w.expr(n.Right)
case ODCLCONST:
// if exporting, DCLCONST should just be removed as its usage
// has already been replaced with literals
......
......@@ -935,9 +935,6 @@ func (r *importReader) node() *Node {
}
return x
// case OCMPSTR, OCMPIFACE:
// unreachable - mapped to std comparison operators by exporter
// --------------------------------------------------------------------
// statements
case ODCL:
......
......@@ -1010,20 +1010,6 @@ func (o *Order) expr(n, lhs *Node) *Node {
}
}
case OCMPSTR:
n.Left = o.expr(n.Left, nil)
n.Right = o.expr(n.Right, nil)
// Mark string(byteSlice) arguments to reuse byteSlice backing
// buffer during conversion. String comparison does not
// memorize the strings for later use, so it is safe.
if n.Left.Op == OARRAYBYTESTR {
n.Left.Op = OARRAYBYTESTRTMP
}
if n.Right.Op == OARRAYBYTESTR {
n.Right.Op = OARRAYBYTESTRTMP
}
// key must be addressable
case OINDEXMAP:
n.Left = o.expr(n.Left, nil)
......@@ -1181,11 +1167,24 @@ func (o *Order) expr(n, lhs *Node) *Node {
n.Left = o.expr(n.Left, nil)
n = o.copyExpr(n, n.Type, true)
case OEQ, ONE:
case OEQ, ONE, OLT, OLE, OGT, OGE:
n.Left = o.expr(n.Left, nil)
n.Right = o.expr(n.Right, nil)
t := n.Left.Type
if t.IsStruct() || t.IsArray() {
switch {
case t.IsString():
// Mark string(byteSlice) arguments to reuse byteSlice backing
// buffer during conversion. String comparison does not
// memorize the strings for later use, so it is safe.
if n.Left.Op == OARRAYBYTESTR {
n.Left.Op = OARRAYBYTESTRTMP
}
if n.Right.Op == OARRAYBYTESTR {
n.Right.Op = OARRAYBYTESTRTMP
}
case t.IsStruct() || t.IsArray():
// for complex comparisons, we need both args to be
// addressable so we can pass them to the runtime.
n.Left = o.addrTemp(n.Left)
......
......@@ -65,7 +65,7 @@ func (n *Node) ResetAux() {
func (n *Node) SubOp() Op {
switch n.Op {
case OASOP, OCMPIFACE, OCMPSTR, ONAME:
case OASOP, ONAME:
default:
Fatalf("unexpected op: %v", n.Op)
}
......@@ -74,7 +74,7 @@ func (n *Node) SubOp() Op {
func (n *Node) SetSubOp(op Op) {
switch n.Op {
case OASOP, OCMPIFACE, OCMPSTR, ONAME:
case OASOP, ONAME:
default:
Fatalf("unexpected op: %v", n.Op)
}
......@@ -610,8 +610,8 @@ const (
OCAP // cap(Left)
OCLOSE // close(Left)
OCLOSURE // func Type { Body } (func literal)
OCMPIFACE // Left Etype Right (interface comparison, x == y or x != y)
OCMPSTR // Left Etype Right (string comparison, x == y, x < y, etc)
_ // toolstash kludge; was OCMPIFACE
_ // toolstash kludge; was OCMPSTR
OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form)
OMAPLIT // Type{List} (composite literal, Type is map)
OSTRUCTLIT // Type{List} (composite literal, Type is struct)
......
......@@ -747,12 +747,7 @@ func typecheck1(n *Node, top int) *Node {
}
}
if et == TSTRING {
if iscmp[n.Op] {
ot := n.Op
n.Op = OCMPSTR
n.SetSubOp(ot)
} else if n.Op == OADD {
if et == TSTRING && n.Op == OADD {
// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
n.Op = OADDSTR
......@@ -769,22 +764,6 @@ func typecheck1(n *Node, top int) *Node {
n.Left = nil
n.Right = nil
}
}
if et == TINTER {
if l.Op == OLITERAL && l.Val().Ctype() == CTNIL {
// swap for back end
n.Left = r
n.Right = l
} else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL {
} else // leave alone for back end
if r.Type.IsInterface() == l.Type.IsInterface() {
ot := n.Op
n.Op = OCMPIFACE
n.SetSubOp(ot)
}
}
if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
if r.Val().U.(*Mpint).CmpInt64(0) == 0 {
......
This diff is collapsed.
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