Skip to content

Commit

Permalink
cmd/compile: implement unsafe.Add and unsafe.Slice
Browse files Browse the repository at this point in the history
Updates #19367.
Updates #40481.

Change-Id: Iabd2afdd0d520e5d68fd9e6dedd013335a4b3886
Reviewed-on: https://go-review.googlesource.com/c/go/+/312214
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Trust: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
  • Loading branch information
mdempsky committed May 2, 2021
1 parent 0d32d9e commit fadad85
Show file tree
Hide file tree
Showing 20 changed files with 439 additions and 204 deletions.
7 changes: 6 additions & 1 deletion src/cmd/compile/internal/escape/escape.go
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ func (e *escape) exprSkipInit(k hole, n ir.Node) {
n := n.(*ir.UnaryExpr)
e.discard(n.X)

case ir.OCALLMETH, ir.OCALLFUNC, ir.OCALLINTER, ir.OLEN, ir.OCAP, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCOPY:
case ir.OCALLMETH, ir.OCALLFUNC, ir.OCALLINTER, ir.OLEN, ir.OCAP, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
e.call([]hole{k}, n, nil)

case ir.ONEW:
Expand Down Expand Up @@ -1101,6 +1101,11 @@ func (e *escape) call(ks []hole, call, where ir.Node) {
case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE:
call := call.(*ir.UnaryExpr)
argument(e.discardHole(), call.X)

case ir.OUNSAFEADD, ir.OUNSAFESLICE:
call := call.(*ir.BinaryExpr)
argument(ks[0], call.X)
argument(e.discardHole(), call.Y)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/ir/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (n *BinaryExpr) SetOp(op Op) {
panic(n.no("SetOp " + op.String()))
case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
OCOPY, OCOMPLEX,
OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE,
OEFACE:
n.op = op
}
Expand Down
132 changes: 68 additions & 64 deletions src/cmd/compile/internal/ir/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,69 +25,71 @@ import (
// Op

var OpNames = []string{
OADDR: "&",
OADD: "+",
OADDSTR: "+",
OALIGNOF: "unsafe.Alignof",
OANDAND: "&&",
OANDNOT: "&^",
OAND: "&",
OAPPEND: "append",
OAS: "=",
OAS2: "=",
OBREAK: "break",
OCALL: "function call", // not actual syntax
OCAP: "cap",
OCASE: "case",
OCLOSE: "close",
OCOMPLEX: "complex",
OBITNOT: "^",
OCONTINUE: "continue",
OCOPY: "copy",
ODELETE: "delete",
ODEFER: "defer",
ODIV: "/",
OEQ: "==",
OFALL: "fallthrough",
OFOR: "for",
OFORUNTIL: "foruntil", // not actual syntax; used to avoid off-end pointer live on backedge.892
OGE: ">=",
OGOTO: "goto",
OGT: ">",
OIF: "if",
OIMAG: "imag",
OINLMARK: "inlmark",
ODEREF: "*",
OLEN: "len",
OLE: "<=",
OLSH: "<<",
OLT: "<",
OMAKE: "make",
ONEG: "-",
OMOD: "%",
OMUL: "*",
ONEW: "new",
ONE: "!=",
ONOT: "!",
OOFFSETOF: "unsafe.Offsetof",
OOROR: "||",
OOR: "|",
OPANIC: "panic",
OPLUS: "+",
OPRINTN: "println",
OPRINT: "print",
ORANGE: "range",
OREAL: "real",
ORECV: "<-",
ORECOVER: "recover",
ORETURN: "return",
ORSH: ">>",
OSELECT: "select",
OSEND: "<-",
OSIZEOF: "unsafe.Sizeof",
OSUB: "-",
OSWITCH: "switch",
OXOR: "^",
OADDR: "&",
OADD: "+",
OADDSTR: "+",
OALIGNOF: "unsafe.Alignof",
OANDAND: "&&",
OANDNOT: "&^",
OAND: "&",
OAPPEND: "append",
OAS: "=",
OAS2: "=",
OBREAK: "break",
OCALL: "function call", // not actual syntax
OCAP: "cap",
OCASE: "case",
OCLOSE: "close",
OCOMPLEX: "complex",
OBITNOT: "^",
OCONTINUE: "continue",
OCOPY: "copy",
ODELETE: "delete",
ODEFER: "defer",
ODIV: "/",
OEQ: "==",
OFALL: "fallthrough",
OFOR: "for",
OFORUNTIL: "foruntil", // not actual syntax; used to avoid off-end pointer live on backedge.892
OGE: ">=",
OGOTO: "goto",
OGT: ">",
OIF: "if",
OIMAG: "imag",
OINLMARK: "inlmark",
ODEREF: "*",
OLEN: "len",
OLE: "<=",
OLSH: "<<",
OLT: "<",
OMAKE: "make",
ONEG: "-",
OMOD: "%",
OMUL: "*",
ONEW: "new",
ONE: "!=",
ONOT: "!",
OOFFSETOF: "unsafe.Offsetof",
OOROR: "||",
OOR: "|",
OPANIC: "panic",
OPLUS: "+",
OPRINTN: "println",
OPRINT: "print",
ORANGE: "range",
OREAL: "real",
ORECV: "<-",
ORECOVER: "recover",
ORETURN: "return",
ORSH: ">>",
OSELECT: "select",
OSEND: "<-",
OSIZEOF: "unsafe.Sizeof",
OSUB: "-",
OSWITCH: "switch",
OUNSAFEADD: "unsafe.Add",
OUNSAFESLICE: "unsafe.Slice",
OXOR: "^",
}

// GoString returns the Go syntax for the Op, or else its name.
Expand Down Expand Up @@ -218,6 +220,8 @@ var OpPrec = []int{
OTMAP: 8,
OTSTRUCT: 8,
OTYPE: 8,
OUNSAFEADD: 8,
OUNSAFESLICE: 8,
OINDEXMAP: 8,
OINDEX: 8,
OSLICE: 8,
Expand Down Expand Up @@ -794,7 +798,7 @@ func exprFmt(n Node, s fmt.State, prec int) {
n := n.(*SliceHeaderExpr)
fmt.Fprintf(s, "sliceheader{%v,%v,%v}", n.Ptr, n.Len, n.Cap)

case OCOMPLEX, OCOPY:
case OCOMPLEX, OCOPY, OUNSAFEADD, OUNSAFESLICE:
n := n.(*BinaryExpr)
fmt.Fprintf(s, "%v(%v, %v)", n.Op(), n.X, n.Y)

Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/ir/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ const (
OALIGNOF // unsafe.Alignof(X)
OOFFSETOF // unsafe.Offsetof(X)
OSIZEOF // unsafe.Sizeof(X)
OUNSAFEADD // unsafe.Add(X, Y)
OUNSAFESLICE // unsafe.Slice(X, Y)
OMETHEXPR // method expression

// statements
Expand Down
90 changes: 46 additions & 44 deletions src/cmd/compile/internal/ir/op_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/cmd/compile/internal/noder/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ func (g *irgen) expr(expr syntax.Expr) ir.Node {
}
switch {
case tv.IsBuiltin():
// Qualified builtins, such as unsafe.Add and unsafe.Slice.
if expr, ok := expr.(*syntax.SelectorExpr); ok {
if name, ok := expr.X.(*syntax.Name); ok {
if _, ok := g.info.Uses[name].(*types2.PkgName); ok {
return g.use(expr.Sel)
}
}
}
return g.use(expr.(*syntax.Name))
case tv.IsType():
return ir.TypeNode(g.typ(tv.Type))
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/noder/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,11 +795,11 @@ func transformBuiltin(n *ir.CallExpr) ir.Node {
return u1
}

case ir.OCOMPLEX, ir.OCOPY:
case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
transformArgs(n)
b := ir.NewBinaryExpr(n.Pos(), op, n.Args[0], n.Args[1])
n1 := typed(n.Type(), ir.InitExpr(n.Init(), b))
if op == ir.OCOPY {
if op != ir.OCOMPLEX {
// nothing more to do
return n1
}
Expand Down
6 changes: 6 additions & 0 deletions src/cmd/compile/internal/ssagen/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -3196,6 +3196,12 @@ func (s *state) expr(n ir.Node) *ssa.Value {
n := n.(*ir.UnaryExpr)
return s.newObject(n.Type().Elem())

case ir.OUNSAFEADD:
n := n.(*ir.BinaryExpr)
ptr := s.expr(n.X)
len := s.expr(n.Y)
return s.newValue2(ssa.OpAddPtr, n.Type(), ptr, len)

default:
s.Fatalf("unhandled expr %v", n.Op())
return nil
Expand Down
Loading

0 comments on commit fadad85

Please sign in to comment.