diff options
author | Cherry Zhang <cherryyz@google.com> | 2019-05-09 21:24:56 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-05-09 21:24:56 +0000 |
commit | 8743680541b8aeefdecba01b1960509a8d184202 (patch) | |
tree | 6e0408b38efa777cfebe66ec1eadb2781cb07cc3 /gcc | |
parent | 08e113f4aea9b3e80ffc1365ebd9db8ceedf8797 (diff) | |
download | gcc-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/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 7 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/go.dg/mapstring.go | 11 |
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 +} |