Skip to content

Commit

Permalink
cmd/compile/internal/gc: remove OCMPIFACE and OCMPSTR
Browse files Browse the repository at this point in the history
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: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
  • Loading branch information
mdempsky committed Oct 11, 2018
1 parent f64fd66 commit 28fbbf4
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 267 deletions.
4 changes: 1 addition & 3 deletions src/cmd/compile/internal/gc/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -1058,9 +1058,7 @@ func idealkind(n *Node) Ctype {
OLT,
ONE,
ONOT,
OOROR,
OCMPSTR,
OCMPIFACE:
OOROR:
return CTBOOL

// shifts (beware!).
Expand Down
7 changes: 0 additions & 7 deletions src/cmd/compile/internal/gc/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -1146,8 +1146,6 @@ var opprec = []int{
OGE: 4,
OGT: 4,
ONE: 4,
OCMPSTR: 4,
OCMPIFACE: 4,
OSEND: 3,
OANDAND: 2,
OOROR: 1,
Expand Down Expand Up @@ -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)
}
Expand Down
6 changes: 0 additions & 6 deletions src/cmd/compile/internal/gc/iexport.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions src/cmd/compile/internal/gc/iimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
31 changes: 15 additions & 16 deletions src/cmd/compile/internal/gc/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions src/cmd/compile/internal/gc/syntax.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down
49 changes: 14 additions & 35 deletions src/cmd/compile/internal/gc/typecheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,43 +747,22 @@ 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 {
// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
n.Op = OADDSTR

if l.Op == OADDSTR {
n.List.Set(l.List.Slice())
} else {
n.List.Set1(l)
}
if r.Op == OADDSTR {
n.List.AppendNodes(&r.List)
} else {
n.List.Append(r)
}
n.Left = nil
n.Right = nil
}
}
if et == TSTRING && n.Op == OADD {
// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
n.Op = OADDSTR

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 l.Op == OADDSTR {
n.List.Set(l.List.Slice())
} else {
n.List.Set1(l)
}
if r.Op == OADDSTR {
n.List.AppendNodes(&r.List)
} else {
n.List.Append(r)
}
n.Left = nil
n.Right = nil
}

if (op == ODIV || op == OMOD) && Isconst(r, CTINT) {
Expand Down
Loading

0 comments on commit 28fbbf4

Please sign in to comment.