comparison gcc/go/go-gcc.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 // go-gcc.cc -- Go frontend to gcc IR. 1 // go-gcc.cc -- Go frontend to gcc IR.
2 // Copyright (C) 2011-2018 Free Software Foundation, Inc. 2 // Copyright (C) 2011-2020 Free Software Foundation, Inc.
3 // Contributed by Ian Lance Taylor, Google. 3 // Contributed by Ian Lance Taylor, Google.
4 4
5 // This file is part of GCC. 5 // This file is part of GCC.
6 6
7 // GCC is free software; you can redistribute it and/or modify it under 7 // GCC is free software; you can redistribute it and/or modify it under
23 // This has to be included outside of extern "C", so we have to 23 // This has to be included outside of extern "C", so we have to
24 // include it here before tree.h includes it later. 24 // include it here before tree.h includes it later.
25 #include <gmp.h> 25 #include <gmp.h>
26 26
27 #include "tree.h" 27 #include "tree.h"
28 #include "opts.h"
28 #include "fold-const.h" 29 #include "fold-const.h"
29 #include "stringpool.h" 30 #include "stringpool.h"
30 #include "stor-layout.h" 31 #include "stor-layout.h"
31 #include "varasm.h" 32 #include "varasm.h"
32 #include "tree-iterator.h" 33 #include "tree-iterator.h"
480 error_function() 481 error_function()
481 { return this->make_function(error_mark_node); } 482 { return this->make_function(error_mark_node); }
482 483
483 Bfunction* 484 Bfunction*
484 function(Btype* fntype, const std::string& name, const std::string& asm_name, 485 function(Btype* fntype, const std::string& name, const std::string& asm_name,
485 bool is_visible, bool is_declaration, bool is_inlinable, 486 unsigned int flags, Location);
486 bool disable_split_stack, bool does_not_return,
487 bool in_unique_section, Location);
488 487
489 Bstatement* 488 Bstatement*
490 function_defer_statement(Bfunction* function, Bexpression* undefer, 489 function_defer_statement(Bfunction* function, Bexpression* undefer,
491 Bexpression* defer, Location); 490 Bexpression* defer, Location);
492 491
603 const_ptr_type_node, 602 const_ptr_type_node,
604 size_type_node, 603 size_type_node,
605 NULL_TREE), 604 NULL_TREE),
606 false, false); 605 false, false);
607 606
608 // Used by runtime/internal/sys. 607 // We use __builtin_memmove for copying data.
608 this->define_builtin(BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
609 build_function_type_list(void_type_node,
610 ptr_type_node,
611 const_ptr_type_node,
612 size_type_node,
613 NULL_TREE),
614 false, false);
615
616 // We use __builtin_memset for zeroing data.
617 this->define_builtin(BUILT_IN_MEMSET, "__builtin_memset", "memset",
618 build_function_type_list(void_type_node,
619 ptr_type_node,
620 integer_type_node,
621 size_type_node,
622 NULL_TREE),
623 false, false);
624
625 // Used by runtime/internal/sys and math/bits.
609 this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz", 626 this->define_builtin(BUILT_IN_CTZ, "__builtin_ctz", "ctz",
610 build_function_type_list(integer_type_node, 627 build_function_type_list(integer_type_node,
611 unsigned_type_node, 628 unsigned_type_node,
612 NULL_TREE), 629 NULL_TREE),
613 true, false); 630 true, false);
614 this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll", 631 this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
615 build_function_type_list(integer_type_node, 632 build_function_type_list(integer_type_node,
616 long_long_unsigned_type_node, 633 long_long_unsigned_type_node,
634 NULL_TREE),
635 true, false);
636 this->define_builtin(BUILT_IN_CLZ, "__builtin_clz", "clz",
637 build_function_type_list(integer_type_node,
638 unsigned_type_node,
639 NULL_TREE),
640 true, false);
641 this->define_builtin(BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
642 build_function_type_list(integer_type_node,
643 long_long_unsigned_type_node,
644 NULL_TREE),
645 true, false);
646 this->define_builtin(BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
647 build_function_type_list(integer_type_node,
648 unsigned_type_node,
649 NULL_TREE),
650 true, false);
651 this->define_builtin(BUILT_IN_POPCOUNTLL, "__builtin_popcountll", "popcountll",
652 build_function_type_list(integer_type_node,
653 long_long_unsigned_type_node,
654 NULL_TREE),
655 true, false);
656 this->define_builtin(BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
657 build_function_type_list(uint16_type_node,
658 uint16_type_node,
617 NULL_TREE), 659 NULL_TREE),
618 true, false); 660 true, false);
619 this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32", 661 this->define_builtin(BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
620 build_function_type_list(uint32_type_node, 662 build_function_type_list(uint32_type_node,
621 uint32_type_node, 663 uint32_type_node,
734 // functions which call recover, and for runtime.getcallerpc. 776 // functions which call recover, and for runtime.getcallerpc.
735 t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE); 777 t = build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE);
736 this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address", 778 this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
737 NULL, t, false, false); 779 NULL, t, false, false);
738 780
739 // The runtime calls __builtin_frame_address for runtime.getcallersp. 781 // The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
740 this->define_builtin(BUILT_IN_FRAME_ADDRESS, "__builtin_frame_address", 782 t = build_function_type_list(ptr_type_node, NULL_TREE);
783 this->define_builtin(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa",
741 NULL, t, false, false); 784 NULL, t, false, false);
742 785
743 // The runtime calls __builtin_extract_return_addr when recording 786 // The runtime calls __builtin_extract_return_addr when recording
744 // the address to which a function returns. 787 // the address to which a function returns.
745 this->define_builtin(BUILT_IN_EXTRACT_RETURN_ADDR, 788 this->define_builtin(BUILT_IN_EXTRACT_RETURN_ADDR,
760 build_varargs_function_type_list(void_type_node, 803 build_varargs_function_type_list(void_type_node,
761 const_ptr_type_node, 804 const_ptr_type_node,
762 NULL_TREE), 805 NULL_TREE),
763 false, false); 806 false, false);
764 807
765 // The compiler uses __builtin_unreachable for cases that can not 808 // The compiler uses __builtin_unreachable for cases that cannot
766 // occur. 809 // occur.
767 this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL, 810 this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
768 build_function_type(void_type_node, void_list_node), 811 build_function_type(void_type_node, void_list_node),
769 true, true); 812 true, true);
813
814 // We provide some atomic functions.
815 t = build_function_type_list(uint32_type_node,
816 ptr_type_node,
817 integer_type_node,
818 NULL_TREE);
819 this->define_builtin(BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL,
820 t, false, false);
821
822 t = build_function_type_list(uint64_type_node,
823 ptr_type_node,
824 integer_type_node,
825 NULL_TREE);
826 this->define_builtin(BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL,
827 t, false, false);
828
829 t = build_function_type_list(void_type_node,
830 ptr_type_node,
831 uint32_type_node,
832 integer_type_node,
833 NULL_TREE);
834 this->define_builtin(BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL,
835 t, false, false);
836
837 t = build_function_type_list(void_type_node,
838 ptr_type_node,
839 uint64_type_node,
840 integer_type_node,
841 NULL_TREE);
842 this->define_builtin(BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL,
843 t, false, false);
844
845 t = build_function_type_list(uint32_type_node,
846 ptr_type_node,
847 uint32_type_node,
848 integer_type_node,
849 NULL_TREE);
850 this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL,
851 t, false, false);
852
853 t = build_function_type_list(uint64_type_node,
854 ptr_type_node,
855 uint64_type_node,
856 integer_type_node,
857 NULL_TREE);
858 this->define_builtin(BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL,
859 t, false, false);
860
861 t = build_function_type_list(boolean_type_node,
862 ptr_type_node,
863 ptr_type_node,
864 uint32_type_node,
865 boolean_type_node,
866 integer_type_node,
867 integer_type_node,
868 NULL_TREE);
869 this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
870 "__atomic_compare_exchange_4", NULL,
871 t, false, false);
872
873 t = build_function_type_list(boolean_type_node,
874 ptr_type_node,
875 ptr_type_node,
876 uint64_type_node,
877 boolean_type_node,
878 integer_type_node,
879 integer_type_node,
880 NULL_TREE);
881 this->define_builtin(BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
882 "__atomic_compare_exchange_8", NULL,
883 t, false, false);
884
885 t = build_function_type_list(uint32_type_node,
886 ptr_type_node,
887 uint32_type_node,
888 integer_type_node,
889 NULL_TREE);
890 this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4", NULL,
891 t, false, false);
892
893 t = build_function_type_list(uint64_type_node,
894 ptr_type_node,
895 uint64_type_node,
896 integer_type_node,
897 NULL_TREE);
898 this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8", NULL,
899 t, false, false);
900
901 t = build_function_type_list(unsigned_char_type_node,
902 ptr_type_node,
903 unsigned_char_type_node,
904 integer_type_node,
905 NULL_TREE);
906 this->define_builtin(BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1", NULL,
907 t, false, false);
908 this->define_builtin(BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1", NULL,
909 t, false, false);
910
911 t = build_function_type_list(unsigned_char_type_node,
912 ptr_type_node,
913 unsigned_char_type_node,
914 integer_type_node,
915 NULL_TREE);
916 this->define_builtin(BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
917 t, false, false);
918 this->define_builtin(BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
919 t, false, false);
770 } 920 }
771 921
772 // Get an unnamed integer type. 922 // Get an unnamed integer type.
773 923
774 Btype* 924 Btype*
909 result = result_struct->get_tree(); 1059 result = result_struct->get_tree();
910 } 1060 }
911 if (result == error_mark_node) 1061 if (result == error_mark_node)
912 return this->error_type(); 1062 return this->error_type();
913 1063
914 // The libffi library can not represent a zero-sized object. To 1064 // The libffi library cannot represent a zero-sized object. To
915 // avoid causing confusion on 32-bit SPARC, we treat a function that 1065 // avoid causing confusion on 32-bit SPARC, we treat a function that
916 // returns a zero-sized value as returning void. That should do no 1066 // returns a zero-sized value as returning void. That should do no
917 // harm since there is no actual value to be returned. See 1067 // harm since there is no actual value to be returned. See
918 // https://gcc.gnu.org/PR72814 for details. 1068 // https://gcc.gnu.org/PR72814 for details.
919 if (result != void_type_node && int_size_in_bytes(result) == 0) 1069 if (result != void_type_node && int_size_in_bytes(result) == 0)
1049 placeholder->set_tree(error_mark_node); 1199 placeholder->set_tree(error_mark_node);
1050 return false; 1200 return false;
1051 } 1201 }
1052 gcc_assert(TREE_CODE(tt) == POINTER_TYPE); 1202 gcc_assert(TREE_CODE(tt) == POINTER_TYPE);
1053 TREE_TYPE(pt) = TREE_TYPE(tt); 1203 TREE_TYPE(pt) = TREE_TYPE(tt);
1204 TYPE_CANONICAL(pt) = TYPE_CANONICAL(tt);
1054 if (TYPE_NAME(pt) != NULL_TREE) 1205 if (TYPE_NAME(pt) != NULL_TREE)
1055 { 1206 {
1056 // Build the data structure gcc wants to see for a typedef. 1207 // Build the data structure gcc wants to see for a typedef.
1057 tree copy = build_variant_type_copy(pt); 1208 tree copy = build_variant_type_copy(pt);
1058 TYPE_NAME(copy) = NULL_TREE; 1209 TYPE_NAME(copy) = NULL_TREE;
1080 { 1231 {
1081 tree decl = build_decl(location.gcc_location(), TYPE_DECL, 1232 tree decl = build_decl(location.gcc_location(), TYPE_DECL,
1082 get_identifier_from_string(name), 1233 get_identifier_from_string(name),
1083 ret); 1234 ret);
1084 TYPE_NAME(ret) = decl; 1235 TYPE_NAME(ret) = decl;
1236
1237 // The struct type that eventually replaces this placeholder will require
1238 // structural equality. The placeholder must too, so that the requirement
1239 // for structural equality propagates to references that are constructed
1240 // before the replacement occurs.
1241 SET_TYPE_STRUCTURAL_EQUALITY(ret);
1085 } 1242 }
1086 return this->make_type(ret); 1243 return this->make_type(ret);
1087 } 1244 }
1088 1245
1089 // Fill in the fields of a placeholder struct type. 1246 // Fill in the fields of a placeholder struct type.
1098 Btype* r = this->fill_in_struct(placeholder, fields); 1255 Btype* r = this->fill_in_struct(placeholder, fields);
1099 1256
1100 if (TYPE_NAME(t) != NULL_TREE) 1257 if (TYPE_NAME(t) != NULL_TREE)
1101 { 1258 {
1102 // Build the data structure gcc wants to see for a typedef. 1259 // Build the data structure gcc wants to see for a typedef.
1103 tree copy = build_variant_type_copy(t); 1260 tree copy = build_distinct_type_copy(t);
1104 TYPE_NAME(copy) = NULL_TREE; 1261 TYPE_NAME(copy) = NULL_TREE;
1105 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy; 1262 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
1263 TYPE_SIZE(copy) = NULL_TREE;
1264 Btype* bc = this->make_type(copy);
1265 this->fill_in_struct(bc, fields);
1266 delete bc;
1106 } 1267 }
1107 1268
1108 return r->get_tree() != error_mark_node; 1269 return r->get_tree() != error_mark_node;
1109 } 1270 }
1110 1271
2243 ps != statements.end(); 2404 ps != statements.end();
2244 ++ps, ++pc) 2405 ++ps, ++pc)
2245 { 2406 {
2246 if (pc->empty()) 2407 if (pc->empty())
2247 { 2408 {
2248 source_location loc = (*ps != NULL 2409 location_t loc = (*ps != NULL
2249 ? EXPR_LOCATION((*ps)->get_tree()) 2410 ? EXPR_LOCATION((*ps)->get_tree())
2250 : UNKNOWN_LOCATION); 2411 : UNKNOWN_LOCATION);
2251 tree label = create_artificial_label(loc); 2412 tree label = create_artificial_label(loc);
2252 tree c = build_case_label(NULL_TREE, NULL_TREE, label); 2413 tree c = build_case_label(NULL_TREE, NULL_TREE, label);
2253 append_to_statement_list(c, &stmt_list); 2414 append_to_statement_list(c, &stmt_list);
2254 } 2415 }
2255 else 2416 else
2259 ++pcv) 2420 ++pcv)
2260 { 2421 {
2261 tree t = (*pcv)->get_tree(); 2422 tree t = (*pcv)->get_tree();
2262 if (t == error_mark_node) 2423 if (t == error_mark_node)
2263 return this->error_statement(); 2424 return this->error_statement();
2264 source_location loc = EXPR_LOCATION(t); 2425 location_t loc = EXPR_LOCATION(t);
2265 tree label = create_artificial_label(loc); 2426 tree label = create_artificial_label(loc);
2266 tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label); 2427 tree c = build_case_label((*pcv)->get_tree(), NULL_TREE, label);
2267 append_to_statement_list(c, &stmt_list); 2428 append_to_statement_list(c, &stmt_list);
2268 } 2429 }
2269 } 2430 }
3045 3206
3046 // Declare or define a new function. 3207 // Declare or define a new function.
3047 3208
3048 Bfunction* 3209 Bfunction*
3049 Gcc_backend::function(Btype* fntype, const std::string& name, 3210 Gcc_backend::function(Btype* fntype, const std::string& name,
3050 const std::string& asm_name, bool is_visible, 3211 const std::string& asm_name, unsigned int flags,
3051 bool is_declaration, bool is_inlinable, 3212 Location location)
3052 bool disable_split_stack, bool does_not_return,
3053 bool in_unique_section, Location location)
3054 { 3213 {
3055 tree functype = fntype->get_tree(); 3214 tree functype = fntype->get_tree();
3056 if (functype != error_mark_node) 3215 if (functype != error_mark_node)
3057 { 3216 {
3058 gcc_assert(FUNCTION_POINTER_TYPE_P(functype)); 3217 gcc_assert(FUNCTION_POINTER_TYPE_P(functype));
3063 return this->error_function(); 3222 return this->error_function();
3064 3223
3065 tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype); 3224 tree decl = build_decl(location.gcc_location(), FUNCTION_DECL, id, functype);
3066 if (! asm_name.empty()) 3225 if (! asm_name.empty())
3067 SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name)); 3226 SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
3068 if (is_visible) 3227 if ((flags & function_is_visible) != 0)
3069 TREE_PUBLIC(decl) = 1; 3228 TREE_PUBLIC(decl) = 1;
3070 if (is_declaration) 3229 if ((flags & function_is_declaration) != 0)
3071 DECL_EXTERNAL(decl) = 1; 3230 DECL_EXTERNAL(decl) = 1;
3072 else 3231 else
3073 { 3232 {
3074 tree restype = TREE_TYPE(functype); 3233 tree restype = TREE_TYPE(functype);
3075 tree resdecl = 3234 tree resdecl =
3077 DECL_ARTIFICIAL(resdecl) = 1; 3236 DECL_ARTIFICIAL(resdecl) = 1;
3078 DECL_IGNORED_P(resdecl) = 1; 3237 DECL_IGNORED_P(resdecl) = 1;
3079 DECL_CONTEXT(resdecl) = decl; 3238 DECL_CONTEXT(resdecl) = decl;
3080 DECL_RESULT(decl) = resdecl; 3239 DECL_RESULT(decl) = resdecl;
3081 } 3240 }
3082 if (!is_inlinable) 3241 if ((flags & function_is_inlinable) == 0)
3083 DECL_UNINLINABLE(decl) = 1; 3242 DECL_UNINLINABLE(decl) = 1;
3084 if (disable_split_stack) 3243 if ((flags & function_no_split_stack) != 0)
3085 { 3244 {
3086 tree attr = get_identifier ("no_split_stack"); 3245 tree attr = get_identifier ("no_split_stack");
3087 DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); 3246 DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
3088 } 3247 }
3089 if (does_not_return) 3248 if ((flags & function_does_not_return) != 0)
3090 TREE_THIS_VOLATILE(decl) = 1; 3249 TREE_THIS_VOLATILE(decl) = 1;
3091 if (in_unique_section) 3250 if ((flags & function_in_unique_section) != 0)
3092 resolve_unique_section(decl, 0, 1); 3251 resolve_unique_section(decl, 0, 1);
3252 if ((flags & function_only_inline) != 0)
3253 {
3254 TREE_PUBLIC (decl) = 1;
3255 DECL_EXTERNAL(decl) = 1;
3256 DECL_DECLARED_INLINE_P(decl) = 1;
3257 }
3258
3259 // Optimize thunk functions for size. A thunk created for a defer
3260 // statement that may call recover looks like:
3261 // if runtime.setdeferretaddr(L1) {
3262 // goto L1
3263 // }
3264 // realfn()
3265 // L1:
3266 // The idea is that L1 should be the address to which realfn
3267 // returns. This only works if this little function is not over
3268 // optimized. At some point GCC started duplicating the epilogue in
3269 // the basic-block reordering pass, breaking this assumption.
3270 // Optimizing the function for size avoids duplicating the epilogue.
3271 // This optimization shouldn't matter for any thunk since all thunks
3272 // are small.
3273 size_t pos = name.find("..thunk");
3274 if (pos != std::string::npos)
3275 {
3276 for (pos += 7; pos < name.length(); ++pos)
3277 {
3278 if (name[pos] < '0' || name[pos] > '9')
3279 break;
3280 }
3281 if (pos == name.length())
3282 {
3283 struct cl_optimization cur_opts;
3284 cl_optimization_save(&cur_opts, &global_options);
3285 global_options.x_optimize_size = 1;
3286 global_options.x_optimize_fast = 0;
3287 global_options.x_optimize_debug = 0;
3288 DECL_FUNCTION_SPECIFIC_OPTIMIZATION(decl) =
3289 build_optimization_node(&global_options);
3290 cl_optimization_restore(&global_options, &cur_opts);
3291 }
3292 }
3093 3293
3094 go_preserve_from_gc(decl); 3294 go_preserve_from_gc(decl);
3095 return new Bfunction(decl); 3295 return new Bfunction(decl);
3096 } 3296 }
3097 3297
3248 { 3448 {
3249 tree decl = (*p)->get_tree(); 3449 tree decl = (*p)->get_tree();
3250 if (decl != error_mark_node) 3450 if (decl != error_mark_node)
3251 { 3451 {
3252 go_preserve_from_gc(decl); 3452 go_preserve_from_gc(decl);
3253 gimplify_function_tree(decl); 3453 if (DECL_STRUCT_FUNCTION(decl) == NULL)
3454 allocate_struct_function(decl, false);
3254 cgraph_node::finalize_function(decl, true); 3455 cgraph_node::finalize_function(decl, true);
3255 3456
3256 defs[i] = decl; 3457 defs[i] = decl;
3257 ++i; 3458 ++i;
3258 } 3459 }