Mercurial > hg > CbC > CbC_gcc
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. */ |