diff mbox series

Go patch committed: Use temporary variable for stack allocation

Message ID CAOyqgcVt3Q3wVtsWq5Jf3dv7BkySHDs3+xeKEZ6i62ZDbtR4sw@mail.gmail.com
State New
Headers show
Series Go patch committed: Use temporary variable for stack allocation | expand

Commit Message

Ian Lance Taylor Jan. 9, 2018, 11:57 p.m. UTC
This patch to the Go frontend by Cherry Zhang uses a temporary
variable for stack allocation when possible.  Currently, an allocation
expression that can be allocated on stack is implemented with
__builtin_alloca, which turns into __morestack_allocate_stack_space,
which may call the C malloc function.  This may be slow.  Also if this
happens during certain runtime functions (e.g. write barrier), bad
things might happen (when the escape analysis is enabled for the
runtime).  Make a temporary variable on stack for the allocation
instead.  Also remove the write barrier in the assignment in building
heap expression when it is stack allocated.  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 256411)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-bea521d1d8688bea5b14b1ae2a03aec949f48a44
+7ef1b48f63c0a64b83fc049884fb89677e19b2dd
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 256407)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -12387,6 +12387,7 @@  Allocation_expression::do_get_backend(Tr
 {
   Gogo* gogo = context->gogo();
   Location loc = this->location();
+  Btype* btype = this->type_->get_backend(gogo);
 
   if (this->allocate_on_stack_)
     {
@@ -12397,10 +12398,20 @@  Allocation_expression::do_get_backend(Tr
           go_assert(saw_errors());
           return gogo->backend()->error_expression();
         }
-      return gogo->backend()->stack_allocation_expression(size, loc);
+      Bstatement* decl;
+      Named_object* fn = context->function();
+      go_assert(fn != NULL);
+      Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
+      Bexpression* zero = gogo->backend()->zero_expression(btype);
+      Bvariable* temp =
+        gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
+                                            zero, true, loc, &decl);
+      Bexpression* ret = gogo->backend()->var_expression(temp, loc);
+      ret = gogo->backend()->address_expression(ret, loc);
+      ret = gogo->backend()->compound_expression(decl, ret, loc);
+      return ret;
     }
 
-  Btype* btype = this->type_->get_backend(gogo);
   Bexpression* space =
     gogo->allocate_memory(this->type_, loc)->get_backend(context);
   Btype* pbtype = gogo->backend()->pointer_type(btype);
@@ -14278,7 +14289,7 @@  Heap_expression::do_get_backend(Translat
   // don't do this in the write barrier pass because in some cases
   // backend conversion can introduce new Heap_expression values.
   Bstatement* assn;
-  if (!etype->has_pointer())
+  if (!etype->has_pointer() || this->allocate_on_stack_)
     {
       space = gogo->backend()->var_expression(space_temp, loc);
       Bexpression* ref =