This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
V3 [PATCH] i386: Handle REG_EH_REGION note
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Uros Bizjak <ubizjak at gmail dot com>, Jan Hubicka <hubicka at ucw dot cz>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Hongtao Liu <crazylht at gmail dot com>
- Date: Thu, 14 Mar 2019 21:08:17 +0800
- Subject: V3 [PATCH] i386: Handle REG_EH_REGION note
On 3/14/19, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Mar 14, 2019 at 4:34 PM Jakub Jelinek <jakub@redhat.com> wrote:
>>
>> On Thu, Mar 14, 2019 at 11:30:21AM +0800, H.J. Lu wrote:
>> > We need to split the basic block if we create new insns, which may
>> > throw exceptions, in the middle of the basic blocks.
>> >
>> > Tested on AVX2 and AVX512 machines with and without
>> >
>> > --with-arch=native
>> >
>> > OK for trunk?
>>
>> That looks much better, I see you chose to follow what lower-subreg.c
>> does
>> here. I just wonder if instead of the sbitmap of blocks to check for
>> splitting it
>> wouldn't be more efficient to have an auto_vec<rtx_insn *> holding the
>> exact
>> set_insns that need splitting after them and just grab the bb using
>> BLOCK_FOR_INSN.
>>
>
> Good idea. I will work on it.
>
Here it is. OK for trunk?
Thanks.
--
H.J.
From 64ac61ce7095c49406ea34b05f1c22fbb98ca3f7 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 12 Mar 2019 08:55:24 +0800
Subject: [PATCH] i386: Handle REG_EH_REGION note
When we split:
(insn 18 17 76 2 (set (reg:SF 88 [ _19 ])
(float:SF (mem/c:SI (symbol_ref:DI ("d") [flags 0x2] <var_decl 0x7fd6d8290c60 d>) [1 d+0 S4 A32]))) "x.ii":4:20 170 {*floatsisf2}
(expr_list:REG_EH_REGION (const_int 2 [0x2])
(nil)))
to
(insn 94 17 18 2 (set (reg:V4SF 115)
(vec_merge:V4SF (vec_duplicate:V4SF (float:SF (mem/c:SI (symbol_ref:DI ("d") [flags 0x2] <var_decl 0x7f346837ac60 d>) [1 d+0 S4 A32])))
(reg:V4SF 114)
(const_int 1 [0x1]))) "x.ii":4:20 -1
(nil))
(insn 18 94 76 2 (set (reg:SF 88 [ _19 ])
(subreg:SF (reg:V4SF 115) 0)) "x.ii":4:20 112 {*movsf_internal}
(expr_list:REG_EH_REGION (const_int 2 [0x2])
(nil)))
we must copy the REG_EH_REGION note to the first insn and split the block
after the newly added insn. The REG_EH_REGION on the second insn will be
removed later since it no longer traps.
gcc/
PR target/89650
* config/i386/i386.c (remove_partial_avx_dependency): Handle
REG_EH_REGION note.
gcc/testsuite/
PR target/89650
* g++.target/i386/pr89650.C: New test.
---
gcc/config/i386/i386.c | 42 +++++++++++++++++++++++++
gcc/testsuite/g++.target/i386/pr89650.C | 19 +++++++++++
2 files changed, 61 insertions(+)
create mode 100644 gcc/testsuite/g++.target/i386/pr89650.C
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1f94a45909d..93ff46f329a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2819,6 +2819,8 @@ remove_partial_avx_dependency (void)
rtx set;
rtx v4sf_const0 = NULL_RTX;
+ auto_vec<rtx_insn *> splitted_insn;
+
FOR_EACH_BB_FN (bb, cfun)
{
FOR_BB_INSNS (bb, insn)
@@ -2875,6 +2877,17 @@ remove_partial_avx_dependency (void)
set_insn = emit_insn_before (set, insn);
df_insn_rescan (set_insn);
+ if (cfun->can_throw_non_call_exceptions)
+ {
+ /* Handle REG_EH_REGION note. */
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (note)
+ {
+ splitted_insn.safe_push (set_insn);
+ add_reg_note (set_insn, REG_EH_REGION, XEXP (note, 0));
+ }
+ }
+
src = gen_rtx_SUBREG (dest_mode, vec, 0);
set = gen_rtx_SET (dest, src);
@@ -2925,6 +2938,35 @@ remove_partial_avx_dependency (void)
df_insn_rescan (set_insn);
df_process_deferred_rescans ();
loop_optimizer_finalize ();
+
+ if (!splitted_insn.is_empty ())
+ {
+ free_dominance_info (CDI_DOMINATORS);
+
+ unsigned int i;
+ FOR_EACH_VEC_ELT (splitted_insn, i, insn)
+ {
+ rtx_insn *end;
+ edge fallthru;
+
+ bb = BLOCK_FOR_INSN (insn);
+ end = BB_END (bb);
+
+ while (insn != end)
+ if (control_flow_insn_p (insn))
+ {
+ /* Split the block after insn. There will be a
+ fallthru edge, which is OK so we keep it. We
+ have to create the exception edges ourselves. */
+ fallthru = split_block (bb, insn);
+ rtl_make_eh_edge (NULL, bb, BB_END (bb));
+ bb = fallthru->dest;
+ insn = BB_HEAD (bb);
+ }
+ else
+ insn = NEXT_INSN (insn);
+ }
+ }
}
bitmap_obstack_release (NULL);
diff --git a/gcc/testsuite/g++.target/i386/pr89650.C b/gcc/testsuite/g++.target/i386/pr89650.C
new file mode 100644
index 00000000000..4b253cbf467
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/pr89650.C
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -flive-range-shrinkage -fno-tree-dce -fno-dce -fnon-call-exceptions -mavx" }
+
+int d, e;
+struct g {
+ float f;
+ g(float h) : f(h + d) {}
+ ~g() {}
+};
+struct i {
+ int a;
+ int b : 4;
+ int &c;
+ i(int h) : a(), b(), c(h) {}
+};
+int main() {
+ i j(e);
+ g k[]{1, 2};
+}
--
2.20.1