From 47e8a22a179a53f681ab4e2478ffd62d01fb5f52 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 9 Jan 2018 23:36:46 +0000 Subject: [PATCH] compiler: stack allocate defer thunk 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. Reviewed-on: https://go-review.googlesource.com/85639 From-SVN: r256410 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/escape.cc | 9 ++++++++- gcc/go/gofrontend/statements.cc | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index fe3c16e2fe6..80ccaf3b3b9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc index 7a0545108bb..65ccf9bd0db 100644 --- a/gcc/go/gofrontend/escape.cc +++ b/gcc/go/gofrontend/escape.cc @@ -1420,7 +1420,14 @@ Escape_analysis_assign::statement(Block*, size_t*, Statement* s) 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: diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 93718ff8c2a..1c079bb40c7 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -2156,6 +2156,8 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function, // 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 -- 2.30.2