aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-06-21 14:34:26 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-06-21 14:34:26 +0000
commit28b9598b64122e232f2998d8fed2f10ebbf78884 (patch)
tree61e15520c182ee2d61f3e78111672e36494dc133
parentc9b236e5cafaea9d09ff8102140c72eb3d70e302 (diff)
downloadgcc-28b9598b64122e232f2998d8fed2f10ebbf78884.zip
gcc-28b9598b64122e232f2998d8fed2f10ebbf78884.tar.gz
gcc-28b9598b64122e232f2998d8fed2f10ebbf78884.tar.bz2
compiler: omit write barrier for assignment to *(convert(&local))
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
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/wb.cc20
2 files changed, 21 insertions, 1 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 10104a7..4bc337c 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -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.
diff --git a/gcc/go/gofrontend/wb.cc b/gcc/go/gofrontend/wb.cc
index c1d54e6..501ad6a 100644
--- a/gcc/go/gofrontend/wb.cc
+++ b/gcc/go/gofrontend/wb.cc
@@ -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();