summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2014-10-16 17:17:40 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2014-10-16 17:17:40 +0000
commit960224c3b740cedfefc3efeb3a19fa5f72d93051 (patch)
tree06cda2f7f9645e6b615d5012520a22f8c9184c2a /gcc
parent01e4aecea8435f75dfb69c3b5fee1c309a9715b0 (diff)
downloadgcc-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.cc8
-rw-r--r--gcc/go/gofrontend/gogo.h9
-rw-r--r--gcc/go/gofrontend/statements.cc2
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.