]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: omit write barrier for assignment to *(convert(&local))
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 21 Jun 2019 14:34:26 +0000 (14:34 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 21 Jun 2019 14:34:26 +0000 (14:34 +0000)
    Assignments to local variables don't need a write barrier. But
    currently the compiler inserts a write barrier if the LHS is a
    local variable with type converted, as *(convert(&local)). Let
    the compiler recognize this pattern and omit the write barrier.

    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/182541

From-SVN: r272550

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/wb.cc

index 10104a78197c45e6d710291ed3cab24bf258fcbc..4bc337c7c5466d461d485d019e49ab9a4bf43a8c 100644 (file)
@@ -1,4 +1,4 @@
-62e3a8cc0a862b0abd3d0b1ef6cf4b228992a137
+593f94f008c24f5abfe7f917a717cf2b0a2585e2
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index c1d54e6cb4c0a46cc248ff42b771d72545809585..501ad6a8ca208426f715ef22d316eaed0fc538fb 100644 (file)
@@ -735,6 +735,26 @@ Gogo::assign_needs_write_barrier(Expression* lhs)
        }
     }
 
+  // Nothing to do for an assignment to *(convert(&x)) where
+  // x is local variable or a temporary variable.
+  Unary_expression* ue = lhs->unary_expression();
+  if (ue != NULL && ue->op() == OPERATOR_MULT)
+    {
+      Expression* expr = ue->operand();
+      while (true)
+        {
+          if (expr->conversion_expression() != NULL)
+            expr = expr->conversion_expression()->expr();
+          else if (expr->unsafe_conversion_expression() != NULL)
+            expr = expr->unsafe_conversion_expression()->expr();
+          else
+            break;
+        }
+      ue = expr->unary_expression();
+      if (ue != NULL && ue->op() == OPERATOR_AND)
+        return this->assign_needs_write_barrier(ue->operand());
+    }
+
   // For a struct assignment, we don't need a write barrier if all the
   // pointer types can not be in the heap.
   Struct_type* st = lhs->type()->struct_type();