diff options
author | Kewen Lin <linkw@linux.ibm.com> | 2022-11-15 20:26:07 -0600 |
---|---|---|
committer | Kewen Lin <linkw@linux.ibm.com> | 2022-11-15 20:26:07 -0600 |
commit | 63e1b2e767a3f4695373c2406ff719c0a60c1858 (patch) | |
tree | 90a3632d3bf10d138033381340bda2381f0d2db8 /gcc/function.cc | |
parent | cdc34229c11ff955aa1a08fb3919327f3c1a4e8a (diff) | |
download | gcc-63e1b2e767a3f4695373c2406ff719c0a60c1858.zip gcc-63e1b2e767a3f4695373c2406ff719c0a60c1858.tar.gz gcc-63e1b2e767a3f4695373c2406ff719c0a60c1858.tar.bz2 |
rtl: Try to remove EH edges after {pro,epi}logue generation [PR90259]
After prologue and epilogue generation, the judgement on whether
one memory access onto stack frame may trap or not could change,
since we get more exact stack information by now.
As PR90259 shows, some memory access becomes impossible to trap
any more after prologue and epilogue generation, it can make
subsequent optimization be able to remove it if safe, but it
results in unexpected control flow status due to REG_EH_REGION
note missing.
This patch proposes to try to remove EH edges with function
purge_all_dead_edges after prologue and epilogue generation,
it simplifies CFG as early as we can and don't need any fixup
in downstream passes.
CFG simplification result with PR90259's case as example:
*before*
18: %1:TF=call [`__gcc_qdiv'] argc:0
REG_EH_REGION 0x2
77: NOTE_INSN_BASIC_BLOCK 3
19: NOTE_INSN_DELETED
20: NOTE_INSN_DELETED
110: [%31:SI+0x20]=%1:DF
REG_EH_REGION 0x2
116: NOTE_INSN_BASIC_BLOCK 4
111: [%31:SI+0x28]=%2:DF
REG_EH_REGION 0x2
22: NOTE_INSN_BASIC_BLOCK 5
108: %0:DF=[%31:SI+0x20]
REG_EH_REGION 0x2
117: NOTE_INSN_BASIC_BLOCK 6
109: %1:DF=[%31:SI+0x28]
REG_EH_REGION 0x2
79: NOTE_INSN_BASIC_BLOCK 7
26: [%31:SI+0x18]=%0:DF
104: pc=L69
105: barrier
*after*
18: %1:TF=call [`__gcc_qdiv'] argc:0
REG_EH_REGION 0x2
77: NOTE_INSN_BASIC_BLOCK 3
19: NOTE_INSN_DELETED
20: NOTE_INSN_DELETED
110: [%31:SI+0x20]=%1:DF
111: [%31:SI+0x28]=%2:DF
108: %0:DF=[%31:SI+0x20]
109: %1:DF=[%31:SI+0x28]
26: [%31:SI+0x18]=%0:DF
104: pc=L69
105: barrier
PR rtl-optimization/90259
gcc/ChangeLog:
* function.cc (rest_of_handle_thread_prologue_and_epilogue): Add
parameter fun, and call function purge_all_dead_edges.
(pass_thread_prologue_and_epilogue::execute): Name unamed parameter
as fun, and use it for rest_of_handle_thread_prologue_and_epilogue.
gcc/testsuite/ChangeLog:
* g++.target/powerpc/pr90259.C: New.
Diffstat (limited to 'gcc/function.cc')
-rw-r--r-- | gcc/function.cc | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/gcc/function.cc b/gcc/function.cc index d3da20e..361aa5f 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -6546,7 +6546,7 @@ make_pass_leaf_regs (gcc::context *ctxt) } static unsigned int -rest_of_handle_thread_prologue_and_epilogue (void) +rest_of_handle_thread_prologue_and_epilogue (function *fun) { /* prepare_shrink_wrap is sensitive to the block structure of the control flow graph, so clean it up first. */ @@ -6563,6 +6563,13 @@ rest_of_handle_thread_prologue_and_epilogue (void) Fix that up. */ fixup_partitions (); + /* After prologue and epilogue generation, the judgement on whether + one memory access onto stack frame may trap or not could change, + since we get more exact stack information by now. So try to + remove any EH edges here, see PR90259. */ + if (fun->can_throw_non_call_exceptions) + purge_all_dead_edges (); + /* Shrink-wrapping can result in unreachable edges in the epilogue, see PR57320. */ cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0); @@ -6631,9 +6638,9 @@ public: {} /* opt_pass methods: */ - unsigned int execute (function *) final override + unsigned int execute (function * fun) final override { - return rest_of_handle_thread_prologue_and_epilogue (); + return rest_of_handle_thread_prologue_and_epilogue (fun); } }; // class pass_thread_prologue_and_epilogue |