public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).