comparison gcc/sel-sched-ir.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 /* Instruction scheduling pass. Selective scheduler and pipeliner. 1 /* Instruction scheduling pass. Selective scheduler and pipeliner.
2 Copyright (C) 2006-2018 Free Software Foundation, Inc. 2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free 7 the terms of the GNU General Public License as published by the Free
31 #include "cfganal.h" 31 #include "cfganal.h"
32 #include "cfgbuild.h" 32 #include "cfgbuild.h"
33 #include "insn-config.h" 33 #include "insn-config.h"
34 #include "insn-attr.h" 34 #include "insn-attr.h"
35 #include "recog.h" 35 #include "recog.h"
36 #include "params.h"
37 #include "target.h" 36 #include "target.h"
38 #include "sched-int.h" 37 #include "sched-int.h"
39 #include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */ 38 #include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
40 39
41 #ifdef INSN_SCHEDULING 40 #ifdef INSN_SCHEDULING
59 58
60 /* Data structure to describe interaction with the generic scheduler utils. */ 59 /* Data structure to describe interaction with the generic scheduler utils. */
61 static struct common_sched_info_def sel_common_sched_info; 60 static struct common_sched_info_def sel_common_sched_info;
62 61
63 /* The loop nest being pipelined. */ 62 /* The loop nest being pipelined. */
64 struct loop *current_loop_nest; 63 class loop *current_loop_nest;
65 64
66 /* LOOP_NESTS is a vector containing the corresponding loop nest for 65 /* LOOP_NESTS is a vector containing the corresponding loop nest for
67 each region. */ 66 each region. */
68 static vec<loop_p> loop_nests; 67 static vec<loop_p> loop_nests;
69 68
309 { 308 {
310 while (*lp) 309 while (*lp)
311 flist_remove (lp); 310 flist_remove (lp);
312 } 311 }
313 312
314 /* Add ORIGINAL_INSN the def list DL honoring CROSSES_CALL. */ 313 /* Add ORIGINAL_INSN the def list DL honoring CROSSED_CALL_ABIS. */
315 void 314 void
316 def_list_add (def_list_t *dl, insn_t original_insn, bool crosses_call) 315 def_list_add (def_list_t *dl, insn_t original_insn,
316 unsigned int crossed_call_abis)
317 { 317 {
318 def_t d; 318 def_t d;
319 319
320 _list_add (dl); 320 _list_add (dl);
321 d = DEF_LIST_DEF (*dl); 321 d = DEF_LIST_DEF (*dl);
322 322
323 d->orig_insn = original_insn; 323 d->orig_insn = original_insn;
324 d->crosses_call = crosses_call; 324 d->crossed_call_abis = crossed_call_abis;
325 } 325 }
326 326
327 327
328 /* Functions to work with target contexts. */ 328 /* Functions to work with target contexts. */
329 329
422 clear_target_context (tc); 422 clear_target_context (tc);
423 init_target_context (tc, clean_p); 423 init_target_context (tc, clean_p);
424 } 424 }
425 425
426 /* Functions to work with dependence contexts. 426 /* Functions to work with dependence contexts.
427 Dc (aka deps context, aka deps_t, aka struct deps_desc *) is short for dependence 427 Dc (aka deps context, aka deps_t, aka class deps_desc *) is short for dependence
428 context. It accumulates information about processed insns to decide if 428 context. It accumulates information about processed insns to decide if
429 current insn is dependent on the processed ones. */ 429 current insn is dependent on the processed ones. */
430 430
431 /* Make a copy of FROM in TO. */ 431 /* Make a copy of FROM in TO. */
432 static void 432 static void
438 438
439 /* Allocate store for dep context. */ 439 /* Allocate store for dep context. */
440 static deps_t 440 static deps_t
441 alloc_deps_context (void) 441 alloc_deps_context (void)
442 { 442 {
443 return XNEW (struct deps_desc); 443 return XNEW (class deps_desc);
444 } 444 }
445 445
446 /* Allocate and initialize dep context. */ 446 /* Allocate and initialize dep context. */
447 static deps_t 447 static deps_t
448 create_deps_context (void) 448 create_deps_context (void)
701 FENCE_ISSUE_MORE (f) = issue_rate; 701 FENCE_ISSUE_MORE (f) = issue_rate;
702 } 702 }
703 else 703 else
704 if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn)) 704 if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn))
705 { 705 {
706 /* Would be weird if same insn is successor of several fallthrough
707 edges. */
708 gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb
709 != BLOCK_FOR_INSN (last_scheduled_insn_old));
710
711 state_free (FENCE_STATE (f)); 706 state_free (FENCE_STATE (f));
712 FENCE_STATE (f) = state; 707 FENCE_STATE (f) = state;
713 708
714 delete_target_context (FENCE_TC (f)); 709 delete_target_context (FENCE_TC (f));
715 FENCE_TC (f) = tc; 710 FENCE_TC (f) = tc;
2664 { 2659 {
2665 if (reload_completed) 2660 if (reload_completed)
2666 return; 2661 return;
2667 2662
2668 HARD_REG_SET temp; 2663 HARD_REG_SET temp;
2669 unsigned regno;
2670 hard_reg_set_iterator hrsi;
2671 2664
2672 get_implicit_reg_pending_clobbers (&temp, insn); 2665 get_implicit_reg_pending_clobbers (&temp, insn);
2673 EXECUTE_IF_SET_IN_HARD_REG_SET (temp, 0, regno, hrsi) 2666 IOR_REG_SET_HRS (IDATA_REG_SETS (id), temp);
2674 SET_REGNO_REG_SET (IDATA_REG_SETS (id), regno);
2675 } 2667 }
2676 2668
2677 /* Setup register sets describing INSN in ID. */ 2669 /* Setup register sets describing INSN in ID. */
2678 static void 2670 static void
2679 setup_id_reg_sets (idata_t id, insn_t insn) 2671 setup_id_reg_sets (idata_t id, insn_t insn)
2752 2744
2753 /* Initialize instruction data for INSN in ID. */ 2745 /* Initialize instruction data for INSN in ID. */
2754 static void 2746 static void
2755 deps_init_id (idata_t id, insn_t insn, bool force_unique_p) 2747 deps_init_id (idata_t id, insn_t insn, bool force_unique_p)
2756 { 2748 {
2757 struct deps_desc _dc, *dc = &_dc; 2749 class deps_desc _dc, *dc = &_dc;
2758 2750
2759 deps_init_id_data.where = DEPS_IN_NOWHERE; 2751 deps_init_id_data.where = DEPS_IN_NOWHERE;
2760 deps_init_id_data.id = id; 2752 deps_init_id_data.id = id;
2761 deps_init_id_data.force_unique_p = force_unique_p; 2753 deps_init_id_data.force_unique_p = force_unique_p;
2762 deps_init_id_data.force_use_p = false; 2754 deps_init_id_data.force_use_p = false;
3393 ds_t 3385 ds_t
3394 has_dependence_p (expr_t expr, insn_t pred, ds_t **has_dep_pp) 3386 has_dependence_p (expr_t expr, insn_t pred, ds_t **has_dep_pp)
3395 { 3387 {
3396 int i; 3388 int i;
3397 ds_t ds; 3389 ds_t ds;
3398 struct deps_desc *dc; 3390 class deps_desc *dc;
3399 3391
3400 if (INSN_SIMPLEJUMP_P (pred)) 3392 if (INSN_SIMPLEJUMP_P (pred))
3401 /* Unconditional jump is just a transfer of control flow. 3393 /* Unconditional jump is just a transfer of control flow.
3402 Ignore it. */ 3394 Ignore it. */
3403 return false; 3395 return false;
3780 { 3772 {
3781 pred_bb = e->src; 3773 pred_bb = e->src;
3782 3774
3783 if (!(e->flags & EDGE_FALLTHRU)) 3775 if (!(e->flags & EDGE_FALLTHRU))
3784 { 3776 {
3785 /* We can not invalidate computed topological order by moving 3777 /* We cannot invalidate computed topological order by moving
3786 the edge destination block (E->SUCC) along a fallthru edge. 3778 the edge destination block (E->SUCC) along a fallthru edge.
3787 3779
3788 We will update dominators here only when we'll get 3780 We will update dominators here only when we'll get
3789 an unreachable block when redirecting, otherwise 3781 an unreachable block when redirecting, otherwise
3790 sel_redirect_edge_and_branch will take care of it. */ 3782 sel_redirect_edge_and_branch will take care of it. */
5400 { 5392 {
5401 gcc_assert (from != to); 5393 gcc_assert (from != to);
5402 5394
5403 if (current_loop_nest) 5395 if (current_loop_nest)
5404 { 5396 {
5405 struct loop *loop; 5397 class loop *loop;
5406 5398
5407 for (loop = current_loop_nest; loop; loop = loop_outer (loop)) 5399 for (loop = current_loop_nest; loop; loop = loop_outer (loop))
5408 if (considered_for_pipelining_p (loop) && loop->latch == from) 5400 if (considered_for_pipelining_p (loop) && loop->latch == from)
5409 { 5401 {
5410 gcc_assert (loop == current_loop_nest); 5402 gcc_assert (loop == current_loop_nest);
5640 old_seqno); 5632 old_seqno);
5641 set_immediate_dominator (CDI_DOMINATORS, to, 5633 set_immediate_dominator (CDI_DOMINATORS, to,
5642 recompute_dominator (CDI_DOMINATORS, to)); 5634 recompute_dominator (CDI_DOMINATORS, to));
5643 set_immediate_dominator (CDI_DOMINATORS, orig_dest, 5635 set_immediate_dominator (CDI_DOMINATORS, orig_dest,
5644 recompute_dominator (CDI_DOMINATORS, orig_dest)); 5636 recompute_dominator (CDI_DOMINATORS, orig_dest));
5637 if (jump && sel_bb_head_p (jump))
5638 compute_live (jump);
5645 } 5639 }
5646 5640
5647 /* A wrapper for redirect_edge_and_branch. Return TRUE if blocks connected by 5641 /* A wrapper for redirect_edge_and_branch. Return TRUE if blocks connected by
5648 redirected edge are in reverse topological order. */ 5642 redirected edge are in reverse topological order. */
5649 bool 5643 bool
5700 set_immediate_dominator (CDI_DOMINATORS, to, 5694 set_immediate_dominator (CDI_DOMINATORS, to,
5701 recompute_dominator (CDI_DOMINATORS, to)); 5695 recompute_dominator (CDI_DOMINATORS, to));
5702 set_immediate_dominator (CDI_DOMINATORS, orig_dest, 5696 set_immediate_dominator (CDI_DOMINATORS, orig_dest,
5703 recompute_dominator (CDI_DOMINATORS, orig_dest)); 5697 recompute_dominator (CDI_DOMINATORS, orig_dest));
5704 } 5698 }
5699 if (jump && sel_bb_head_p (jump))
5700 compute_live (jump);
5705 return recompute_toporder_p; 5701 return recompute_toporder_p;
5706 } 5702 }
5707 5703
5708 /* This variable holds the cfg hooks used by the selective scheduler. */ 5704 /* This variable holds the cfg hooks used by the selective scheduler. */
5709 static struct cfg_hooks sel_cfg_hooks; 5705 static struct cfg_hooks sel_cfg_hooks;
6001 } 5997 }
6002 5998
6003 /* Create a region for LOOP and return its number. If we don't want 5999 /* Create a region for LOOP and return its number. If we don't want
6004 to pipeline LOOP, return -1. */ 6000 to pipeline LOOP, return -1. */
6005 static int 6001 static int
6006 make_region_from_loop (struct loop *loop) 6002 make_region_from_loop (class loop *loop)
6007 { 6003 {
6008 unsigned int i; 6004 unsigned int i;
6009 int new_rgn_number = -1; 6005 int new_rgn_number = -1;
6010 struct loop *inner; 6006 class loop *inner;
6011 6007
6012 /* Basic block index, to be assigned to BLOCK_TO_BB. */ 6008 /* Basic block index, to be assigned to BLOCK_TO_BB. */
6013 int bb_ord_index = 0; 6009 int bb_ord_index = 0;
6014 basic_block *loop_blocks; 6010 basic_block *loop_blocks;
6015 basic_block preheader_block; 6011 basic_block preheader_block;
6016 6012
6017 if (loop->num_nodes 6013 if (loop->num_nodes
6018 > (unsigned) PARAM_VALUE (PARAM_MAX_PIPELINE_REGION_BLOCKS)) 6014 > (unsigned) param_max_pipeline_region_blocks)
6019 return -1; 6015 return -1;
6020 6016
6021 /* Don't pipeline loops whose latch belongs to some of its inner loops. */ 6017 /* Don't pipeline loops whose latch belongs to some of its inner loops. */
6022 for (inner = loop->inner; inner; inner = inner->inner) 6018 for (inner = loop->inner; inner; inner = inner->inner)
6023 if (flow_bb_inside_loop_p (inner, loop->latch)) 6019 if (flow_bb_inside_loop_p (inner, loop->latch))
6024 return -1; 6020 return -1;
6025 6021
6026 loop->ninsns = num_loop_insns (loop); 6022 loop->ninsns = num_loop_insns (loop);
6027 if ((int) loop->ninsns > PARAM_VALUE (PARAM_MAX_PIPELINE_REGION_INSNS)) 6023 if ((int) loop->ninsns > param_max_pipeline_region_insns)
6028 return -1; 6024 return -1;
6029 6025
6030 loop_blocks = get_loop_body_in_custom_order (loop, bb_top_order_comparator); 6026 loop_blocks = get_loop_body_in_custom_order (loop, bb_top_order_comparator);
6031 6027
6032 for (i = 0; i < loop->num_nodes; i++) 6028 for (i = 0; i < loop->num_nodes; i++)
6094 6090
6095 /* Create region(s) from loop nest LOOP, such that inner loops will be 6091 /* Create region(s) from loop nest LOOP, such that inner loops will be
6096 pipelined before outer loops. Returns true when a region for LOOP 6092 pipelined before outer loops. Returns true when a region for LOOP
6097 is created. */ 6093 is created. */
6098 static bool 6094 static bool
6099 make_regions_from_loop_nest (struct loop *loop) 6095 make_regions_from_loop_nest (class loop *loop)
6100 { 6096 {
6101 struct loop *cur_loop; 6097 class loop *cur_loop;
6102 int rgn_number; 6098 int rgn_number;
6103 6099
6104 /* Traverse all inner nodes of the loop. */ 6100 /* Traverse all inner nodes of the loop. */
6105 for (cur_loop = loop->inner; cur_loop; cur_loop = cur_loop->next) 6101 for (cur_loop = loop->inner; cur_loop; cur_loop = cur_loop->next)
6106 if (! bitmap_bit_p (bbs_in_loop_rgns, cur_loop->header->index)) 6102 if (! bitmap_bit_p (bbs_in_loop_rgns, cur_loop->header->index))
6132 bitmap_clear (bbs_in_loop_rgns); 6128 bitmap_clear (bbs_in_loop_rgns);
6133 6129
6134 recompute_rev_top_order (); 6130 recompute_rev_top_order ();
6135 } 6131 }
6136 6132
6137 /* Returns a struct loop for region RGN. */ 6133 /* Returns a class loop for region RGN. */
6138 loop_p 6134 loop_p
6139 get_loop_nest_for_rgn (unsigned int rgn) 6135 get_loop_nest_for_rgn (unsigned int rgn)
6140 { 6136 {
6141 /* Regions created with extend_rgns don't have corresponding loop nests, 6137 /* Regions created with extend_rgns don't have corresponding loop nests,
6142 because they don't represent loops. */ 6138 because they don't represent loops. */
6146 return NULL; 6142 return NULL;
6147 } 6143 }
6148 6144
6149 /* True when LOOP was included into pipelining regions. */ 6145 /* True when LOOP was included into pipelining regions. */
6150 bool 6146 bool
6151 considered_for_pipelining_p (struct loop *loop) 6147 considered_for_pipelining_p (class loop *loop)
6152 { 6148 {
6153 if (loop_depth (loop) == 0) 6149 if (loop_depth (loop) == 0)
6154 return false; 6150 return false;
6155 6151
6156 /* Now, the loop could be too large or irreducible. Check whether its 6152 /* Now, the loop could be too large or irreducible. Check whether its
6248 } 6244 }
6249 6245
6250 /* Free data structures used in pipelining of loops. */ 6246 /* Free data structures used in pipelining of loops. */
6251 void sel_finish_pipelining (void) 6247 void sel_finish_pipelining (void)
6252 { 6248 {
6253 struct loop *loop; 6249 class loop *loop;
6254 6250
6255 /* Release aux fields so we don't free them later by mistake. */ 6251 /* Release aux fields so we don't free them later by mistake. */
6256 FOR_EACH_LOOP (loop, 0) 6252 FOR_EACH_LOOP (loop, 0)
6257 loop->aux = NULL; 6253 loop->aux = NULL;
6258 6254
6323 bool 6319 bool
6324 sel_is_loop_preheader_p (basic_block bb) 6320 sel_is_loop_preheader_p (basic_block bb)
6325 { 6321 {
6326 if (current_loop_nest) 6322 if (current_loop_nest)
6327 { 6323 {
6328 struct loop *outer; 6324 class loop *outer;
6329 6325
6330 if (preheader_removed) 6326 if (preheader_removed)
6331 return false; 6327 return false;
6332 6328
6333 /* Preheader is the first block in the region. */ 6329 /* Preheader is the first block in the region. */