aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2010-12-17 06:33:41 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2010-12-17 06:33:41 +0000
commitb5343013fe2755e0ce86306e17ba316cddcc6e24 (patch)
treeeaa0d2dd05a12f27cd941019fb7010fb9d5cb99a /gcc
parent94c4ae321544428ae014b59e0b3ee19c1431b277 (diff)
downloadgcc-b5343013fe2755e0ce86306e17ba316cddcc6e24.zip
gcc-b5343013fe2755e0ce86306e17ba316cddcc6e24.tar.gz
gcc-b5343013fe2755e0ce86306e17ba316cddcc6e24.tar.bz2
Avoid always splitting the stack when calling append and copy.
From-SVN: r167970
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/expressions.cc51
1 files changed, 42 insertions, 9 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 553e6d6..cb5c45c 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -7785,9 +7785,23 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
bytecount, element_size);
bytecount = fold_convert_loc(location, size_type_node, bytecount);
- tree call = build_call_expr_loc(location,
- built_in_decls[BUILT_IN_MEMMOVE],
- 3, arg1_val, arg2_val, bytecount);
+ arg1_val = fold_convert_loc(location, ptr_type_node, arg1_val);
+ arg2_val = fold_convert_loc(location, ptr_type_node, arg2_val);
+
+ static tree copy_fndecl;
+ tree call = Gogo::call_builtin(&copy_fndecl,
+ location,
+ "__go_copy",
+ 3,
+ void_type_node,
+ ptr_type_node,
+ arg1_val,
+ ptr_type_node,
+ arg2_val,
+ size_type_node,
+ bytecount);
+ if (call == error_mark_node)
+ return error_mark_node;
return fold_build2_loc(location, COMPOUND_EXPR, TREE_TYPE(len),
call, len);
@@ -7800,12 +7814,29 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
Expression* arg1 = args->front();
Expression* arg2 = args->back();
+ Array_type* at = arg1->type()->array_type();
+ Type* element_type = at->element_type();
+
tree arg1_tree = arg1->get_tree(context);
tree arg2_tree = arg2->get_tree(context);
if (arg1_tree == error_mark_node || arg2_tree == error_mark_node)
return error_mark_node;
- tree descriptor_tree = arg1->type()->type_descriptor_pointer(gogo);
+ Array_type* at2 = arg2->type()->array_type();
+ arg2_tree = save_expr(arg2_tree);
+ tree arg2_val = at2->value_pointer_tree(gogo, arg2_tree);
+ tree arg2_len = at2->length_tree(gogo, arg2_tree);
+ if (arg2_val == error_mark_node || arg2_len == error_mark_node)
+ return error_mark_node;
+ arg2_val = fold_convert_loc(location, ptr_type_node, arg2_val);
+ arg2_len = fold_convert_loc(location, size_type_node, arg2_len);
+
+ tree element_type_tree = element_type->get_tree(gogo);
+ if (element_type_tree == error_mark_node)
+ return error_mark_node;
+ tree element_size = TYPE_SIZE_UNIT(element_type_tree);
+ element_size = fold_convert_loc(location, size_type_node,
+ element_size);
// We rebuild the decl each time since the slice types may
// change.
@@ -7813,14 +7844,16 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
return Gogo::call_builtin(&append_fndecl,
location,
"__go_append",
- 3,
+ 4,
TREE_TYPE(arg1_tree),
- TREE_TYPE(descriptor_tree),
- descriptor_tree,
TREE_TYPE(arg1_tree),
arg1_tree,
- TREE_TYPE(arg2_tree),
- arg2_tree);
+ ptr_type_node,
+ arg2_val,
+ size_type_node,
+ arg2_len,
+ size_type_node,
+ element_size);
}
case BUILTIN_REAL: