From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6228 invoked by alias); 31 Jul 2007 08:20:27 -0000 Received: (qmail 6219 invoked by uid 22791); 31 Jul 2007 08:20:27 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 31 Jul 2007 08:20:25 +0000 Received: (qmail 17908 invoked from network); 31 Jul 2007 08:20:23 -0000 Received: from unknown (HELO gateway) (10.0.0.100) by mail.codesourcery.com with SMTP; 31 Jul 2007 08:20:23 -0000 Received: by gateway (Postfix, from userid 1010) id 3DC036C0D4; Tue, 31 Jul 2007 01:20:23 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard@codesourcery.com Subject: Re: Fix mode-switching problem for SH SJLJ exceptions References: <87myxruwx4.fsf@firetop.home> Date: Tue, 31 Jul 2007 09:45:00 -0000 In-Reply-To: <87myxruwx4.fsf@firetop.home> (Richard Sandiford's message of "Fri\, 20 Jul 2007 12\:39\:03 +0100") Message-ID: <878x8xugqh.fsf@firetop.home> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-07/txt/msg02163.txt.bz2 Ping Richard Sandiford writes: > Functions that return a value usually end with the sequence: > > A: (clobber (reg H)) > ... > B: (set (reg H) (reg P)) > ... > C: (use (reg H)) > > where H is the hard return register and P is the pseudo register > to which return values are assigned. > > mode-switching.c uses a specially-split exit block to enforce MODE_EXIT > (the mode required on exit from a function). The code that creates this > block -- create_pre_exit -- tries to find insn B and starts the new block > immediately before (or sometimes immediately after) it. > > However, B can be deleted if P is never initialised. In this case, > create_pre_exit splits the block immediately before A instead. > The code only searches for A and B in the fallthrough predecessor > to the exit block; it assumes that P is never initialised if the > block contains neither A nor B. > > In some cases B may be made up of several individual insns. > create_pre_exit therefore records the range of modified registers > and stops on the first SET that doesn't assign to part of H. > It then asserts that it has found a SET or CLOBBER for the > whole of H (except in some corner cases). > > This shows up a problem on SJLJ targets, where the call to the SJLJ > unregister function is inserted between A and B. If B has been deleted, > the first SET we find may be setting up the argument to that call. > We then stop the search without having found either A or B, so the > assertion triggers. > > At this point we have already searched past the call itself, and this > seems bogus. We are supposed to enforce MODE_EXIT _after_ the last call. > I therefore just treated searches that reach a call in the same way as > searches that reach the beginning of a block. > > Bootstrapped & regression-tested on x86_64-linux-gnu. Also regression-tested > on sh-elf (multilibs {,-m2,-m3,-m4,-m4/-ml}) and sh-wrs-vxworks. OK to > install? > > Richard > > > gcc/ > * mode-switching.c (create_pre_exit): Don't search past calls. > > Index: gcc/mode-switching.c > =================================================================== > --- gcc/mode-switching.c (revision 126715) > +++ gcc/mode-switching.c (working copy) > @@ -246,6 +246,17 @@ create_pre_exit (int n_entities, int *en > > if (INSN_P (return_copy)) > { > + /* When using SJLJ exceptions, the call to the > + unregister function is inserted between the > + clobber of the return value and the copy. > + We do not want to split the block before this > + or any other call; if we have not found the > + copy yet, the copy must have been deleted. */ > + if (CALL_P (return_copy)) > + { > + short_block = 1; > + break; > + } > return_copy_pat = PATTERN (return_copy); > switch (GET_CODE (return_copy_pat)) > {