This patch by Cherry Zhang changes the Go frontend to use gcWriteBarrier for pointer-shaped struct/array values. If a struct/array is pointer-shaped (i.e. having a single field that is pointer-shaped), we can use gcWriteBarrier instead of typedmemmove for 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 272127) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -a32739aadf0c7a65fcd5d5b6d0a0d206bff24a4f +3f7dcb98df3ce1d4e02d0072fd21e70dc08351db 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 272127) +++ gcc/go/gofrontend/wb.cc (working copy) @@ -955,14 +955,21 @@ Gogo::assign_with_write_barrier(Function // fallthrough case Type::TYPE_STRUCT: - { - // TODO: split assignments for small struct/array? - rhs = Expression::make_unary(OPERATOR_AND, rhs, loc); - rhs->unary_expression()->set_does_not_escape(); - call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3, - Expression::make_type_descriptor(type, loc), - lhs, rhs); - } + if (type->is_direct_iface_type()) + { + rhs = Expression::unpack_direct_iface(rhs, loc); + rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc); + call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs); + } + else + { + // TODO: split assignments for small struct/array? + rhs = Expression::make_unary(OPERATOR_AND, rhs, loc); + rhs->unary_expression()->set_does_not_escape(); + call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3, + Expression::make_type_descriptor(type, loc), + lhs, rhs); + } break; }