* Go patch committed: Avoid copy for string([]byte) conversion in map keys
@ 2019-05-09 21:25 Ian Lance Taylor
0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2019-05-09 21:25 UTC (permalink / raw)
To: gcc-patches, gofrontend-dev
[-- Attachment #1: Type: text/plain, Size: 723 bytes --]
This patch to the Go frontend by Cherry Zhang avoids a copy for a
string([]byte) conversion used as a map key. 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.
Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed
to mainline.
Ian
2019-05-09 Cherry Zhang <cherryyz@google.com>
* go.dg/mapstring.go: New test.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 2526 bytes --]
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE (revision 271021)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -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.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc (revision 271021)
+++ gcc/go/gofrontend/expressions.cc (working copy)
@@ -12158,6 +12158,13 @@ Map_index_expression::do_flatten(Gogo* g
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))
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc (revision 270993)
+++ gcc/go/gofrontend/statements.cc (working copy)
@@ -1307,6 +1307,13 @@ Tuple_map_assignment_statement::do_lower
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
Index: gcc/testsuite/go.dg/mapstring.go
===================================================================
--- gcc/testsuite/go.dg/mapstring.go (nonexistent)
+++ gcc/testsuite/go.dg/mapstring.go (working copy)
@@ -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
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2019-05-09 21:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-09 21:25 Go patch committed: Avoid copy for string([]byte) conversion in map keys Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).