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
This commit is contained in:
Ian Lance Taylor 2019-06-21 14:34:26 +00:00
parent c9b236e5ca
commit 28b9598b64
2 changed files with 21 additions and 1 deletions

View 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.

View 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();