aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-05-09 21:24:56 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-05-09 21:24:56 +0000
commit8743680541b8aeefdecba01b1960509a8d184202 (patch)
tree6e0408b38efa777cfebe66ec1eadb2781cb07cc3 /gcc
parent08e113f4aea9b3e80ffc1365ebd9db8ceedf8797 (diff)
downloadgcc-8743680541b8aeefdecba01b1960509a8d184202.zip
gcc-8743680541b8aeefdecba01b1960509a8d184202.tar.gz
gcc-8743680541b8aeefdecba01b1960509a8d184202.tar.bz2
compiler: avoid copy for string([]byte) conversion used in map keys
If a string([]byte) conversion is used immediately as a key for a map read, we don't need to copy the backing store of the byte slice, as mapaccess does not keep a reference to it. The gc compiler does more than this: it also avoids the copy if the map key is a composite literal that contains the conversion as a field, like, T{ ... { ..., string(b), ... }, ... }. For now, we just optimize the simple case, which is probably most common. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/176197 * go.dg/mapstring.go: New test. From-SVN: r271044
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc7
-rw-r--r--gcc/go/gofrontend/statements.cc7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/go.dg/mapstring.go11
5 files changed, 30 insertions, 1 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index f6f28a3..b601770 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-9c8581187b1c1a30036263728370f31cb846a274
+3dbf51c01c5d0acbf9ae47f77166fa9935881749
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 2c1286c..929571b 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -12158,6 +12158,13 @@ Map_index_expression::do_flatten(Gogo* gogo, Named_object*,
return Expression::make_error(loc);
}
+ // Avoid copy for string([]byte) conversions used in map keys.
+ // mapaccess doesn't keep the reference, so this is safe.
+ Type_conversion_expression* ce = this->index_->conversion_expression();
+ if (ce != NULL && ce->type()->is_string_type()
+ && ce->expr()->type()->is_slice_type())
+ ce->set_no_copy(true);
+
if (!Type::are_identical(mt->key_type(), this->index_->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 2e2d039..67ab184 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -1307,6 +1307,13 @@ Tuple_map_assignment_statement::do_lower(Gogo* gogo, Named_object*,
if (map_type == NULL)
return Statement::make_error_statement(loc);
+ // Avoid copy for string([]byte) conversions used in map keys.
+ // mapaccess doesn't keep the reference, so this is safe.
+ Type_conversion_expression* ce = map_index->index()->conversion_expression();
+ if (ce != NULL && ce->type()->is_string_type()
+ && ce->expr()->type()->is_slice_type())
+ ce->set_no_copy(true);
+
Block* b = new Block(enclosing, loc);
// Move out any subexpressions to make sure that functions are
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f75dbe7..4959d2a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-05-09 Cherry Zhang <cherryyz@google.com>
+
+ * go.dg/mapstring.go: New test.
+
2019-05-09 Richard Earnshaw <rearnsha@arm.com>
PR target/90405
diff --git a/gcc/testsuite/go.dg/mapstring.go b/gcc/testsuite/go.dg/mapstring.go
new file mode 100644
index 0000000..8a60e74
--- /dev/null
+++ b/gcc/testsuite/go.dg/mapstring.go
@@ -0,0 +1,11 @@
+// { dg-do compile }
+// { dg-options "-fgo-debug-optimization" }
+
+package p
+
+func F(m map[string]int, a, b []byte) int {
+ x := m[string(a)] // { dg-error "no copy string\\(\\\[\\\]byte\\)" }
+ y, ok := m[string(b)] // { dg-error "no copy string\\(\\\[\\\]byte\\)" }
+ _ = ok
+ return x + y
+}