This patch by Cherry Zhang fixes the Go frontend to make escape
analysis work with imported inlineable functions.

The escape analysis pass was written before we imported inlineable
function bodies, and in some places it skipped functions that are not
in the local package.  Now that there are imported function bodies,
make the escape analysis work with them.

Note that it is necessary for the escape analysis to run on imported
function bodies, even if they are already tagged.  The tags only have
the information of the parameters (receiver, results), but not the
internal nodes, e.g. local variables.  We still need to do the
analysis to get all the information.  (In the future maybe we could
export/import escape info for internal nodes also, then we don't need
to redo the analysis.)

Also add assertions to ensure that if we analyze the same function in
multiple places, they'd better agree with each other.

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

Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 272055)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-b79e9e79fddc9040ab58c7c518eb08454f308def
+a32739aadf0c7a65fcd5d5b6d0a0d206bff24a4f
 
 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 271983)
+++ gcc/go/gofrontend/escape.cc (working copy)
@@ -2773,15 +2773,8 @@ Gogo::assign_connectivity(Escape_context
       if (!p->type()->has_pointer())
         continue;
 
-      // External function?  Parameters must escape unless //go:noescape is 
set.
-      // TODO(cmang): Implement //go:noescape directive.
-      if (fn->package() != NULL)
-       param_node->set_encoding(Node::ESCAPE_HEAP);
-      else
-        {
-          param_node->set_encoding(Node::ESCAPE_NONE);
-          context->track(param_node);
-        }
+      param_node->set_encoding(Node::ESCAPE_NONE);
+      context->track(param_node);
     }
 
   Escape_analysis_loop el;
@@ -3319,9 +3312,6 @@ Escape_analysis_tag::tag(Named_object* f
 {
   // External functions are assumed unsafe
   // unless //go:noescape is given before the declaration.
-  if (fn->package() != NULL)
-    return;
-
   if (fn->is_function_declaration())
     {
       Function_declaration* fdcl = fn->func_declaration_value();
Index: gcc/go/gofrontend/types.h
===================================================================
--- gcc/go/gofrontend/types.h   (revision 271983)
+++ gcc/go/gofrontend/types.h   (working copy)
@@ -1494,7 +1494,12 @@ class Typed_identifier
   // Set the escape note.
   void
   set_note(const std::string& note)
-  { this->note_ = new std::string(note); }
+  {
+    if (this->note_ != NULL)
+      go_assert(*this->note_ == note);
+    else
+      this->note_ = new std::string(note);
+  }
 
  private:
   // Identifier name.

Reply via email to