From 960224c3b740cedfefc3efeb3a19fa5f72d93051 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 16 Oct 2014 17:17:40 +0000 Subject: [PATCH] re PR go/63560 (__go_set_defer_retaddr shouldn't be split by IPA split) PR go/63560 compiler: Mark functions that call defer_retaddr as not inlinable. This is to that the GCC middle-end won't split them. See http://gcc.gnu.org/PR63560. From-SVN: r216341 --- gcc/go/gofrontend/gogo.cc | 8 ++++++++ gcc/go/gofrontend/gogo.h | 9 +++++++++ gcc/go/gofrontend/statements.cc | 2 ++ 3 files changed, 19 insertions(+) diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 81a555fdd88..4c7eca4b247 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -4945,6 +4945,14 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) // our return address comparison. bool is_inlinable = !(this->calls_recover_ || this->is_recover_thunk_); + // If a function calls __go_set_defer_retaddr, then mark it as + // uninlinable. This prevents the GCC backend from splitting + // the function; splitting the function is a bad idea because we + // want the return address label to be in the same function as + // the call. + if (this->calls_defer_retaddr_) + is_inlinable = false; + // If this is a thunk created to call a function which calls // the predeclared recover function, we need to disable // stack splitting for the thunk. diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 01390ac28d2..4453d13c835 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -1065,6 +1065,12 @@ class Function set_has_recover_thunk() { this->has_recover_thunk_ = true; } + // Record that this function is a thunk created for a defer + // statement that calls the __go_set_defer_retaddr runtime function. + void + set_calls_defer_retaddr() + { this->calls_defer_retaddr_ = true; } + // Mark the function as going into a unique section. void set_in_unique_section() @@ -1190,6 +1196,9 @@ class Function bool is_recover_thunk_ : 1; // True if this function already has a recover thunk. bool has_recover_thunk_ : 1; + // True if this is a thunk built for a defer statement that calls + // the __go_set_defer_retaddr runtime function. + bool calls_defer_retaddr_ : 1; // True if this function should be put in a unique section. This is // turned on for field tracking. bool in_unique_section_ : 1; diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 69073b50913..ccf5452371d 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -2376,6 +2376,8 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name) location); s->determine_types(); gogo->add_statement(s); + + function->func_value()->set_calls_defer_retaddr(); } // Get a reference to the parameter. -- 2.30.2