diff options
author | Cherry Zhang <cherryyz@google.com> | 2019-06-18 23:55:50 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-06-18 23:55:50 +0000 |
commit | 864fcf61a00fa1b73ae32be6f1ee11a6f7362b82 (patch) | |
tree | 251712aed0fe7f6df1a7e269149d6854d66555cc /gcc | |
parent | ed920373a5faece7ea0bfdfebbd615294165c01c (diff) | |
download | gcc-864fcf61a00fa1b73ae32be6f1ee11a6f7362b82.zip gcc-864fcf61a00fa1b73ae32be6f1ee11a6f7362b82.tar.gz gcc-864fcf61a00fa1b73ae32be6f1ee11a6f7362b82.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/go.dg/concatstring.go | 8 |
4 files changed, 33 insertions, 1 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d89e8e3..16abddf 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 740daec..e5e6ba7 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 6ff197c..6f48341 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-06-18 Cherry Zhang <cherryyz@google.com> + + * go.dg/concatstring.go: New test. + 2019-06-18 Thomas Schwinge <thomas@codesourcery.com> PR fortran/90921 diff --git a/gcc/testsuite/go.dg/concatstring.go b/gcc/testsuite/go.dg/concatstring.go new file mode 100644 index 0000000..5dc4254 --- /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\\)" } +} |