Mercurial > hg > CbC > CbC_gcc
comparison gcc/cfgcleanup.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 /* Control flow optimization code for GNU compiler. | 1 /* Control flow optimization code for GNU compiler. |
2 Copyright (C) 1987-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1987-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 |
41 #include "memmodel.h" | 41 #include "memmodel.h" |
42 #include "tm_p.h" | 42 #include "tm_p.h" |
43 #include "insn-config.h" | 43 #include "insn-config.h" |
44 #include "emit-rtl.h" | 44 #include "emit-rtl.h" |
45 #include "cselib.h" | 45 #include "cselib.h" |
46 #include "params.h" | |
47 #include "tree-pass.h" | 46 #include "tree-pass.h" |
48 #include "cfgloop.h" | 47 #include "cfgloop.h" |
49 #include "cfgrtl.h" | 48 #include "cfgrtl.h" |
50 #include "cfganal.h" | 49 #include "cfganal.h" |
51 #include "cfgbuild.h" | 50 #include "cfgbuild.h" |
52 #include "cfgcleanup.h" | 51 #include "cfgcleanup.h" |
53 #include "dce.h" | 52 #include "dce.h" |
54 #include "dbgcnt.h" | 53 #include "dbgcnt.h" |
55 #include "rtl-iter.h" | 54 #include "rtl-iter.h" |
55 #include "regs.h" | |
56 #include "function-abi.h" | |
56 | 57 |
57 #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) | 58 #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) |
58 | 59 |
59 /* Set to true when we are running first pass of try_optimize_cfg loop. */ | 60 /* Set to true when we are running first pass of try_optimize_cfg loop. */ |
60 static bool first_pass; | 61 static bool first_pass; |
255 unsigned i; | 256 unsigned i; |
256 regset nonequal; | 257 regset nonequal; |
257 bool failed = false; | 258 bool failed = false; |
258 reg_set_iterator rsi; | 259 reg_set_iterator rsi; |
259 | 260 |
261 /* Jump threading may cause fixup_partitions to introduce new crossing edges, | |
262 which is not allowed after reload. */ | |
263 gcc_checking_assert (!reload_completed || !crtl->has_bb_partition); | |
264 | |
260 if (b->flags & BB_NONTHREADABLE_BLOCK) | 265 if (b->flags & BB_NONTHREADABLE_BLOCK) |
261 return NULL; | 266 return NULL; |
262 | 267 |
263 /* At the moment, we do handle only conditional jumps, but later we may | 268 /* At the moment, we do handle only conditional jumps, but later we may |
264 want to extend this code to tablejumps and others. */ | 269 want to extend this code to tablejumps and others. */ |
304 ??? This is far too pessimistic. We should allow swapped operands, | 309 ??? This is far too pessimistic. We should allow swapped operands, |
305 different CCmodes, or for example comparisons for interval, that | 310 different CCmodes, or for example comparisons for interval, that |
306 dominate even when operands are not equivalent. */ | 311 dominate even when operands are not equivalent. */ |
307 if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0)) | 312 if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0)) |
308 || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))) | 313 || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))) |
314 return NULL; | |
315 | |
316 /* Punt if BB_END (e->src) is doloop-like conditional jump that modifies | |
317 the registers used in cond1. */ | |
318 if (modified_in_p (cond1, BB_END (e->src))) | |
309 return NULL; | 319 return NULL; |
310 | 320 |
311 /* Short circuit cases where block B contains some side effects, as we can't | 321 /* Short circuit cases where block B contains some side effects, as we can't |
312 safely bypass it. */ | 322 safely bypass it. */ |
313 for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b)); | 323 for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b)); |
336 | 346 |
337 for (insn = NEXT_INSN (BB_HEAD (b)); | 347 for (insn = NEXT_INSN (BB_HEAD (b)); |
338 insn != NEXT_INSN (BB_END (b)) && !failed; | 348 insn != NEXT_INSN (BB_END (b)) && !failed; |
339 insn = NEXT_INSN (insn)) | 349 insn = NEXT_INSN (insn)) |
340 { | 350 { |
351 /* cond2 must not mention any register that is not equal to the | |
352 former block. Check this before processing that instruction, | |
353 as BB_END (b) could contain also clobbers. */ | |
354 if (insn == BB_END (b) | |
355 && mentions_nonequal_regs (cond2, nonequal)) | |
356 goto failed_exit; | |
357 | |
341 if (INSN_P (insn)) | 358 if (INSN_P (insn)) |
342 { | 359 { |
343 rtx pat = PATTERN (insn); | 360 rtx pat = PATTERN (insn); |
344 | 361 |
345 if (GET_CODE (pat) == PARALLEL) | 362 if (GET_CODE (pat) == PARALLEL) |
359 if (failed) | 376 if (failed) |
360 { | 377 { |
361 b->flags |= BB_NONTHREADABLE_BLOCK; | 378 b->flags |= BB_NONTHREADABLE_BLOCK; |
362 goto failed_exit; | 379 goto failed_exit; |
363 } | 380 } |
364 | |
365 /* cond2 must not mention any register that is not equal to the | |
366 former block. */ | |
367 if (mentions_nonequal_regs (cond2, nonequal)) | |
368 goto failed_exit; | |
369 | 381 |
370 EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi) | 382 EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi) |
371 goto failed_exit; | 383 goto failed_exit; |
372 | 384 |
373 BITMAP_FREE (nonequal); | 385 BITMAP_FREE (nonequal); |
1215 <= BUILT_IN_ASAN_STOREN) | 1227 <= BUILT_IN_ASAN_STOREN) |
1216 return dir_none; | 1228 return dir_none; |
1217 } | 1229 } |
1218 } | 1230 } |
1219 } | 1231 } |
1232 | |
1233 if (insn_callee_abi (i1) != insn_callee_abi (i2)) | |
1234 return dir_none; | |
1220 } | 1235 } |
1221 | 1236 |
1222 /* If both i1 and i2 are frame related, verify all the CFA notes | 1237 /* If both i1 and i2 are frame related, verify all the CFA notes |
1223 in the same order and with the same content. */ | 1238 in the same order and with the same content. */ |
1224 if (RTX_FRAME_RELATED_P (i1) && !insns_have_identical_cfa_notes (i1, i2)) | 1239 if (RTX_FRAME_RELATED_P (i1) && !insns_have_identical_cfa_notes (i1, i2)) |
1247 | 1262 |
1248 for (note = REG_NOTES (i2); note; note = XEXP (note, 1)) | 1263 for (note = REG_NOTES (i2); note; note = XEXP (note, 1)) |
1249 if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) | 1264 if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) |
1250 SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); | 1265 SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); |
1251 | 1266 |
1252 if (!hard_reg_set_equal_p (i1_regset, i2_regset)) | 1267 if (i1_regset != i2_regset) |
1253 return dir_none; | 1268 return dir_none; |
1254 } | 1269 } |
1255 #endif | 1270 #endif |
1256 | 1271 |
1257 if (reload_completed | 1272 if (reload_completed |
1590 whether they went through the prologue. Sibcalls are fine, we know | 1605 whether they went through the prologue. Sibcalls are fine, we know |
1591 that we either didn't need or inserted an epilogue before them. */ | 1606 that we either didn't need or inserted an epilogue before them. */ |
1592 if (crtl->shrink_wrapped | 1607 if (crtl->shrink_wrapped |
1593 && single_succ_p (bb1) | 1608 && single_succ_p (bb1) |
1594 && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun) | 1609 && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun) |
1595 && !JUMP_P (BB_END (bb1)) | 1610 && (!JUMP_P (BB_END (bb1)) |
1611 /* Punt if the only successor is a fake edge to exit, the jump | |
1612 must be some weird one. */ | |
1613 || (single_succ_edge (bb1)->flags & EDGE_FAKE) != 0) | |
1596 && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1)))) | 1614 && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1)))) |
1597 return false; | 1615 return false; |
1598 | 1616 |
1599 /* If BB1 has only one successor, we may be looking at either an | 1617 /* If BB1 has only one successor, we may be looking at either an |
1600 unconditional jump, or a fake edge to exit. */ | 1618 unconditional jump, or a fake edge to exit. */ |
1601 if (single_succ_p (bb1) | 1619 if (single_succ_p (bb1) |
1602 && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0 | 1620 && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0 |
1603 && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1)))) | 1621 && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1)))) |
2001 | 2019 |
2002 /* Don't proceed with the crossjump unless we found a sufficient number | 2020 /* Don't proceed with the crossjump unless we found a sufficient number |
2003 of matching instructions or the 'from' block was totally matched | 2021 of matching instructions or the 'from' block was totally matched |
2004 (such that its predecessors will hopefully be redirected and the | 2022 (such that its predecessors will hopefully be redirected and the |
2005 block removed). */ | 2023 block removed). */ |
2006 if ((nmatch < PARAM_VALUE (PARAM_MIN_CROSSJUMP_INSNS)) | 2024 if ((nmatch < param_min_crossjump_insns) |
2007 && (newpos1 != BB_HEAD (src1))) | 2025 && (newpos1 != BB_HEAD (src1))) |
2008 return false; | 2026 return false; |
2009 | 2027 |
2010 /* Avoid deleting preserve label when redirecting ABNORMAL edges. */ | 2028 /* Avoid deleting preserve label when redirecting ABNORMAL edges. */ |
2011 if (block_has_preserve_label (e1->dest) | 2029 if (block_has_preserve_label (e1->dest) |
2194 | 2212 |
2195 /* It is always cheapest to redirect a block that ends in a branch to | 2213 /* It is always cheapest to redirect a block that ends in a branch to |
2196 a block that falls through into BB, as that adds no branches to the | 2214 a block that falls through into BB, as that adds no branches to the |
2197 program. We'll try that combination first. */ | 2215 program. We'll try that combination first. */ |
2198 fallthru = NULL; | 2216 fallthru = NULL; |
2199 max = PARAM_VALUE (PARAM_MAX_CROSSJUMP_EDGES); | 2217 max = param_max_crossjump_edges; |
2200 | 2218 |
2201 if (EDGE_COUNT (bb->preds) > max) | 2219 if (EDGE_COUNT (bb->preds) > max) |
2202 return false; | 2220 return false; |
2203 | 2221 |
2204 fallthru = find_fallthru_edge (bb->preds); | 2222 fallthru = find_fallthru_edge (bb->preds); |
2700 edge e; | 2718 edge e; |
2701 edge_iterator ei; | 2719 edge_iterator ei; |
2702 | 2720 |
2703 if (current_ir_type () == IR_RTL_CFGLAYOUT) | 2721 if (current_ir_type () == IR_RTL_CFGLAYOUT) |
2704 { | 2722 { |
2705 if (BB_FOOTER (b) | 2723 rtx_insn *insn; |
2706 && BARRIER_P (BB_FOOTER (b))) | 2724 for (insn = BB_FOOTER (b); |
2725 insn; insn = NEXT_INSN (insn)) | |
2726 if (BARRIER_P (insn)) | |
2727 break; | |
2728 if (insn) | |
2707 FOR_EACH_EDGE (e, ei, b->preds) | 2729 FOR_EACH_EDGE (e, ei, b->preds) |
2708 if ((e->flags & EDGE_FALLTHRU) | 2730 if ((e->flags & EDGE_FALLTHRU)) |
2709 && BB_FOOTER (e->src) == NULL) | |
2710 { | 2731 { |
2711 if (BB_FOOTER (b)) | 2732 if (BB_FOOTER (b) |
2733 && BB_FOOTER (e->src) == NULL) | |
2712 { | 2734 { |
2713 BB_FOOTER (e->src) = BB_FOOTER (b); | 2735 BB_FOOTER (e->src) = BB_FOOTER (b); |
2714 BB_FOOTER (b) = NULL; | 2736 BB_FOOTER (b) = NULL; |
2715 } | 2737 } |
2716 else | 2738 else |
2717 { | 2739 emit_barrier_after_bb (e->src); |
2718 start_sequence (); | |
2719 BB_FOOTER (e->src) = emit_barrier (); | |
2720 end_sequence (); | |
2721 } | |
2722 } | 2740 } |
2723 } | 2741 } |
2724 else | 2742 else |
2725 { | 2743 { |
2726 rtx_insn *last = get_last_bb_insn (b); | 2744 rtx_insn *last = get_last_bb_insn (b); |
3172 is good enough. */ | 3190 is good enough. */ |
3173 if ((mode & CLEANUP_EXPENSIVE) && !reload_completed | 3191 if ((mode & CLEANUP_EXPENSIVE) && !reload_completed |
3174 && !delete_trivially_dead_insns (get_insns (), max_reg_num ())) | 3192 && !delete_trivially_dead_insns (get_insns (), max_reg_num ())) |
3175 break; | 3193 break; |
3176 if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred) | 3194 if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred) |
3177 run_fast_dce (); | 3195 { |
3196 run_fast_dce (); | |
3197 mode &= ~CLEANUP_FORCE_FAST_DCE; | |
3198 } | |
3178 } | 3199 } |
3179 else | 3200 else |
3180 break; | 3201 break; |
3181 } | 3202 } |
3182 | 3203 |
3183 if (mode & CLEANUP_CROSSJUMP) | 3204 if (mode & CLEANUP_CROSSJUMP) |
3184 remove_fake_exit_edges (); | 3205 remove_fake_exit_edges (); |
3206 | |
3207 if (mode & CLEANUP_FORCE_FAST_DCE) | |
3208 run_fast_dce (); | |
3185 | 3209 |
3186 /* Don't call delete_dead_jumptables in cfglayout mode, because | 3210 /* Don't call delete_dead_jumptables in cfglayout mode, because |
3187 that function assumes that jump tables are in the insns stream. | 3211 that function assumes that jump tables are in the insns stream. |
3188 But we also don't _have_ to delete dead jumptables in cfglayout | 3212 But we also don't _have_ to delete dead jumptables in cfglayout |
3189 mode because we shouldn't even be looking at things that are | 3213 mode because we shouldn't even be looking at things that are |
3257 return new pass_jump (ctxt); | 3281 return new pass_jump (ctxt); |
3258 } | 3282 } |
3259 | 3283 |
3260 namespace { | 3284 namespace { |
3261 | 3285 |
3286 const pass_data pass_data_jump_after_combine = | |
3287 { | |
3288 RTL_PASS, /* type */ | |
3289 "jump_after_combine", /* name */ | |
3290 OPTGROUP_NONE, /* optinfo_flags */ | |
3291 TV_JUMP, /* tv_id */ | |
3292 0, /* properties_required */ | |
3293 0, /* properties_provided */ | |
3294 0, /* properties_destroyed */ | |
3295 0, /* todo_flags_start */ | |
3296 0, /* todo_flags_finish */ | |
3297 }; | |
3298 | |
3299 class pass_jump_after_combine : public rtl_opt_pass | |
3300 { | |
3301 public: | |
3302 pass_jump_after_combine (gcc::context *ctxt) | |
3303 : rtl_opt_pass (pass_data_jump_after_combine, ctxt) | |
3304 {} | |
3305 | |
3306 /* opt_pass methods: */ | |
3307 virtual bool gate (function *) { return flag_thread_jumps; } | |
3308 virtual unsigned int execute (function *); | |
3309 | |
3310 }; // class pass_jump_after_combine | |
3311 | |
3312 unsigned int | |
3313 pass_jump_after_combine::execute (function *) | |
3314 { | |
3315 /* Jump threading does not keep dominators up-to-date. */ | |
3316 free_dominance_info (CDI_DOMINATORS); | |
3317 cleanup_cfg (CLEANUP_THREADING); | |
3318 return 0; | |
3319 } | |
3320 | |
3321 } // anon namespace | |
3322 | |
3323 rtl_opt_pass * | |
3324 make_pass_jump_after_combine (gcc::context *ctxt) | |
3325 { | |
3326 return new pass_jump_after_combine (ctxt); | |
3327 } | |
3328 | |
3329 namespace { | |
3330 | |
3262 const pass_data pass_data_jump2 = | 3331 const pass_data pass_data_jump2 = |
3263 { | 3332 { |
3264 RTL_PASS, /* type */ | 3333 RTL_PASS, /* type */ |
3265 "jump2", /* name */ | 3334 "jump2", /* name */ |
3266 OPTGROUP_NONE, /* optinfo_flags */ | 3335 OPTGROUP_NONE, /* optinfo_flags */ |