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/go | |
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/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 20 |
2 files changed, 21 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()) |