comparison gcc/ipa-reference.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
comparison
equal deleted inserted replaced
130:e108057fa461 132:d34655255c78
1 /* Callgraph based analysis of static variables. 1 /* Callgraph based analysis of static variables.
2 Copyright (C) 2004-2017 Free Software Foundation, Inc. 2 Copyright (C) 2004-2018 Free Software Foundation, Inc.
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> 3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
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
47 #include "data-streamer.h" 47 #include "data-streamer.h"
48 #include "calls.h" 48 #include "calls.h"
49 #include "splay-tree.h" 49 #include "splay-tree.h"
50 #include "ipa-utils.h" 50 #include "ipa-utils.h"
51 #include "ipa-reference.h" 51 #include "ipa-reference.h"
52 52 #include "symbol-summary.h"
53 static void remove_node_data (struct cgraph_node *node,
54 void *data ATTRIBUTE_UNUSED);
55 static void duplicate_node_data (struct cgraph_node *src,
56 struct cgraph_node *dst,
57 void *data ATTRIBUTE_UNUSED);
58 53
59 /* The static variables defined within the compilation unit that are 54 /* The static variables defined within the compilation unit that are
60 loaded or stored directly by function that owns this structure. */ 55 loaded or stored directly by function that owns this structure. */
61 56
62 struct ipa_reference_local_vars_info_d 57 struct ipa_reference_local_vars_info_d
82 { 77 {
83 bitmap statics_not_read; 78 bitmap statics_not_read;
84 bitmap statics_not_written; 79 bitmap statics_not_written;
85 }; 80 };
86 81
87 typedef struct ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t; 82 typedef ipa_reference_local_vars_info_d *ipa_reference_local_vars_info_t;
88 typedef struct ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t; 83 typedef ipa_reference_global_vars_info_d *ipa_reference_global_vars_info_t;
89 typedef struct ipa_reference_optimization_summary_d *ipa_reference_optimization_summary_t; 84 typedef ipa_reference_optimization_summary_d *
85 ipa_reference_optimization_summary_t;
90 86
91 struct ipa_reference_vars_info_d 87 struct ipa_reference_vars_info_d
92 { 88 {
93 struct ipa_reference_local_vars_info_d local; 89 struct ipa_reference_local_vars_info_d local;
94 struct ipa_reference_global_vars_info_d global; 90 struct ipa_reference_global_vars_info_d global;
112 propagation) */ 108 propagation) */
113 static bitmap_obstack local_info_obstack; 109 static bitmap_obstack local_info_obstack;
114 /* Obstack holding global analysis live forever. */ 110 /* Obstack holding global analysis live forever. */
115 static bitmap_obstack optimization_summary_obstack; 111 static bitmap_obstack optimization_summary_obstack;
116 112
117 /* Holders of ipa cgraph hooks: */ 113 class ipa_ref_var_info_summary_t: public function_summary
118 static struct cgraph_2node_hook_list *node_duplication_hook_holder; 114 <ipa_reference_vars_info_d *>
119 static struct cgraph_node_hook_list *node_removal_hook_holder; 115 {
120 116 public:
121 /* Vector where the reference var infos are actually stored. 117 ipa_ref_var_info_summary_t (symbol_table *symtab):
122 Indexed by UID of call graph nodes. */ 118 function_summary <ipa_reference_vars_info_d *> (symtab) {}
123 static vec<ipa_reference_vars_info_t> ipa_reference_vars_vector; 119 };
124 120
125 /* TODO: find a place where we should release the vector. */ 121 static ipa_ref_var_info_summary_t *ipa_ref_var_info_summaries = NULL;
126 static vec<ipa_reference_optimization_summary_t> ipa_reference_opt_sum_vector; 122
123 class ipa_ref_opt_summary_t: public function_summary
124 <ipa_reference_optimization_summary_d *>
125 {
126 public:
127 ipa_ref_opt_summary_t (symbol_table *symtab):
128 function_summary <ipa_reference_optimization_summary_d *> (symtab) {}
129
130
131 virtual void remove (cgraph_node *src_node,
132 ipa_reference_optimization_summary_d *data);
133 virtual void duplicate (cgraph_node *src_node, cgraph_node *dst_node,
134 ipa_reference_optimization_summary_d *src_data,
135 ipa_reference_optimization_summary_d *dst_data);
136 };
137
138 static ipa_ref_opt_summary_t *ipa_ref_opt_sum_summaries = NULL;
127 139
128 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */ 140 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
129 static inline ipa_reference_vars_info_t 141 static inline ipa_reference_vars_info_t
130 get_reference_vars_info (struct cgraph_node *node) 142 get_reference_vars_info (struct cgraph_node *node)
131 { 143 {
132 if (!ipa_reference_vars_vector.exists () 144 if (ipa_ref_var_info_summaries == NULL)
133 || ipa_reference_vars_vector.length () <= (unsigned int) node->uid)
134 return NULL; 145 return NULL;
135 return ipa_reference_vars_vector[node->uid]; 146
147 ipa_reference_vars_info_t v = ipa_ref_var_info_summaries->get (node);
148 return v == NULL ? NULL : v;
136 } 149 }
137 150
138 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */ 151 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
139 static inline ipa_reference_optimization_summary_t 152 static inline ipa_reference_optimization_summary_t
140 get_reference_optimization_summary (struct cgraph_node *node) 153 get_reference_optimization_summary (struct cgraph_node *node)
141 { 154 {
142 if (!ipa_reference_opt_sum_vector.exists () 155 if (ipa_ref_opt_sum_summaries == NULL)
143 || (ipa_reference_opt_sum_vector.length () <= (unsigned int) node->uid))
144 return NULL; 156 return NULL;
145 return ipa_reference_opt_sum_vector[node->uid]; 157
146 } 158 ipa_reference_optimization_summary_t v
147 159 = ipa_ref_opt_sum_summaries->get (node);
148 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */ 160
149 static inline void 161 return v == NULL ? NULL : v;
150 set_reference_vars_info (struct cgraph_node *node,
151 ipa_reference_vars_info_t info)
152 {
153 if (!ipa_reference_vars_vector.exists ()
154 || ipa_reference_vars_vector.length () <= (unsigned int) node->uid)
155 ipa_reference_vars_vector.safe_grow_cleared (node->uid + 1);
156 ipa_reference_vars_vector[node->uid] = info;
157 }
158
159 /* Return the ipa_reference_vars structure starting from the cgraph NODE. */
160 static inline void
161 set_reference_optimization_summary (struct cgraph_node *node,
162 ipa_reference_optimization_summary_t info)
163 {
164 if (!ipa_reference_opt_sum_vector.exists ()
165 || (ipa_reference_opt_sum_vector.length () <= (unsigned int) node->uid))
166 ipa_reference_opt_sum_vector.safe_grow_cleared (node->uid + 1);
167 ipa_reference_opt_sum_vector[node->uid] = info;
168 } 162 }
169 163
170 /* Return a bitmap indexed by ipa_reference_var_uid for the static variables 164 /* Return a bitmap indexed by ipa_reference_var_uid for the static variables
171 that are *not* read during the execution of the function FN. Returns 165 that are *not* read during the execution of the function FN. Returns
172 NULL if no data is available. */ 166 NULL if no data is available. */
428 bitmap_obstack_initialize (&local_info_obstack); 422 bitmap_obstack_initialize (&local_info_obstack);
429 bitmap_obstack_initialize (&optimization_summary_obstack); 423 bitmap_obstack_initialize (&optimization_summary_obstack);
430 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack); 424 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
431 ignore_module_statics = BITMAP_ALLOC (&optimization_summary_obstack); 425 ignore_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
432 426
433 node_removal_hook_holder = 427 if (ipa_ref_var_info_summaries == NULL)
434 symtab->add_cgraph_removal_hook (&remove_node_data, NULL); 428 ipa_ref_var_info_summaries = new ipa_ref_var_info_summary_t (symtab);
435 node_duplication_hook_holder = 429
436 symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL); 430 if (ipa_ref_opt_sum_summaries != NULL)
431 {
432 delete ipa_ref_opt_sum_summaries;
433 ipa_ref_opt_sum_summaries = NULL;
434 }
437 } 435 }
438 436
439 437
440 /* Set up the persistent info for FN. */ 438 /* Set up the persistent info for FN. */
441 439
442 static ipa_reference_local_vars_info_t 440 static ipa_reference_local_vars_info_t
443 init_function_info (struct cgraph_node *fn) 441 init_function_info (struct cgraph_node *fn)
444 { 442 {
445 ipa_reference_vars_info_t info 443 ipa_reference_vars_info_t info
446 = XCNEW (struct ipa_reference_vars_info_d); 444 = ipa_ref_var_info_summaries->get_create (fn);
447
448 /* Add the info to the tree's annotation. */
449 set_reference_vars_info (fn, info);
450 445
451 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack); 446 info->local.statics_read = BITMAP_ALLOC (&local_info_obstack);
452 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack); 447 info->local.statics_written = BITMAP_ALLOC (&local_info_obstack);
453 448
454 return &info->local; 449 return &info->local;
508 } 503 }
509 504
510 505
511 /* Called when new clone is inserted to callgraph late. */ 506 /* Called when new clone is inserted to callgraph late. */
512 507
513 static void 508 void
514 duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst, 509 ipa_ref_opt_summary_t::duplicate (cgraph_node *, cgraph_node *,
515 void *data ATTRIBUTE_UNUSED) 510 ipa_reference_optimization_summary_d *ginfo,
516 { 511 ipa_reference_optimization_summary_d
517 ipa_reference_optimization_summary_t ginfo; 512 *dst_ginfo)
518 ipa_reference_optimization_summary_t dst_ginfo; 513 {
519
520 ginfo = get_reference_optimization_summary (src);
521 if (!ginfo)
522 return;
523 dst_ginfo = XCNEW (struct ipa_reference_optimization_summary_d);
524 set_reference_optimization_summary (dst, dst_ginfo);
525 dst_ginfo->statics_not_read = 514 dst_ginfo->statics_not_read =
526 copy_static_var_set (ginfo->statics_not_read); 515 copy_static_var_set (ginfo->statics_not_read);
527 dst_ginfo->statics_not_written = 516 dst_ginfo->statics_not_written =
528 copy_static_var_set (ginfo->statics_not_written); 517 copy_static_var_set (ginfo->statics_not_written);
529 } 518 }
530 519
531 /* Called when node is removed. */ 520 /* Called when node is removed. */
532 521
533 static void 522 void
534 remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) 523 ipa_ref_opt_summary_t::remove (cgraph_node *,
535 { 524 ipa_reference_optimization_summary_d *ginfo)
536 ipa_reference_optimization_summary_t ginfo; 525 {
537 ginfo = get_reference_optimization_summary (node); 526 if (ginfo->statics_not_read
538 if (ginfo) 527 && ginfo->statics_not_read != all_module_statics)
539 { 528 BITMAP_FREE (ginfo->statics_not_read);
540 if (ginfo->statics_not_read 529
541 && ginfo->statics_not_read != all_module_statics) 530 if (ginfo->statics_not_written
542 BITMAP_FREE (ginfo->statics_not_read); 531 && ginfo->statics_not_written != all_module_statics)
543 532 BITMAP_FREE (ginfo->statics_not_written);
544 if (ginfo->statics_not_written
545 && ginfo->statics_not_written != all_module_statics)
546 BITMAP_FREE (ginfo->statics_not_written);
547 free (ginfo);
548 set_reference_optimization_summary (node, NULL);
549 }
550 } 533 }
551 534
552 /* Analyze each function in the cgraph to see which global or statics 535 /* Analyze each function in the cgraph to see which global or statics
553 are read or written. */ 536 are read or written. */
554 537
669 { 652 {
670 enum availability avail; 653 enum availability avail;
671 struct cgraph_node *callee = e->callee->function_symbol (&avail); 654 struct cgraph_node *callee = e->callee->function_symbol (&avail);
672 gcc_checking_assert (callee); 655 gcc_checking_assert (callee);
673 if (avail <= AVAIL_INTERPOSABLE 656 if (avail <= AVAIL_INTERPOSABLE
674 || (callee->analyzed && !opt_for_fn (callee->decl, flag_ipa_reference))) 657 || (callee->analyzed && !opt_for_fn (callee->decl,
658 flag_ipa_reference)))
675 read_write_all_from_decl (callee, read_all, write_all); 659 read_write_all_from_decl (callee, read_all, write_all);
676 } 660 }
677 661
678 for (ie = node->indirect_calls; 662 for (ie = node->indirect_calls;
679 ie && !(read_all && write_all); 663 ie && !(read_all && write_all);
847 dump_static_vars_set_to_file (dump_file, node_g->statics_written); 831 dump_static_vars_set_to_file (dump_file, node_g->statics_written);
848 fprintf (dump_file, "\n"); 832 fprintf (dump_file, "\n");
849 } 833 }
850 } 834 }
851 835
836 if (ipa_ref_opt_sum_summaries == NULL)
837 ipa_ref_opt_sum_summaries = new ipa_ref_opt_summary_t (symtab);
838
852 /* Cleanup. */ 839 /* Cleanup. */
853 FOR_EACH_DEFINED_FUNCTION (node) 840 FOR_EACH_DEFINED_FUNCTION (node)
854 { 841 {
855 ipa_reference_vars_info_t node_info; 842 ipa_reference_vars_info_t node_info;
856 ipa_reference_global_vars_info_t node_g; 843 ipa_reference_global_vars_info_t node_g;
857 ipa_reference_optimization_summary_t opt;
858 844
859 node_info = get_reference_vars_info (node); 845 node_info = get_reference_vars_info (node);
860 if (!node->alias && opt_for_fn (node->decl, flag_ipa_reference) 846 if (!node->alias && opt_for_fn (node->decl, flag_ipa_reference)
861 && (node->get_availability () > AVAIL_INTERPOSABLE 847 && (node->get_availability () > AVAIL_INTERPOSABLE
862 || (flags_from_decl_or_type (node->decl) & ECF_LEAF))) 848 || (flags_from_decl_or_type (node->decl) & ECF_LEAF)))
863 { 849 {
864 node_g = &node_info->global; 850 node_g = &node_info->global;
865 851
866 opt = XCNEW (struct ipa_reference_optimization_summary_d); 852 ipa_reference_optimization_summary_d *opt
867 set_reference_optimization_summary (node, opt); 853 = ipa_ref_opt_sum_summaries->get_create (node);
868 854
869 /* Create the complimentary sets. */ 855 /* Create the complimentary sets. */
870 856
871 if (bitmap_empty_p (node_g->statics_read)) 857 if (bitmap_empty_p (node_g->statics_read))
872 opt->statics_not_read = all_module_statics; 858 opt->statics_not_read = all_module_statics;
890 bitmap_and_compl (opt->statics_not_written, 876 bitmap_and_compl (opt->statics_not_written,
891 all_module_statics, 877 all_module_statics,
892 node_g->statics_written); 878 node_g->statics_written);
893 } 879 }
894 } 880 }
895 free (node_info);
896 } 881 }
897 882
898 ipa_free_postorder_info (); 883 ipa_free_postorder_info ();
899 free (order); 884 free (order);
900 885
901 bitmap_obstack_release (&local_info_obstack); 886 bitmap_obstack_release (&local_info_obstack);
902 ipa_reference_vars_vector.release (); 887
888 if (ipa_ref_var_info_summaries == NULL)
889 {
890 delete ipa_ref_var_info_summaries;
891 ipa_ref_var_info_summaries = NULL;
892 }
893
894 ipa_ref_var_info_summaries = NULL;
903 if (dump_file) 895 if (dump_file)
904 splay_tree_delete (reference_vars_to_consider); 896 splay_tree_delete (reference_vars_to_consider);
905 reference_vars_to_consider = NULL; 897 reference_vars_to_consider = NULL;
906 return remove_p ? TODO_remove_functions : 0; 898 return remove_p ? TODO_remove_functions : 0;
907 } 899 }
917 909
918 /* See if we have (non-empty) info. */ 910 /* See if we have (non-empty) info. */
919 if (!node->definition || node->global.inlined_to) 911 if (!node->definition || node->global.inlined_to)
920 return false; 912 return false;
921 info = get_reference_optimization_summary (node); 913 info = get_reference_optimization_summary (node);
922 if (!info || (bitmap_empty_p (info->statics_not_read) 914 if (!info
923 && bitmap_empty_p (info->statics_not_written))) 915 || (bitmap_empty_p (info->statics_not_read)
916 && bitmap_empty_p (info->statics_not_written)))
924 return false; 917 return false;
925 918
926 /* See if we want to encode it. 919 /* See if we want to encode it.
927 Encode also referenced functions since constant folding might turn it into 920 Encode also referenced functions since constant folding might turn it into
928 a direct call. 921 a direct call.
968 streamer_write_hwi_stream (ob->main_stream, count); 961 streamer_write_hwi_stream (ob->main_stream, count);
969 if (!count) 962 if (!count)
970 return; 963 return;
971 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi) 964 EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
972 { 965 {
973 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value; 966 tree decl = (tree)splay_tree_lookup (reference_vars_to_consider,
967 index)->value;
974 lto_output_var_decl_index (ob->decl_state, ob->main_stream, decl); 968 lto_output_var_decl_index (ob->decl_state, ob->main_stream, decl);
975 } 969 }
976 } 970 }
977 971
978 /* Serialize the ipa info for lto. */ 972 /* Serialize the ipa info for lto. */
1058 = lto_get_file_decl_data (); 1052 = lto_get_file_decl_data ();
1059 struct lto_file_decl_data * file_data; 1053 struct lto_file_decl_data * file_data;
1060 unsigned int j = 0; 1054 unsigned int j = 0;
1061 bitmap_obstack_initialize (&optimization_summary_obstack); 1055 bitmap_obstack_initialize (&optimization_summary_obstack);
1062 1056
1063 node_removal_hook_holder = 1057 if (ipa_ref_opt_sum_summaries == NULL)
1064 symtab->add_cgraph_removal_hook (&remove_node_data, NULL); 1058 ipa_ref_opt_sum_summaries = new ipa_ref_opt_summary_t (symtab);
1065 node_duplication_hook_holder = 1059
1066 symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL);
1067 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack); 1060 all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
1068 1061
1069 while ((file_data = file_data_vec[j++])) 1062 while ((file_data = file_data_vec[j++]))
1070 { 1063 {
1071 const char *data; 1064 const char *data;
1097 1090
1098 for (i = 0; i < f_count; i++) 1091 for (i = 0; i < f_count; i++)
1099 { 1092 {
1100 unsigned int j, index; 1093 unsigned int j, index;
1101 struct cgraph_node *node; 1094 struct cgraph_node *node;
1102 ipa_reference_optimization_summary_t info;
1103 int v_count; 1095 int v_count;
1104 lto_symtab_encoder_t encoder; 1096 lto_symtab_encoder_t encoder;
1105 1097
1106 index = streamer_read_uhwi (ib); 1098 index = streamer_read_uhwi (ib);
1107 encoder = file_data->symtab_node_encoder; 1099 encoder = file_data->symtab_node_encoder;
1108 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref 1100 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref
1109 (encoder, index)); 1101 (encoder, index));
1110 info = XCNEW (struct ipa_reference_optimization_summary_d); 1102
1111 set_reference_optimization_summary (node, info); 1103 ipa_reference_optimization_summary_d *info
1112 info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack); 1104 = ipa_ref_opt_sum_summaries->get_create (node);
1113 info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack); 1105
1106 info->statics_not_read = BITMAP_ALLOC
1107 (&optimization_summary_obstack);
1108 info->statics_not_written = BITMAP_ALLOC
1109 (&optimization_summary_obstack);
1114 if (dump_file) 1110 if (dump_file)
1115 fprintf (dump_file, 1111 fprintf (dump_file,
1116 "\nFunction name:%s:\n static not read:", 1112 "\nFunction name:%s:\n static not read:",
1117 node->dump_asm_name ()); 1113 node->dump_asm_name ());
1118 1114
1165 lto_destroy_simple_input_block (file_data, 1161 lto_destroy_simple_input_block (file_data,
1166 LTO_section_ipa_reference, 1162 LTO_section_ipa_reference,
1167 ib, data, len); 1163 ib, data, len);
1168 } 1164 }
1169 else 1165 else
1170 /* Fatal error here. We do not want to support compiling ltrans units with 1166 /* Fatal error here. We do not want to support compiling ltrans units
1171 different version of compiler or different flags than the WPA unit, so 1167 with different version of compiler or different flags than
1172 this should never happen. */ 1168 the WPA unit, so this should never happen. */
1173 fatal_error (input_location, 1169 fatal_error (input_location,
1174 "ipa reference summary is missing in ltrans unit"); 1170 "ipa reference summary is missing in ltrans unit");
1175 } 1171 }
1176 } 1172 }
1177 1173
1232 within the same process. For use by toplev::finalize. */ 1228 within the same process. For use by toplev::finalize. */
1233 1229
1234 void 1230 void
1235 ipa_reference_c_finalize (void) 1231 ipa_reference_c_finalize (void)
1236 { 1232 {
1233 if (ipa_ref_opt_sum_summaries != NULL)
1234 {
1235 delete ipa_ref_opt_sum_summaries;
1236 ipa_ref_opt_sum_summaries = NULL;
1237 }
1238
1237 if (ipa_init_p) 1239 if (ipa_init_p)
1238 { 1240 {
1239 bitmap_obstack_release (&optimization_summary_obstack); 1241 bitmap_obstack_release (&optimization_summary_obstack);
1240 ipa_init_p = false; 1242 ipa_init_p = false;
1241 } 1243 }
1242 1244 }
1243 if (node_removal_hook_holder)
1244 {
1245 symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
1246 node_removal_hook_holder = NULL;
1247 }
1248 if (node_duplication_hook_holder)
1249 {
1250 symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
1251 node_duplication_hook_holder = NULL;
1252 }
1253 }