Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-outof-ssa.c @ 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 /* Convert a program in SSA form into Normal form. | 1 /* Convert a program in SSA form into Normal form. |
2 Copyright (C) 2004-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2004-2020 Free Software Foundation, Inc. |
3 Contributed by Andrew Macleod <amacleod@redhat.com> | 3 Contributed by Andrew Macleod <amacleod@redhat.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 | 7 GCC is free software; you can redistribute it and/or modify |
127 3, and in a bootstrap of GCC, the maximum size encountered was 7. | 127 3, and in a bootstrap of GCC, the maximum size encountered was 7. |
128 This also limits the number of possible nodes that are involved to | 128 This also limits the number of possible nodes that are involved to |
129 rarely more than 6, and in the bootstrap of gcc, the maximum number | 129 rarely more than 6, and in the bootstrap of gcc, the maximum number |
130 of nodes encountered was 12. */ | 130 of nodes encountered was 12. */ |
131 | 131 |
132 struct elim_graph | 132 class elim_graph |
133 { | 133 { |
134 public: | |
134 elim_graph (var_map map); | 135 elim_graph (var_map map); |
135 | 136 |
136 /* Size of the elimination vectors. */ | 137 /* Size of the elimination vectors. */ |
137 int size; | 138 int size; |
138 | 139 |
141 | 142 |
142 /* The predecessor and successor edge list. */ | 143 /* The predecessor and successor edge list. */ |
143 auto_vec<int> edge_list; | 144 auto_vec<int> edge_list; |
144 | 145 |
145 /* Source locus on each edge */ | 146 /* Source locus on each edge */ |
146 auto_vec<source_location> edge_locus; | 147 auto_vec<location_t> edge_locus; |
147 | 148 |
148 /* Visited vector. */ | 149 /* Visited vector. */ |
149 auto_sbitmap visited; | 150 auto_sbitmap visited; |
150 | 151 |
151 /* Stack for visited nodes. */ | 152 /* Stack for visited nodes. */ |
160 /* List of constant copies to emit. These are pushed on in pairs. */ | 161 /* List of constant copies to emit. These are pushed on in pairs. */ |
161 auto_vec<int> const_dests; | 162 auto_vec<int> const_dests; |
162 auto_vec<tree> const_copies; | 163 auto_vec<tree> const_copies; |
163 | 164 |
164 /* Source locations for any constant copies. */ | 165 /* Source locations for any constant copies. */ |
165 auto_vec<source_location> copy_locus; | 166 auto_vec<location_t> copy_locus; |
166 }; | 167 }; |
167 | 168 |
168 | 169 |
169 /* For an edge E find out a good source location to associate with | 170 /* For an edge E find out a good source location to associate with |
170 instructions inserted on edge E. If E has an implicit goto set, | 171 instructions inserted on edge E. If E has an implicit goto set, |
171 use its location. Otherwise search instructions in predecessors | 172 use its location. Otherwise search instructions in predecessors |
172 of E for a location, and use that one. That makes sense because | 173 of E for a location, and use that one. That makes sense because |
173 we insert on edges for PHI nodes, and effects of PHIs happen on | 174 we insert on edges for PHI nodes, and effects of PHIs happen on |
174 the end of the predecessor conceptually. */ | 175 the end of the predecessor conceptually. An exception is made |
176 for EH edges because we don't want to drag the source location | |
177 of unrelated statements at the beginning of handlers; they would | |
178 be further reused for various EH constructs, which would damage | |
179 the coverage information. */ | |
175 | 180 |
176 static void | 181 static void |
177 set_location_for_edge (edge e) | 182 set_location_for_edge (edge e) |
178 { | 183 { |
179 if (e->goto_locus) | 184 if (e->goto_locus) |
180 { | 185 set_curr_insn_location (e->goto_locus); |
181 set_curr_insn_location (e->goto_locus); | 186 else if (e->flags & EDGE_EH) |
187 { | |
188 basic_block bb = e->dest; | |
189 gimple_stmt_iterator gsi; | |
190 | |
191 do | |
192 { | |
193 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
194 { | |
195 gimple *stmt = gsi_stmt (gsi); | |
196 if (is_gimple_debug (stmt)) | |
197 continue; | |
198 if (gimple_has_location (stmt) || gimple_block (stmt)) | |
199 { | |
200 set_curr_insn_location (gimple_location (stmt)); | |
201 return; | |
202 } | |
203 } | |
204 /* Nothing found in this basic block. Make a half-assed attempt | |
205 to continue with another block. */ | |
206 if (single_succ_p (bb)) | |
207 bb = single_succ (bb); | |
208 else | |
209 bb = e->dest; | |
210 } | |
211 while (bb != e->dest); | |
182 } | 212 } |
183 else | 213 else |
184 { | 214 { |
185 basic_block bb = e->src; | 215 basic_block bb = e->src; |
186 gimple_stmt_iterator gsi; | 216 gimple_stmt_iterator gsi; |
236 } | 266 } |
237 | 267 |
238 /* Insert a copy instruction from partition SRC to DEST onto edge E. */ | 268 /* Insert a copy instruction from partition SRC to DEST onto edge E. */ |
239 | 269 |
240 static void | 270 static void |
241 insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus) | 271 insert_partition_copy_on_edge (edge e, int dest, int src, location_t locus) |
242 { | 272 { |
243 tree var; | 273 tree var; |
244 if (dump_file && (dump_flags & TDF_DETAILS)) | 274 if (dump_file && (dump_flags & TDF_DETAILS)) |
245 { | 275 { |
246 fprintf (dump_file, | 276 fprintf (dump_file, |
270 | 300 |
271 /* Insert a copy instruction from expression SRC to partition DEST | 301 /* Insert a copy instruction from expression SRC to partition DEST |
272 onto edge E. */ | 302 onto edge E. */ |
273 | 303 |
274 static void | 304 static void |
275 insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus) | 305 insert_value_copy_on_edge (edge e, int dest, tree src, location_t locus) |
276 { | 306 { |
277 rtx dest_rtx, seq, x; | 307 rtx dest_rtx, seq, x; |
278 machine_mode dest_mode, src_mode; | 308 machine_mode dest_mode, src_mode; |
279 int unsignedp; | 309 int unsignedp; |
280 | 310 |
331 /* Insert a copy instruction from RTL expression SRC to partition DEST | 361 /* Insert a copy instruction from RTL expression SRC to partition DEST |
332 onto edge E. */ | 362 onto edge E. */ |
333 | 363 |
334 static void | 364 static void |
335 insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp, | 365 insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp, |
336 source_location locus) | 366 location_t locus) |
337 { | 367 { |
338 if (dump_file && (dump_flags & TDF_DETAILS)) | 368 if (dump_file && (dump_flags & TDF_DETAILS)) |
339 { | 369 { |
340 fprintf (dump_file, | 370 fprintf (dump_file, |
341 "Inserting a temp copy on edge BB%d->BB%d : PART.%d = ", | 371 "Inserting a temp copy on edge BB%d->BB%d : PART.%d = ", |
365 | 395 |
366 /* Insert a copy instruction from partition SRC to RTL lvalue DEST | 396 /* Insert a copy instruction from partition SRC to RTL lvalue DEST |
367 onto edge E. */ | 397 onto edge E. */ |
368 | 398 |
369 static void | 399 static void |
370 insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus) | 400 insert_part_to_rtx_on_edge (edge e, rtx dest, int src, location_t locus) |
371 { | 401 { |
372 tree var; | 402 tree var; |
373 if (dump_file && (dump_flags & TDF_DETAILS)) | 403 if (dump_file && (dump_flags & TDF_DETAILS)) |
374 { | 404 { |
375 fprintf (dump_file, | 405 fprintf (dump_file, |
442 | 472 |
443 | 473 |
444 /* Add the edge PRED->SUCC to graph G. */ | 474 /* Add the edge PRED->SUCC to graph G. */ |
445 | 475 |
446 static inline void | 476 static inline void |
447 elim_graph_add_edge (elim_graph *g, int pred, int succ, source_location locus) | 477 elim_graph_add_edge (elim_graph *g, int pred, int succ, location_t locus) |
448 { | 478 { |
449 g->edge_list.safe_push (pred); | 479 g->edge_list.safe_push (pred); |
450 g->edge_list.safe_push (succ); | 480 g->edge_list.safe_push (succ); |
451 g->edge_locus.safe_push (locus); | 481 g->edge_locus.safe_push (locus); |
452 } | 482 } |
454 | 484 |
455 /* Remove an edge from graph G for which NODE is the predecessor, and | 485 /* Remove an edge from graph G for which NODE is the predecessor, and |
456 return the successor node. -1 is returned if there is no such edge. */ | 486 return the successor node. -1 is returned if there is no such edge. */ |
457 | 487 |
458 static inline int | 488 static inline int |
459 elim_graph_remove_succ_edge (elim_graph *g, int node, source_location *locus) | 489 elim_graph_remove_succ_edge (elim_graph *g, int node, location_t *locus) |
460 { | 490 { |
461 int y; | 491 int y; |
462 unsigned x; | 492 unsigned x; |
463 for (x = 0; x < g->edge_list.length (); x += 2) | 493 for (x = 0; x < g->edge_list.length (); x += 2) |
464 if (g->edge_list[x] == node) | 494 if (g->edge_list[x] == node) |
554 clear_elim_graph (g); | 584 clear_elim_graph (g); |
555 | 585 |
556 for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) | 586 for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) |
557 { | 587 { |
558 gphi *phi = gsi.phi (); | 588 gphi *phi = gsi.phi (); |
559 source_location locus; | 589 location_t locus; |
560 | 590 |
561 p0 = var_to_partition (g->map, gimple_phi_result (phi)); | 591 p0 = var_to_partition (g->map, gimple_phi_result (phi)); |
562 /* Ignore results which are not in partitions. */ | 592 /* Ignore results which are not in partitions. */ |
563 if (p0 == NO_PARTITION) | 593 if (p0 == NO_PARTITION) |
564 continue; | 594 continue; |
565 | 595 |
566 Ti = PHI_ARG_DEF (phi, g->e->dest_idx); | 596 Ti = PHI_ARG_DEF (phi, g->e->dest_idx); |
567 locus = gimple_phi_arg_location_from_edge (phi, g->e); | 597 /* See set_location_for_edge for the rationale. */ |
598 if (g->e->flags & EDGE_EH) | |
599 locus = UNKNOWN_LOCATION; | |
600 else | |
601 locus = gimple_phi_arg_location_from_edge (phi, g->e); | |
568 | 602 |
569 /* If this argument is a constant, or a SSA_NAME which is being | 603 /* If this argument is a constant, or a SSA_NAME which is being |
570 left in SSA form, just queue a copy to be emitted on this | 604 left in SSA form, just queue a copy to be emitted on this |
571 edge. */ | 605 edge. */ |
572 if (queue_phi_copy_p (g->map, Ti)) | 606 if (queue_phi_copy_p (g->map, Ti)) |
595 | 629 |
596 static void | 630 static void |
597 elim_forward (elim_graph *g, int T) | 631 elim_forward (elim_graph *g, int T) |
598 { | 632 { |
599 int S; | 633 int S; |
600 source_location locus; | 634 location_t locus; |
601 | 635 |
602 bitmap_set_bit (g->visited, T); | 636 bitmap_set_bit (g->visited, T); |
603 FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, | 637 FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, |
604 { | 638 { |
605 if (!bitmap_bit_p (g->visited, S)) | 639 if (!bitmap_bit_p (g->visited, S)) |
613 | 647 |
614 static int | 648 static int |
615 elim_unvisited_predecessor (elim_graph *g, int T) | 649 elim_unvisited_predecessor (elim_graph *g, int T) |
616 { | 650 { |
617 int P; | 651 int P; |
618 source_location locus; | 652 location_t locus; |
619 | 653 |
620 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, | 654 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, |
621 { | 655 { |
622 if (!bitmap_bit_p (g->visited, P)) | 656 if (!bitmap_bit_p (g->visited, P)) |
623 return 1; | 657 return 1; |
629 | 663 |
630 static void | 664 static void |
631 elim_backward (elim_graph *g, int T) | 665 elim_backward (elim_graph *g, int T) |
632 { | 666 { |
633 int P; | 667 int P; |
634 source_location locus; | 668 location_t locus; |
635 | 669 |
636 bitmap_set_bit (g->visited, T); | 670 bitmap_set_bit (g->visited, T); |
637 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, | 671 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, |
638 { | 672 { |
639 if (!bitmap_bit_p (g->visited, P)) | 673 if (!bitmap_bit_p (g->visited, P)) |
651 get_temp_reg (tree name) | 685 get_temp_reg (tree name) |
652 { | 686 { |
653 tree type = TREE_TYPE (name); | 687 tree type = TREE_TYPE (name); |
654 int unsignedp; | 688 int unsignedp; |
655 machine_mode reg_mode = promote_ssa_mode (name, &unsignedp); | 689 machine_mode reg_mode = promote_ssa_mode (name, &unsignedp); |
690 if (reg_mode == BLKmode) | |
691 return assign_temp (type, 0, 0); | |
656 rtx x = gen_reg_rtx (reg_mode); | 692 rtx x = gen_reg_rtx (reg_mode); |
657 if (POINTER_TYPE_P (type)) | 693 if (POINTER_TYPE_P (type)) |
658 mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (type))); | 694 mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (type))); |
659 return x; | 695 return x; |
660 } | 696 } |
664 | 700 |
665 static void | 701 static void |
666 elim_create (elim_graph *g, int T) | 702 elim_create (elim_graph *g, int T) |
667 { | 703 { |
668 int P, S; | 704 int P, S; |
669 source_location locus; | 705 location_t locus; |
670 | 706 |
671 if (elim_unvisited_predecessor (g, T)) | 707 if (elim_unvisited_predecessor (g, T)) |
672 { | 708 { |
673 tree var = partition_to_var (g->map, T); | 709 tree var = partition_to_var (g->map, T); |
674 rtx U = get_temp_reg (var); | 710 rtx U = get_temp_reg (var); |
739 /* If there are any pending constant copies, issue them now. */ | 775 /* If there are any pending constant copies, issue them now. */ |
740 while (g->const_copies.length () > 0) | 776 while (g->const_copies.length () > 0) |
741 { | 777 { |
742 int dest; | 778 int dest; |
743 tree src; | 779 tree src; |
744 source_location locus; | 780 location_t locus; |
745 | 781 |
746 src = g->const_copies.pop (); | 782 src = g->const_copies.pop (); |
747 dest = g->const_dests.pop (); | 783 dest = g->const_dests.pop (); |
748 locus = g->copy_locus.pop (); | 784 locus = g->copy_locus.pop (); |
749 insert_value_copy_on_edge (e, dest, src, locus); | 785 insert_value_copy_on_edge (e, dest, src, locus); |
807 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) | 843 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) |
808 { | 844 { |
809 gphi *phi = gsi.phi (); | 845 gphi *phi = gsi.phi (); |
810 result = gimple_phi_result (phi); | 846 result = gimple_phi_result (phi); |
811 if (virtual_operand_p (result)) | 847 if (virtual_operand_p (result)) |
812 { | 848 remove_phi_node (&gsi, true); |
813 /* There should be no arguments which are not virtual, or the | |
814 results will be incorrect. */ | |
815 if (flag_checking) | |
816 for (size_t i = 0; i < gimple_phi_num_args (phi); i++) | |
817 { | |
818 tree arg = PHI_ARG_DEF (phi, i); | |
819 if (TREE_CODE (arg) == SSA_NAME | |
820 && !virtual_operand_p (arg)) | |
821 { | |
822 fprintf (stderr, "Argument of PHI is not virtual ("); | |
823 print_generic_expr (stderr, arg, TDF_SLIM); | |
824 fprintf (stderr, "), but the result is :"); | |
825 print_gimple_stmt (stderr, phi, 0, TDF_SLIM); | |
826 internal_error ("SSA corruption"); | |
827 } | |
828 } | |
829 | |
830 remove_phi_node (&gsi, true); | |
831 } | |
832 else | 849 else |
833 { | 850 { |
834 /* Also remove real PHIs with no uses. */ | 851 /* Also remove real PHIs with no uses. */ |
835 if (has_zero_uses (result)) | 852 if (has_zero_uses (result)) |
836 { | 853 { |
1169 | 1186 |
1170 for (i = 0; i < gimple_phi_num_args (phi); i++) | 1187 for (i = 0; i < gimple_phi_num_args (phi); i++) |
1171 { | 1188 { |
1172 tree arg = gimple_phi_arg_def (phi, i); | 1189 tree arg = gimple_phi_arg_def (phi, i); |
1173 edge e = gimple_phi_arg_edge (phi, i); | 1190 edge e = gimple_phi_arg_edge (phi, i); |
1191 /* We are only interested in copies emitted on critical | |
1192 backedges. */ | |
1193 if (!(e->flags & EDGE_DFS_BACK) | |
1194 || !EDGE_CRITICAL_P (e)) | |
1195 continue; | |
1174 | 1196 |
1175 /* If the argument is not an SSA_NAME, then we will need a | 1197 /* If the argument is not an SSA_NAME, then we will need a |
1176 constant initialization. If the argument is an SSA_NAME with | 1198 constant initialization. If the argument is an SSA_NAME then |
1177 a different underlying variable then a copy statement will be | 1199 a copy statement may be needed. First handle the case |
1178 needed. */ | 1200 where we cannot insert before the argument definition. */ |
1179 if ((e->flags & EDGE_DFS_BACK) | 1201 if (TREE_CODE (arg) != SSA_NAME |
1180 && (TREE_CODE (arg) != SSA_NAME | 1202 || (gimple_code (SSA_NAME_DEF_STMT (arg)) == GIMPLE_PHI |
1181 || SSA_NAME_VAR (arg) != SSA_NAME_VAR (result) | 1203 && trivially_conflicts_p (bb, result, arg))) |
1182 || trivially_conflicts_p (bb, result, arg))) | |
1183 { | 1204 { |
1184 tree name; | 1205 tree name; |
1185 gassign *stmt; | 1206 gassign *stmt; |
1186 gimple *last = NULL; | 1207 gimple *last = NULL; |
1187 gimple_stmt_iterator gsi2; | 1208 gimple_stmt_iterator gsi2; |
1224 gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); | 1245 gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); |
1225 else | 1246 else |
1226 gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT); | 1247 gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT); |
1227 SET_PHI_ARG_DEF (phi, i, name); | 1248 SET_PHI_ARG_DEF (phi, i, name); |
1228 } | 1249 } |
1250 /* Insert a copy before the definition of the backedge value | |
1251 and adjust all conflicting uses. */ | |
1252 else if (trivially_conflicts_p (bb, result, arg)) | |
1253 { | |
1254 gimple *def = SSA_NAME_DEF_STMT (arg); | |
1255 if (gimple_nop_p (def) | |
1256 || gimple_code (def) == GIMPLE_PHI) | |
1257 continue; | |
1258 tree name = copy_ssa_name (result); | |
1259 gimple *stmt = gimple_build_assign (name, result); | |
1260 imm_use_iterator imm_iter; | |
1261 gimple *use_stmt; | |
1262 /* The following matches trivially_conflicts_p. */ | |
1263 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, result) | |
1264 { | |
1265 if (gimple_bb (use_stmt) != bb | |
1266 || (gimple_code (use_stmt) != GIMPLE_PHI | |
1267 && (maybe_renumber_stmts_bb (bb), true) | |
1268 && gimple_uid (use_stmt) > gimple_uid (def))) | |
1269 { | |
1270 use_operand_p use; | |
1271 FOR_EACH_IMM_USE_ON_STMT (use, imm_iter) | |
1272 SET_USE (use, name); | |
1273 } | |
1274 } | |
1275 gimple_stmt_iterator gsi = gsi_for_stmt (def); | |
1276 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); | |
1277 } | |
1229 } | 1278 } |
1230 } | 1279 } |
1231 | 1280 |
1232 /* Unmark this block again. */ | 1281 /* Unmark this block again. */ |
1233 bb->aux = NULL; | 1282 bb->aux = NULL; |