aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-06-19 15:13:53 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-06-19 15:13:53 +0000
commit4349775a30600906f5811ba7c743a5c22bdb3d7d (patch)
treea603f337ecccb290e61a1766664dd5ec30b5bb58 /gcc
parent7a907deeeb0b17ed332eb6e3a181a35b1873daf5 (diff)
downloadgcc-4349775a30600906f5811ba7c743a5c22bdb3d7d.zip
gcc-4349775a30600906f5811ba7c743a5c22bdb3d7d.tar.gz
gcc-4349775a30600906f5811ba7c743a5c22bdb3d7d.tar.bz2
compiler: optimize string concatenations
runtime.concatstring{2,3,4,5} are just wrappers of concatstrings. These wrappers don't provide any benefit, at least in the C calling convention we use, where passing arrays by value isn't an efficient thing. Change it to always use concatstrings. Also, the cap field of the slice passed to concatstrings is not necessary. So change it to pass a pointer and a length directly, which is more efficient than passing a slice header by value. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/182539 From-SVN: r272476
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc68
-rw-r--r--gcc/go/gofrontend/runtime.def12
3 files changed, 20 insertions, 62 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index e62501f..3b0cff7 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-0e4aa31b26a20b6a6a2ca102b85ba8c8b8cdf876
+7822080a6e226b1e5872e2fcefac30f666f4cc1e
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 766864a..864b62d 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -7442,7 +7442,7 @@ String_concat_expression::do_check_types(Gogo*)
Expression*
String_concat_expression::do_flatten(Gogo*, Named_object*,
- Statement_inserter*)
+ Statement_inserter* inserter)
{
if (this->is_error_expression())
return this;
@@ -7497,56 +7497,22 @@ String_concat_expression::do_flatten(Gogo*, Named_object*,
}
if (buf == NULL)
buf = Expression::make_nil(loc);
- Expression* call;
- switch (this->exprs_->size())
- {
- case 0: case 1:
- go_unreachable();
-
- case 2: case 3: case 4: case 5:
- {
- Expression* len = Expression::make_integer_ul(this->exprs_->size(),
- NULL, loc);
- Array_type* arg_type = Type::make_array_type(type, len);
- arg_type->set_is_array_incomparable();
- Expression* arg =
- Expression::make_array_composite_literal(arg_type, this->exprs_,
- loc);
- Runtime::Function code;
- switch (this->exprs_->size())
- {
- default:
- go_unreachable();
- case 2:
- code = Runtime::CONCATSTRING2;
- break;
- case 3:
- code = Runtime::CONCATSTRING3;
- break;
- case 4:
- code = Runtime::CONCATSTRING4;
- break;
- case 5:
- code = Runtime::CONCATSTRING5;
- break;
- }
- call = Runtime::make_call(code, loc, 2, buf, arg);
- }
- break;
-
- default:
- {
- Type* arg_type = Type::make_array_type(type, NULL);
- Slice_construction_expression* sce =
- Expression::make_slice_composite_literal(arg_type, this->exprs_,
- loc);
- sce->set_storage_does_not_escape();
- call = Runtime::make_call(Runtime::CONCATSTRINGS, loc, 2, buf,
- sce);
- }
- break;
- }
-
+ go_assert(this->exprs_->size() > 1);
+ Expression* len =
+ Expression::make_integer_ul(this->exprs_->size(), NULL, loc);
+ Array_type* array_type = Type::make_array_type(type, len);
+ array_type->set_is_array_incomparable();
+ Expression* array =
+ Expression::make_array_composite_literal(array_type, this->exprs_,
+ loc);
+ Temporary_statement* ts =
+ Statement::make_temporary(array_type, array, loc);
+ inserter->insert(ts);
+ Expression* ref = Expression::make_temporary_reference(ts, loc);
+ ref = Expression::make_unary(OPERATOR_AND, ref, loc);
+ Expression* call =
+ Runtime::make_call(Runtime::CONCATSTRINGS, loc, 3, buf,
+ ref, len->copy());
return Expression::make_cast(type, call, loc);
}
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index 34c86e8..c81ab79 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -36,16 +36,8 @@ DEF_GO_RUNTIME(DECODERUNE, "runtime.decoderune", P2(STRING, INT),
R2(RUNE, INT))
// Concatenate strings.
-DEF_GO_RUNTIME(CONCATSTRINGS, "runtime.concatstrings", P2(POINTER, SLICE),
- R1(STRING))
-DEF_GO_RUNTIME(CONCATSTRING2, "runtime.concatstring2",
- P2(POINTER, ARRAY2STRING), R1(STRING))
-DEF_GO_RUNTIME(CONCATSTRING3, "runtime.concatstring3",
- P2(POINTER, ARRAY3STRING), R1(STRING))
-DEF_GO_RUNTIME(CONCATSTRING4, "runtime.concatstring4",
- P2(POINTER, ARRAY4STRING), R1(STRING))
-DEF_GO_RUNTIME(CONCATSTRING5, "runtime.concatstring5",
- P2(POINTER, ARRAY5STRING), R1(STRING))
+DEF_GO_RUNTIME(CONCATSTRINGS, "runtime.concatstrings",
+ P3(POINTER, POINTER, INT), R1(STRING))
// Compare two strings for equality.
DEF_GO_RUNTIME(EQSTRING, "runtime.eqstring", P2(STRING, STRING), R1(BOOL))