mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-15 22:51:38 +08:00
re PR target/30230 (Incorrect ia64 EH info when an EH region ends in the middle of a bundle)
PR target/30230 * config/ia64/ia64.c (ia64_add_bundle_selector_before): New function. (bundling): Use it. * g++.dg/eh/ia64-2.C: New test. From-SVN: r120103
This commit is contained in:
parent
970af86771
commit
4a4cd49c06
@ -1,3 +1,9 @@
|
||||
2006-12-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/30230
|
||||
* config/ia64/ia64.c (ia64_add_bundle_selector_before): New function.
|
||||
(bundling): Use it.
|
||||
|
||||
2006-12-21 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR target/28966
|
||||
|
@ -7646,6 +7646,53 @@ get_next_important_insn (rtx insn, rtx tail)
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Add a bundle selector TEMPLATE0 before INSN. */
|
||||
|
||||
static void
|
||||
ia64_add_bundle_selector_before (int template0, rtx insn)
|
||||
{
|
||||
rtx b = gen_bundle_selector (GEN_INT (template0));
|
||||
|
||||
ia64_emit_insn_before (b, insn);
|
||||
#if NR_BUNDLES == 10
|
||||
if ((template0 == 4 || template0 == 5)
|
||||
&& (flag_unwind_tables || (flag_exceptions && !USING_SJLJ_EXCEPTIONS)))
|
||||
{
|
||||
int i;
|
||||
rtx note = NULL_RTX;
|
||||
|
||||
/* In .mbb and .bbb bundles, check if CALL_INSN isn't in the
|
||||
first or second slot. If it is and has REG_EH_NOTE set, copy it
|
||||
to following nops, as br.call sets rp to the address of following
|
||||
bundle and therefore an EH region end must be on a bundle
|
||||
boundary. */
|
||||
insn = PREV_INSN (insn);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
do
|
||||
insn = next_active_insn (insn);
|
||||
while (GET_CODE (insn) == INSN
|
||||
&& get_attr_empty (insn) == EMPTY_YES);
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
||||
else if (note)
|
||||
{
|
||||
int code;
|
||||
|
||||
gcc_assert ((code = recog_memoized (insn)) == CODE_FOR_nop
|
||||
|| code == CODE_FOR_nop_b);
|
||||
if (find_reg_note (insn, REG_EH_REGION, NULL_RTX))
|
||||
note = NULL_RTX;
|
||||
else
|
||||
REG_NOTES (insn)
|
||||
= gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0),
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The following function does insn bundling. Bundling means
|
||||
inserting templates and nop insns to fit insn groups into permitted
|
||||
templates. Instruction scheduling uses NDFA (non-deterministic
|
||||
@ -7927,8 +7974,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail)
|
||||
/* We are at the start of a bundle: emit the template
|
||||
(it should be defined). */
|
||||
gcc_assert (template0 >= 0);
|
||||
b = gen_bundle_selector (GEN_INT (template0));
|
||||
ia64_emit_insn_before (b, nop);
|
||||
ia64_add_bundle_selector_before (template0, nop);
|
||||
/* If we have two bundle window, we make one bundle
|
||||
rotation. Otherwise template0 will be undefined
|
||||
(negative value). */
|
||||
@ -7954,8 +8000,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail)
|
||||
/* The current insn is at the bundle start: emit the
|
||||
template. */
|
||||
gcc_assert (template0 >= 0);
|
||||
b = gen_bundle_selector (GEN_INT (template0));
|
||||
ia64_emit_insn_before (b, insn);
|
||||
ia64_add_bundle_selector_before (template0, insn);
|
||||
b = PREV_INSN (insn);
|
||||
insn = b;
|
||||
/* See comment above in analogous place for emitting nops
|
||||
@ -7977,8 +8022,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail)
|
||||
/* See comment above in analogous place for emitting nops
|
||||
after the insn. */
|
||||
gcc_assert (template0 >= 0);
|
||||
b = gen_bundle_selector (GEN_INT (template0));
|
||||
ia64_emit_insn_before (b, insn);
|
||||
ia64_add_bundle_selector_before (template0, insn);
|
||||
b = PREV_INSN (insn);
|
||||
insn = b;
|
||||
template0 = template1;
|
||||
@ -8072,8 +8116,7 @@ bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail)
|
||||
}
|
||||
/* Put the MM-insn in the same slot of a bundle with the
|
||||
same template as the original one. */
|
||||
ia64_emit_insn_before (gen_bundle_selector (GEN_INT (template0)),
|
||||
insn);
|
||||
ia64_add_bundle_selector_before (template0, insn);
|
||||
/* To put the insn in the same slot, add necessary number
|
||||
of nops. */
|
||||
for (j = n; j > 0; j --)
|
||||
|
@ -1,3 +1,8 @@
|
||||
2006-12-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/30230
|
||||
* g++.dg/eh/ia64-2.C: New test.
|
||||
|
||||
2006-12-21 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR target/28966
|
||||
|
57
gcc/testsuite/g++.dg/eh/ia64-2.C
Normal file
57
gcc/testsuite/g++.dg/eh/ia64-2.C
Normal file
@ -0,0 +1,57 @@
|
||||
// PR target/30230
|
||||
// This testcase failed on IA-64, where end of an EH region ended
|
||||
// in the middle of a bundle (with br.call insn in first or second
|
||||
// slot of .bbb/.mbb bundles and EH region end right after it).
|
||||
// But br.call returns to the start of the next bundlem so during
|
||||
// unwinding the call was considered to be outside of the EH region
|
||||
// while it should have been inside.
|
||||
// { dg-options "-O2" }
|
||||
// { dg-do run }
|
||||
|
||||
struct A {};
|
||||
struct B { virtual ~B(); };
|
||||
B::~B () {}
|
||||
struct C { void foo (short &, B &); };
|
||||
struct D { void *d1; C *d2; virtual void virt (void) {} };
|
||||
struct E { D *e1; B *e2; };
|
||||
struct F { void bar (void *, B &); };
|
||||
F *p __attribute__((weak));
|
||||
volatile int r;
|
||||
|
||||
void C::foo (short &x, B &)
|
||||
{
|
||||
if (r)
|
||||
throw A ();
|
||||
x = 1;
|
||||
}
|
||||
|
||||
void F::bar (void *, B &)
|
||||
{
|
||||
throw A ();
|
||||
}
|
||||
|
||||
void baz (E &x)
|
||||
{
|
||||
short g = 0;
|
||||
B b = *x.e2;
|
||||
x.e1->d2->foo (g, b);
|
||||
if (g)
|
||||
p->bar(x.e1->d1, b);
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
F g;
|
||||
D s;
|
||||
E h;
|
||||
p = &g;
|
||||
h.e1 = &s;
|
||||
try
|
||||
{
|
||||
baz (h);
|
||||
}
|
||||
catch (A &)
|
||||
{
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user