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;