Re: Go patch committed: Enable escape analysis for runtime

2018-01-18 Thread Ian Lance Taylor
On Thu, Jan 18, 2018 at 11:53 AM, Rainer Orth
 wrote:
>
>> This patch to the Go frontend by Cherry Zhang enables escape analysis
>> for the runtime package in the Go frontend.  The runtime package was
>> hard-coded non-escape, and the escape analysis was not run for the
>> runtime package.  This patch removes the hard-code, and lets the
>> escape analysis decide.  It is not allowed for local variables and
>> closures in the runtime to be heap allocated. This patch adds the
>> check that make sure that they indeed do not escape.
>>
>> The escape analysis is always run when compiling the runtime now.
>>
>> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
>> to mainline.
>
> this broke Solaris bootstrap:
>
> /vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:182:57: 
> error: n escapes to heap, not allowed in runtime
>   if port_getn(portfd, [0], uint32(len(events)), , wait) < 0 {
>  ^
> /vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:176:11: 
> error: zero escapes to heap, not allowed in runtime
>wait = 
>^
> /vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:174:6: error: 
> .runtime.zero escapes to heap, not allowed in runtime
>   var zero timespec
>   ^
> /vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:179:6: error: 
> .runtime.events escapes to heap, not allowed in runtime
>   var events [128]portevent
>   ^
> /vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:181:6: error: 
> .runtime.n escapes to heap, not allowed in runtime
>   var n uint32 = 1
>   ^
>
> Fixed as follows.  i386-pc-solaris2.11 and sparc-sun-solaris2.11 builds
> have completed, make check still running.

Thanks, patch committed.

Ian


Re: Go patch committed: Enable escape analysis for runtime

2018-01-18 Thread Rainer Orth
Hi Ian,

> This patch to the Go frontend by Cherry Zhang enables escape analysis
> for the runtime package in the Go frontend.  The runtime package was
> hard-coded non-escape, and the escape analysis was not run for the
> runtime package.  This patch removes the hard-code, and lets the
> escape analysis decide.  It is not allowed for local variables and
> closures in the runtime to be heap allocated. This patch adds the
> check that make sure that they indeed do not escape.
>
> The escape analysis is always run when compiling the runtime now.
>
> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
> to mainline.

this broke Solaris bootstrap:

/vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:182:57: error: 
n escapes to heap, not allowed in runtime
  if port_getn(portfd, [0], uint32(len(events)), , wait) < 0 {
 ^
/vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:176:11: error: 
zero escapes to heap, not allowed in runtime
   wait = 
   ^
/vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:174:6: error: 
.runtime.zero escapes to heap, not allowed in runtime
  var zero timespec
  ^
/vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:179:6: error: 
.runtime.events escapes to heap, not allowed in runtime
  var events [128]portevent
  ^
/vol/gcc/src/hg/trunk/local/libgo/go/runtime/netpoll_solaris.go:181:6: error: 
.runtime.n escapes to heap, not allowed in runtime
  var n uint32 = 1
  ^

Fixed as follows.  i386-pc-solaris2.11 and sparc-sun-solaris2.11 builds
have completed, make check still running.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


diff --git a/libgo/go/runtime/netpoll_solaris.go b/libgo/go/runtime/netpoll_solaris.go
--- a/libgo/go/runtime/netpoll_solaris.go
+++ b/libgo/go/runtime/netpoll_solaris.go
@@ -84,6 +84,7 @@ func port_associate(port, source int32, 
 //extern port_dissociate
 func port_dissociate(port, source int32, object uintptr) int32
 
+//go:noescape
 //extern port_getn
 func port_getn(port int32, evs *portevent, max uint32, nget *uint32, timeout *timespec) int32
 


Go patch committed: Enable escape analysis for runtime

2018-01-17 Thread Ian Lance Taylor
This patch to the Go frontend by Cherry Zhang enables escape analysis
for the runtime package in the Go frontend.  The runtime package was
hard-coded non-escape, and the escape analysis was not run for the
runtime package.  This patch removes the hard-code, and lets the
escape analysis decide.  It is not allowed for local variables and
closures in the runtime to be heap allocated. This patch adds the
check that make sure that they indeed do not escape.

The escape analysis is always run when compiling the runtime now.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

I'm almost done.  I promise.

Ian
Index: gcc/go/gofrontend/MERGE
===
--- gcc/go/gofrontend/MERGE (revision 256810)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-3ea7fc3b918210e7248dbc51d90af20639dc4167
+1072286ca9249bd6f75628aead325a66286bcf5b
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/escape.cc
===
--- gcc/go/gofrontend/escape.cc (revision 256707)
+++ gcc/go/gofrontend/escape.cc (working copy)
@@ -873,13 +873,12 @@ escape_hash_match(std::string suffix, st
 void
 Gogo::analyze_escape()
 {
-  if (!optimize_allocation_flag.is_enabled() || saw_errors())
+  if (saw_errors())
 return;
 
-  // Currently runtime is hard-coded to non-escape in various places.
-  // Don't run escape analysis for runtime.
-  // TODO: remove this once it works for runtime.
-  if (this->compiling_runtime() && this->package_name() == "runtime")
+  if (!optimize_allocation_flag.is_enabled()
+  && !this->compiling_runtime())
+// We always run escape analysis when compiling runtime.
 return;
 
   // Discover strongly connected groups of functions to analyze for escape
@@ -1473,6 +1472,35 @@ Escape_analysis_assign::statement(Block*
   return TRAVERSE_SKIP_COMPONENTS;
 }
 
+// Helper function to emit moved-to-heap diagnostics.
+
+static void
+move_to_heap(Gogo* gogo, Expression *expr)
+{
+  Named_object* no;
+  if (expr->var_expression() != NULL)
+no = expr->var_expression()->named_object();
+  else if (expr->enclosed_var_expression() != NULL)
+no = expr->enclosed_var_expression()->variable();
+  else
+return;
+
+  if ((no->is_variable()
+   && !no->var_value()->is_global())
+  || no->is_result_variable())
+{
+  Node* n = Node::make_node(expr);
+  if (gogo->debug_escape_level() != 0)
+go_inform(n->definition_location(),
+  "moved to heap: %s",
+  n->ast_format(gogo).c_str());
+  if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
+go_error_at(expr->location(),
+"%s escapes to heap, not allowed in runtime",
+n->ast_format(gogo).c_str());
+}
+}
+
 // Model expressions within a function as assignments and flows between nodes.
 
 int
@@ -1489,13 +1517,7 @@ Escape_analysis_assign::expression(Expre
   if (debug_level > 1)
go_inform((*pexpr)->location(), "%s too large for stack",
   n->ast_format(gogo).c_str());
-  if (debug_level != 0
-  && ((*pexpr)->var_expression() != NULL
-  || (*pexpr)->enclosed_var_expression() != NULL))
-go_inform(n->definition_location(),
-  "moved to heap: %s",
-  n->ast_format(gogo).c_str());
-
+  move_to_heap(gogo, *pexpr);
   n->set_encoding(Node::ESCAPE_HEAP);
   (*pexpr)->address_taken(true);
   this->assign(this->context_->sink(), n);
@@ -2968,25 +2990,20 @@ Escape_analysis_flood::flood(Level level
  if (src_leaks)
{
  src->set_encoding(Node::ESCAPE_HEAP);
- if (debug_level != 0 && osrcesc != src->encoding())
-   {
-  if (underlying->var_expression() != NULL
-  || underlying->enclosed_var_expression() != NULL)
-go_inform(underlying_node->definition_location(),
-  "moved to heap: %s",
-  underlying_node->ast_format(gogo).c_str());
-
- if (debug_level > 1)
-   go_inform(src->location(),
- "%s escapes to heap, level={%d %d}, "
- "dst.eld=%d, src.eld=%d",
- src->ast_format(gogo).c_str(), level.value(),
- level.suffix_value(), dst_state->loop_depth,
- mod_loop_depth);
- else
-   go_inform(src->location(), "%s escapes to heap",
- src->ast_format(gogo).c_str());
-   }
+  if (osrcesc != src->encoding())
+{
+  move_to_heap(gogo, underlying);
+  if