diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-10-16 17:17:40 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-10-16 17:17:40 +0000 |
commit | 960224c3b740cedfefc3efeb3a19fa5f72d93051 (patch) | |
tree | 06cda2f7f9645e6b615d5012520a22f8c9184c2a /gcc | |
parent | 01e4aecea8435f75dfb69c3b5fee1c309a9715b0 (diff) | |
download | gcc-960224c3b740cedfefc3efeb3a19fa5f72d93051.tar.gz |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 8 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 9 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 2 |
3 files changed, 19 insertions, 0 deletions
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. |