From 06e83d10e60a404f387e0f4df7c75953d53795d4 Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 9 Jan 2018 23:56:54 +0000 Subject: [PATCH] compiler: use temporary variable for stack allocation 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 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@256412 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index fc2e65d5259..0c6538d4e09 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index f4dc8e8b43d..d4a207174db 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -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 = -- 2.11.4.GIT