aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-06-18 23:55:50 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-06-18 23:55:50 +0000
commit864fcf61a00fa1b73ae32be6f1ee11a6f7362b82 (patch)
tree251712aed0fe7f6df1a7e269149d6854d66555cc /gcc
parented920373a5faece7ea0bfdfebbd615294165c01c (diff)
downloadgcc-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/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc20
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/go.dg/concatstring.go8
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\\)" }
+}