]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile,runtime: make selectnbrecv return two values
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 17 Feb 2021 04:36:58 +0000 (11:36 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 23 Feb 2021 05:02:26 +0000 (05:02 +0000)
The only different between selectnbrecv and selectnbrecv2 is the later
set the input pointer value by second return value from chanrecv.

So by making selectnbrecv return two values from chanrecv, we can get
rid of selectnbrecv2, the compiler can now call only selectnbrecv and
generate simpler code.

Change-Id: Ifaf6cf1314c4f47b06ed9606b1578319be808507
Reviewed-on: https://go-review.googlesource.com/c/go/+/292890
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/typecheck/builtin.go
src/cmd/compile/internal/typecheck/builtin/runtime.go
src/cmd/compile/internal/walk/select.go
src/runtime/chan.go

index f9a4f6aef4d82f1079a5b8b8545845b877057f62..17393f801c53d83191bf82daeb52bafdc7d8dba6 100644 (file)
@@ -316,7 +316,7 @@ func runtimeTypes() []*types.Type {
        typs[92] = newSig(params(typs[1], typs[3]), nil)
        typs[93] = newSig(params(typs[1], typs[3], typs[15], typs[3], typs[15]), params(typs[15]))
        typs[94] = newSig(params(typs[87], typs[3]), params(typs[6]))
-       typs[95] = newSig(params(typs[3], typs[84]), params(typs[6]))
+       typs[95] = newSig(params(typs[3], typs[84]), params(typs[6], typs[6]))
        typs[96] = types.NewPtr(typs[6])
        typs[97] = newSig(params(typs[3], typs[96], typs[84]), params(typs[6]))
        typs[98] = newSig(params(typs[63]), nil)
index acb69c7b282e13f88802dd393bad143350902d37..77a6fdb026c70e19381fdbe515217a7f0c8c5700 100644 (file)
@@ -166,7 +166,7 @@ func typedmemclr(typ *byte, dst *any)
 func typedslicecopy(typ *byte, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
 
 func selectnbsend(hchan chan<- any, elem *any) bool
-func selectnbrecv(elem *any, hchan <-chan any) bool
+func selectnbrecv(elem *any, hchan <-chan any) (bool, bool)
 func selectnbrecv2(elem *any, received *bool, hchan <-chan any) bool
 
 func selectsetpc(pc *uintptr)
index 873be289dcc6af955aa18c9d6bc3088e89771df4..d2b67ddf55a7abc8d5ccba5dc9d991aa7cd7fd2e 100644 (file)
@@ -106,7 +106,7 @@ func walkSelectCases(cases []*ir.CommClause) []ir.Node {
                ir.SetPos(n)
                r := ir.NewIfStmt(base.Pos, nil, nil, nil)
                *r.PtrInit() = cas.Init()
-               var call ir.Node
+               var cond ir.Node
                switch n.Op() {
                default:
                        base.Fatalf("select %v", n.Op())
@@ -115,7 +115,7 @@ func walkSelectCases(cases []*ir.CommClause) []ir.Node {
                        // if selectnbsend(c, v) { body } else { default body }
                        n := n.(*ir.SendStmt)
                        ch := n.Chan
-                       call = mkcall1(chanfn("selectnbsend", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), ch, n.Value)
+                       cond = mkcall1(chanfn("selectnbsend", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), ch, n.Value)
 
                case ir.OSELRECV2:
                        n := n.(*ir.AssignListStmt)
@@ -125,18 +125,14 @@ func walkSelectCases(cases []*ir.CommClause) []ir.Node {
                        if ir.IsBlank(elem) {
                                elem = typecheck.NodNil()
                        }
-                       if ir.IsBlank(n.Lhs[1]) {
-                               // if selectnbrecv(&v, c) { body } else { default body }
-                               call = mkcall1(chanfn("selectnbrecv", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, ch)
-                       } else {
-                               // TODO(cuonglm): make this use selectnbrecv()
-                               // if selectnbrecv2(&v, &received, c) { body } else { default body }
-                               receivedp := typecheck.Expr(typecheck.NodAddr(n.Lhs[1]))
-                               call = mkcall1(chanfn("selectnbrecv2", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, receivedp, ch)
-                       }
+                       cond = typecheck.Temp(types.Types[types.TBOOL])
+                       fn := chanfn("selectnbrecv", 2, ch.Type())
+                       call := mkcall1(fn, fn.Type().Results(), r.PtrInit(), elem, ch)
+                       as := ir.NewAssignListStmt(r.Pos(), ir.OAS2, []ir.Node{cond, n.Lhs[1]}, []ir.Node{call})
+                       r.PtrInit().Append(typecheck.Stmt(as))
                }
 
-               r.Cond = typecheck.Expr(call)
+               r.Cond = typecheck.Expr(cond)
                r.Body = cas.Body
                r.Else = append(dflt.Init(), dflt.Body...)
                return []ir.Node{r, ir.NewBranchStmt(base.Pos, ir.OBREAK, nil)}
index ba56e2cc4048e565b02aeed8328af85f01f375b7..f2a75b30f44596490a95c191139d0a1346394ec8 100644 (file)
@@ -687,28 +687,6 @@ func selectnbsend(c *hchan, elem unsafe.Pointer) (selected bool) {
        return chansend(c, elem, false, getcallerpc())
 }
 
-// compiler implements
-//
-//     select {
-//     case v = <-c:
-//             ... foo
-//     default:
-//             ... bar
-//     }
-//
-// as
-//
-//     if selectnbrecv(&v, c) {
-//             ... foo
-//     } else {
-//             ... bar
-//     }
-//
-func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected bool) {
-       selected, _ = chanrecv(c, elem, false)
-       return
-}
-
 // compiler implements
 //
 //     select {
@@ -720,16 +698,14 @@ func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected bool) {
 //
 // as
 //
-//     if c != nil && selectnbrecv2(&v, &ok, c) {
+//     if selected, ok = selectnbrecv(&v, c); selected {
 //             ... foo
 //     } else {
 //             ... bar
 //     }
 //
-func selectnbrecv2(elem unsafe.Pointer, received *bool, c *hchan) (selected bool) {
-       // TODO(khr): just return 2 values from this function, now that it is in Go.
-       selected, *received = chanrecv(c, elem, false)
-       return
+func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected, received bool) {
+       return chanrecv(c, elem, false)
 }
 
 //go:linkname reflect_chansend reflect.chansend