]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compile, runtime: make selectnbrecv return two values
authorIan Lance Taylor <iant@golang.org>
Tue, 3 Aug 2021 18:36:24 +0000 (11:36 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 3 Aug 2021 23:40:00 +0000 (16:40 -0700)
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.

This is the gofrontend version of https://golang.org/cl/292890.

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/339529

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/runtime.def
gcc/go/gofrontend/statements.cc
libgo/go/runtime/chan.go

index 801e039a155034b83102eda28594f83070f5c86a..5a097ffee851d50fde61c7fbfb276c6f01c5ffdf 100644 (file)
@@ -1,4 +1,4 @@
-54361805bd611d896042b879ee7f6d2d4d088537
+2031f0be9c0b5fda6421d290a0261eb6bd1c8205
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index fad8cebc012d60ecb5c211a25adda66b971441ef..87a27085d60b62552c246c3a2f34de8c4a24d71e 100644 (file)
@@ -204,12 +204,8 @@ DEF_GO_RUNTIME(SELECTNBSEND, "runtime.selectnbsend", P2(CHAN, POINTER), R1(BOOL)
 
 // Non-blocking receive a value from a channel, used for two-case select
 // statement with a default case.
-DEF_GO_RUNTIME(SELECTNBRECV, "runtime.selectnbrecv", P2(POINTER, CHAN), R1(BOOL))
-
-// Non-blocking tuple receive from a channel, used for two-case select
-// statement with a default case.
-DEF_GO_RUNTIME(SELECTNBRECV2, "runtime.selectnbrecv2", P3(POINTER, POINTER, CHAN),
-               R1(BOOL))
+DEF_GO_RUNTIME(SELECTNBRECV, "runtime.selectnbrecv", P2(POINTER, CHAN),
+              R2(BOOL, BOOL))
 
 // Block execution.  Used for zero-case select.
 DEF_GO_RUNTIME(BLOCK, "runtime.block", P0(), R0())
index 9643d1b42b3fa3c41b67a8950c6d92fdbf8ec1d0..95fa3c48709e78733dcb8681b0f5f8a9a5c5e6ff 100644 (file)
@@ -6051,7 +6051,7 @@ Select_statement::lower_two_case(Block* b)
   Expression* chanref = Expression::make_temporary_reference(chantmp, loc);
 
   Block* bchan;
-  Expression* call;
+  Expression* cond;
   if (chancase.is_send())
     {
       // if selectnbsend(chan, &val) { body } else { default body }
@@ -6065,7 +6065,7 @@ Select_statement::lower_two_case(Block* b)
 
       Expression* ref = Expression::make_temporary_reference(ts, loc);
       Expression* addr = Expression::make_unary(OPERATOR_AND, ref, loc);
-      call = Runtime::make_call(Runtime::SELECTNBSEND, loc, 2, chanref, addr);
+      cond = Runtime::make_call(Runtime::SELECTNBSEND, loc, 2, chanref, addr);
       bchan = chancase.statements();
     }
   else
@@ -6075,34 +6075,31 @@ Select_statement::lower_two_case(Block* b)
 
       Expression* ref = Expression::make_temporary_reference(ts, loc);
       Expression* addr = Expression::make_unary(OPERATOR_AND, ref, loc);
-      Expression* okref = NULL;
-      if (chancase.closed() == NULL && chancase.closedvar() == NULL)
-        {
-          // Simple receive.
-          // if selectnbrecv(&lhs, chan) { body } else { default body }
-          call = Runtime::make_call(Runtime::SELECTNBRECV, loc, 2, addr, chanref);
-        }
-      else
-        {
-          // Tuple receive.
-          // if selectnbrecv2(&lhs, &ok, chan) { body } else { default body }
-
-          Type* booltype = Type::make_boolean_type();
-          Temporary_statement* okts = Statement::make_temporary(booltype, NULL,
-                                                                loc);
-          b->add_statement(okts);
-
-          okref = Expression::make_temporary_reference(okts, loc);
-          Expression* okaddr = Expression::make_unary(OPERATOR_AND, okref, loc);
-          call = Runtime::make_call(Runtime::SELECTNBRECV2, loc, 3, addr, okaddr,
-                                    chanref);
-        }
+
+      // selected, ok = selectnbrecv(&lhs, chan)
+      Call_expression* call = Runtime::make_call(Runtime::SELECTNBRECV, loc, 2,
+                                                addr, chanref);
+
+      Temporary_statement* selected_temp =
+       Statement::make_temporary(Type::make_boolean_type(),
+                                 Expression::make_call_result(call, 0),
+                                 loc);
+      b->add_statement(selected_temp);
+
+      Temporary_statement* ok_temp =
+       Statement::make_temporary(Type::make_boolean_type(),
+                                 Expression::make_call_result(call, 1),
+                                 loc);
+      b->add_statement(ok_temp);
+
+      cond = Expression::make_temporary_reference(selected_temp, loc);
 
       Location cloc = chancase.location();
       bchan = new Block(b, loc);
       if (chancase.val() != NULL && !chancase.val()->is_sink_expression())
         {
-          Statement* as = Statement::make_assignment(chancase.val(), ref->copy(),
+          Statement* as = Statement::make_assignment(chancase.val(),
+                                                    ref->copy(),
                                                      cloc);
           bchan->add_statement(as);
         }
@@ -6114,12 +6111,18 @@ Select_statement::lower_two_case(Block* b)
 
       if (chancase.closed() != NULL && !chancase.closed()->is_sink_expression())
         {
+         Expression* okref = Expression::make_temporary_reference(ok_temp,
+                                                                  cloc);
           Statement* as = Statement::make_assignment(chancase.closed(),
-                                                     okref->copy(), cloc);
+                                                     okref, cloc);
           bchan->add_statement(as);
         }
       else if (chancase.closedvar() != NULL)
-        chancase.closedvar()->var_value()->set_init(okref->copy());
+       {
+         Expression* okref = Expression::make_temporary_reference(ok_temp,
+                                                                  cloc);
+         chancase.closedvar()->var_value()->set_init(okref);
+       }
 
       Statement* bs = Statement::make_block_statement(chancase.statements(),
                                                       cloc);
@@ -6127,7 +6130,7 @@ Select_statement::lower_two_case(Block* b)
     }
 
   Statement* ifs =
-    Statement::make_if_statement(call, bchan, defcase.statements(), loc);
+    Statement::make_if_statement(cond, bchan, defcase.statements(), loc);
   b->add_statement(ifs);
 
   Statement* label =
index 7878a8fe0124419d2c1eb93058707c58e8c890a3..e3d0ad5acbe7a0a4ea51959f2a7ce9fa667f9046 100644 (file)
@@ -33,7 +33,6 @@ import (
 //go:linkname closechan
 //go:linkname selectnbsend
 //go:linkname selectnbrecv
-//go:linkname selectnbrecv2
 
 const (
        maxAlign  = 8
@@ -709,28 +708,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 {
@@ -742,16 +719,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