compiler: use temporary variable for stack allocation
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 9 Jan 2018 23:56:54 +0000 (23:56 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 9 Jan 2018 23:56:54 +0000 (23:56 +0000)
    Currently, allocation expression that can be allocated on stack
    is implemented with __builtin_alloca, which turns into
    __morestack_allocate_stack_space, which may call C malloc. 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.

    Reviewed-on: https://go-review.googlesource.com/86242

From-SVN: r256412

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/expressions.cc

index fc2e65d5259017c7f6c7f9768b4a25b23926ef4a..0c6538d4e092c7086f01f084cc481333129d87c7 100644 (file)
@@ -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 f4dc8e8b43d3434e6430a3e2d5a47b05b78bf3e4..d4a207174db62a441ac62a43e754e8ae222c12e2 100644 (file)
@@ -12387,6 +12387,7 @@ Allocation_expression::do_get_backend(Translate_context* context)
 {
   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(Translate_context* context)
           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(Translate_context* context)
   // 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 =