This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]