From: Cherry Zhang Date: Tue, 18 Jun 2019 23:55:50 +0000 (+0000) Subject: compiler: avoid copy for string([]byte) conversion used in string concatenation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=864fcf61a00fa1b73ae32be6f1ee11a6f7362b82;p=gcc.git compiler: avoid copy for string([]byte) conversion used in string concatenation If a string([]byte) conversion is used immediately in a string concatenation, we don't need to copy the backing store of the byte slice, as the runtime function doesn't hold any reference to it. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/182437 * go.dg/concatstring.go: New test. From-SVN: r272460 --- diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d89e8e3e288..16abddfcdfa 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -b1ae35965cadac235d7d218e689944286cccdd90 +62d1b667f3e85f72a186b04aad36d701160a4611 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/expressions.cc b/gcc/go/gofrontend/expressions.cc index 740daec5f21..e5e6ba75635 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7408,6 +7408,26 @@ String_concat_expression::do_flatten(Gogo*, Named_object*, return this; Location loc = this->location(); Type* type = this->type(); + + // Mark string([]byte) operands to reuse the backing store. + // runtime.concatstrings does not keep the reference. + // + // Note: in the gc runtime, if all but one inputs are empty, + // concatstrings returns the only nonempty input without copy. + // So it is not safe to reuse the backing store if it is a + // string([]byte) conversion. So the gc compiler does the + // no-copy optimization only when there is at least one + // constant nonempty input. Currently the gccgo runtime + // doesn't do this, so we don't do the check. + for (Expression_list::iterator p = this->exprs_->begin(); + p != this->exprs_->end(); + ++p) + { + Type_conversion_expression* tce = (*p)->conversion_expression(); + if (tce != NULL) + tce->set_no_copy(true); + } + Expression* nil_arg = Expression::make_nil(loc); Expression* call; switch (this->exprs_->size()) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6ff197c8e4d..6f4834191cf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-06-18 Cherry Zhang + + * go.dg/concatstring.go: New test. + 2019-06-18 Thomas Schwinge PR fortran/90921 diff --git a/gcc/testsuite/go.dg/concatstring.go b/gcc/testsuite/go.dg/concatstring.go new file mode 100644 index 00000000000..5dc4254ec19 --- /dev/null +++ b/gcc/testsuite/go.dg/concatstring.go @@ -0,0 +1,8 @@ +// { dg-do compile } +// { dg-options "-fgo-debug-optimization" } + +package p + +func F(b []byte, x string) string { + return "hello " + string(b) + x // { dg-error "no copy string\\(\\\[\\\]byte\\)" } +}