This Go frontend patch by Cherry Zhang omits write barriers for assignments 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. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 272549) +++ gcc/go/gofrontend/MERGE (working copy) @@ -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: gcc/go/gofrontend/wb.cc =================================================================== --- gcc/go/gofrontend/wb.cc (revision 272130) +++ gcc/go/gofrontend/wb.cc (working copy) @@ -735,6 +735,26 @@ Gogo::assign_needs_write_barrier(Express } } + // 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();