diff mbox series

Go patch committed: Stack allocate defer thunk

Message ID CAOyqgcX3ubiEgexJ8h0KOdLOi4vD4ng2s=-EfDpaOmEZ8=objQ@mail.gmail.com
State New
Headers show
Series Go patch committed: Stack allocate defer thunk | expand

Commit Message

Ian Lance Taylor Jan. 9, 2018, 11:36 p.m. UTC
This patch to the Go frontend by Cherry Zhang stack allocates defer
thunk when possible, which is to say when the defer statement is not
in a loop.  Bootstrapped on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian
diff mbox series

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 256407)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-d5774539b17112d9ce709a1fe722daf68eb8594f
+7c5e4d67041e3529a055a923b2b9f5ef09aa72a3
 
 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 256405)
+++ gcc/go/gofrontend/escape.cc	(working copy)
@@ -1420,7 +1420,14 @@  Escape_analysis_assign::statement(Block*
 
     case Statement::STATEMENT_DEFER:
       if (this->context_->loop_depth() == 1)
-	break;
+        {
+          // Defer statement may need to allocate a thunk. When it is
+          // not inside a loop, this can be stack allocated, as it
+          // runs before the function finishes.
+          Node* n = Node::make_node(s);
+          n->set_encoding(Node::ESCAPE_NONE);
+          break;
+        }
       // fallthrough
 
     case Statement::STATEMENT_GO:
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc	(revision 256366)
+++ gcc/go/gofrontend/statements.cc	(working copy)
@@ -2156,6 +2156,8 @@  Thunk_statement::simplify_statement(Gogo
 
   // Allocate the initialized struct on the heap.
   constructor = Expression::make_heap_expression(constructor, location);
+  if ((Node::make_node(this)->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
+    constructor->heap_expression()->set_allocate_on_stack();
 
   // Throw an error if the function is nil.  This is so that for `go
   // nil` we get a backtrace from the go statement, rather than a