aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-01-09 23:56:54 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-09 23:56:54 +0000
commit7117ebbd34484609c88543527496d128014dc0d2 (patch)
tree2e759dfa0ae434d9a556946c8dabf9047e2fc444
parent4a59d4472b9a0a4c25c4483a03c71def7cb3aa8c (diff)
downloadgcc-7117ebbd34484609c88543527496d128014dc0d2.zip
gcc-7117ebbd34484609c88543527496d128014dc0d2.tar.gz
gcc-7117ebbd34484609c88543527496d128014dc0d2.tar.bz2
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 From-SVN: r256412
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc17
2 files changed, 15 insertions, 4 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index fc2e65d..0c6538d 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 f4dc8e8..d4a2071 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 =