diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2010-12-17 06:33:41 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2010-12-17 06:33:41 +0000 |
commit | b5343013fe2755e0ce86306e17ba316cddcc6e24 (patch) | |
tree | eaa0d2dd05a12f27cd941019fb7010fb9d5cb99a /gcc | |
parent | 94c4ae321544428ae014b59e0b3ee19c1431b277 (diff) | |
download | gcc-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.cc | 51 |
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(©_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: |