From: J"orn Rennecke Date: Mon, 12 Jan 2004 17:03:25 +0000 (+0000) Subject: re PR target/13585 (Incorrect optimisation of call to sfunc) X-Git-Tag: releases/gcc-3.3.3~102 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=31240745d138fb20492b69ad472503cef02bf762;p=thirdparty%2Fgcc.git re PR target/13585 (Incorrect optimisation of call to sfunc) PR target/13585 * sh-protos.h (check_use_sfunc_addr): Declare. * sh.c (extract_sfunc_addr, check_use_sfunc_addr): New functions. * sh.md (use_sfunc_addr): Use check_use_sfunc_addr in insn predicate. From-SVN: r75736 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 85568bc64622..d6a2c907d6b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-01-12 J"orn Rennecke + + PR target/13585 + * sh-protos.h (check_use_sfunc_addr): Declare. + * sh.c (extract_sfunc_addr, check_use_sfunc_addr): New functions. + * sh.md (use_sfunc_addr): Use check_use_sfunc_addr in insn predicate. + 2004-01-12 Matthias Klose Backport from mainline diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index 70d0ade07873..7c294625330e 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler for Hitachi / SuperH SH. - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc. Contributed by Steve Chamberlain (sac@cygnus.com). Improved by Jim Wilson (wilson@cygnus.com). @@ -131,6 +131,7 @@ extern bool sh_cannot_change_mode_class extern void sh_mark_label PARAMS ((rtx, int)); extern int sh_register_move_cost PARAMS ((enum machine_mode mode, enum reg_class, enum reg_class)); +extern int check_use_sfunc_addr (rtx, rtx); #ifdef HARD_CONST extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET)); diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 04a67ef1f098..b5db0d18bd7b 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -1,6 +1,6 @@ /* Output routines for GCC for Hitachi / SuperH SH. - Copyright (C) 1993, 1994, 1995, 1997, 1997, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1995, 1997, 1997, 1998, 1999, 2000, 2001, 2002, + 2004 Free Software Foundation, Inc. Contributed by Steve Chamberlain (sac@cygnus.com). Improved by Jim Wilson (wilson@cygnus.com). @@ -7857,4 +7857,51 @@ sh_register_operand (op, mode) return register_operand (op, mode); } +/* INSN is an sfunc; return the rtx that describes the address used. */ +static rtx +extract_sfunc_addr (rtx insn) +{ + rtx pattern, part = NULL_RTX; + int len, i; + + pattern = PATTERN (insn); + len = XVECLEN (pattern, 0); + for (i = 0; i < len; i++) + { + part = XVECEXP (pattern, 0, i); + if (GET_CODE (part) == USE && GET_MODE (XEXP (part, 0)) == Pmode + && GENERAL_REGISTER_P (true_regnum (XEXP (part, 0)))) + return XEXP (part, 0); + } + if (GET_CODE (XVECEXP (pattern, 0, 0)) == UNSPEC_VOLATILE) + return XVECEXP (XVECEXP (pattern, 0, 0), 0, 1); + abort (); +} + +/* Verify that the register in use_sfunc_addr still agrees with the address + used in the sfunc. This prevents fill_slots_from_thread from changing + use_sfunc_addr. + INSN is the use_sfunc_addr instruction, and REG is the register it + guards. */ +int +check_use_sfunc_addr (rtx insn, rtx reg) +{ + /* Search for the sfunc. It should really come right after INSN. */ + while ((insn = NEXT_INSN (insn))) + { + if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN) + break; + if (! INSN_P (insn)) + continue; + + if (GET_CODE (PATTERN (insn)) == SEQUENCE) + insn = XVECEXP (PATTERN (insn), 0, 0); + if (GET_CODE (PATTERN (insn)) != PARALLEL + || get_attr_type (insn) != TYPE_SFUNC) + continue; + return rtx_equal_p (extract_sfunc_addr (insn), reg); + } + abort (); +} + #include "gt-sh.h" diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 56f93cc14c8c..21dca6e7ecf3 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -1,6 +1,6 @@ ;;- Machine description for Hitachi / SuperH SH. -;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -;; Free Software Foundation, Inc. +;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +;; 2004 Free Software Foundation, Inc. ;; Contributed by Steve Chamberlain (sac@cygnus.com). ;; Improved by Jim Wilson (wilson@cygnus.com). @@ -1220,7 +1220,7 @@ (define_insn "use_sfunc_addr" [(set (reg:SI PR_REG) (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))] - "TARGET_SH1" + "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])" "" [(set_attr "length" "0")])