re PR go/63560 (__go_set_defer_retaddr shouldn't be split by IPA split)
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 16 Oct 2014 17:17:40 +0000 (17:17 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 16 Oct 2014 17:17:40 +0000 (17:17 +0000)
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
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/statements.cc

index 81a555fdd88f3eaf79151b1aa124a6a380bd7d8b..4c7eca4b247e412ab9953d258e8024d877ca675a 100644 (file)
@@ -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.
index 01390ac28d20beef2c8136feb5ecc59e314b9897..4453d13c835ab245299ebd085c4cc46973d6626f 100644 (file)
@@ -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;
index 69073b509130babccec5f3583797178986e8610c..ccf5452371ddf14e9a0b2cc693a7494b80f30cfa 100644 (file)
@@ -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.