Commit 960224c3 by Ian Lance Taylor

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
parent 01e4aece
...@@ -4945,6 +4945,14 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) ...@@ -4945,6 +4945,14 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
// our return address comparison. // our return address comparison.
bool is_inlinable = !(this->calls_recover_ || this->is_recover_thunk_); 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 // If this is a thunk created to call a function which calls
// the predeclared recover function, we need to disable // the predeclared recover function, we need to disable
// stack splitting for the thunk. // stack splitting for the thunk.
......
...@@ -1065,6 +1065,12 @@ class Function ...@@ -1065,6 +1065,12 @@ class Function
set_has_recover_thunk() set_has_recover_thunk()
{ this->has_recover_thunk_ = true; } { 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. // Mark the function as going into a unique section.
void void
set_in_unique_section() set_in_unique_section()
...@@ -1190,6 +1196,9 @@ class Function ...@@ -1190,6 +1196,9 @@ class Function
bool is_recover_thunk_ : 1; bool is_recover_thunk_ : 1;
// True if this function already has a recover thunk. // True if this function already has a recover thunk.
bool has_recover_thunk_ : 1; 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 // True if this function should be put in a unique section. This is
// turned on for field tracking. // turned on for field tracking.
bool in_unique_section_ : 1; bool in_unique_section_ : 1;
......
...@@ -2376,6 +2376,8 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name) ...@@ -2376,6 +2376,8 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
location); location);
s->determine_types(); s->determine_types();
gogo->add_statement(s); gogo->add_statement(s);
function->func_value()->set_calls_defer_retaddr();
} }
// Get a reference to the parameter. // Get a reference to the parameter.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment