This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/12301
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 19 Sep 2003 19:50:36 +0200
- Subject: [PATCH] Fix PR optimization/12301
Hi,
This is a regression from GCC 2.95.3 related to EH on SPARC (but that can
potentially affect other targets with delay slots), present in all GCC 3.x
compilers I tested.
The reorg pass doesn't take into account that insns can "internally" throw,
when looking for insns to put in delay slots. So it is allowed to look
behind such an insn and to bring back any insn that doesn't conflict with
those between it and the slot (in the testcase, the first insn is a call and
the second one a move between call-saved registers).
Now an insn that can "internally" throw may perform a jump from the viewpoint
of the function, that is may transfer the control flow to another location
within the function. Therefore insns shouldn't be moved across it (this is
enforced in sched-deps.c, where such insns are treated as barriers).
Bootstrapped/regtested on sparc-sun-solaris2.8 and sparc64-sun-solaris2.9
(c,c++,f77,objc 3.3 branch).
2003-09-19 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/12301
* reorg.c (stop_search_p): Return 1 for insns that can
throw internally.
2003-09-19 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
* g++.dg/opt/delayslot1.C: New test.
--
Eric Botcazou
Index: reorg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reorg.c,v
retrieving revision 1.82
diff -u -p -r1.82 reorg.c
--- reorg.c 26 Sep 2002 22:25:13 -0000 1.82
+++ reorg.c 19 Sep 2003 05:55:33 -0000
@@ -236,6 +236,12 @@ stop_search_p (insn, labels_p)
if (insn == 0)
return 1;
+ /* If the insn can throw an exception that is caught within the function,
+ it may effectively perform a jump from the viewpoint of the function.
+ Therefore act like for a jump. */
+ if (can_throw_internal (insn))
+ return 1;
+
switch (GET_CODE (insn))
{
case NOTE:
// PR optimization/12301
// Origin: Colin Hirsch <gcc@cohi.at>
// Testcase by Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
// This used to fail on SPARC because the reorg pass moved an insn
// across a function call that can throw internally in order to put
// it in a delay slot.
// { dg-do run }
// { dg-options "-O" }
struct S{
char *c;
char data[100];
S () : c (data) {};
S (const S& s) {
c = data;
data[0] = s.c[0];
}
};
S real_cast ()
{
throw 3;
}
S cast_helper(S& debug)
{
try {
return real_cast();
}
catch (int e) {
throw debug;
}
}
int main()
{
S tmp;
try {
cast_helper (tmp);
}
catch (S& e) {}
return 0;
}