X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Frtlanal.c;h=cf58c348489f679c6315b3f752e739d526e644cd;hb=24f1d2c4dcff1de943e875ebfc584e3dd155fd9c;hp=9535104e7079142c7c3a645c8ba73bd09c96ec2d;hpb=c07054e9cb2002971dbefcf713d5dd3ee131bfc4;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 9535104e707..cf58c348489 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1,13 +1,13 @@ /* Analyze RTL for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" @@ -53,26 +52,26 @@ struct subreg_info }; /* Forward declarations */ -static void set_of_1 (rtx, rtx, void *); -static bool covers_regno_p (rtx, unsigned int); -static bool covers_regno_no_parallel_p (rtx, unsigned int); +static void set_of_1 (rtx, const_rtx, void *); +static bool covers_regno_p (const_rtx, unsigned int); +static bool covers_regno_no_parallel_p (const_rtx, unsigned int); static int rtx_referenced_p_1 (rtx *, void *); -static int computed_jump_p_1 (rtx); -static void parms_set (rtx, rtx, void *); +static int computed_jump_p_1 (const_rtx); +static void parms_set (rtx, const_rtx, void *); static void subreg_get_info (unsigned int, enum machine_mode, unsigned int, enum machine_mode, struct subreg_info *); -static unsigned HOST_WIDE_INT cached_nonzero_bits (rtx, enum machine_mode, - rtx, enum machine_mode, +static unsigned HOST_WIDE_INT cached_nonzero_bits (const_rtx, enum machine_mode, + const_rtx, enum machine_mode, unsigned HOST_WIDE_INT); -static unsigned HOST_WIDE_INT nonzero_bits1 (rtx, enum machine_mode, rtx, - enum machine_mode, +static unsigned HOST_WIDE_INT nonzero_bits1 (const_rtx, enum machine_mode, + const_rtx, enum machine_mode, unsigned HOST_WIDE_INT); -static unsigned int cached_num_sign_bit_copies (rtx, enum machine_mode, rtx, +static unsigned int cached_num_sign_bit_copies (const_rtx, enum machine_mode, const_rtx, enum machine_mode, unsigned int); -static unsigned int num_sign_bit_copies1 (rtx, enum machine_mode, rtx, +static unsigned int num_sign_bit_copies1 (const_rtx, enum machine_mode, const_rtx, enum machine_mode, unsigned int); /* Offset of the first 'e', 'E' or 'V' operand for each rtx code, or @@ -107,9 +106,9 @@ num_sign_bit_copies_in_rep[MAX_MODE_INT + 1][MAX_MODE_INT + 1]; (within one function) and so is anything marked `unchanging'. */ int -rtx_unstable_p (rtx x) +rtx_unstable_p (const_rtx x) { - RTX_CODE code = GET_CODE (x); + const RTX_CODE code = GET_CODE (x); int i; const char *fmt; @@ -121,6 +120,7 @@ rtx_unstable_p (rtx x) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -176,8 +176,8 @@ rtx_unstable_p (rtx x) zero, we are slightly more conservative. The frame pointer and the arg pointer are considered constant. */ -int -rtx_varies_p (rtx x, int for_alias) +bool +rtx_varies_p (const_rtx x, bool for_alias) { RTX_CODE code; int i; @@ -195,6 +195,7 @@ rtx_varies_p (rtx x, int for_alias) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -262,7 +263,7 @@ rtx_varies_p (rtx x, int for_alias) alignment machines. */ static int -rtx_addr_can_trap_p_1 (rtx x, enum machine_mode mode, bool unaligned_mems) +rtx_addr_can_trap_p_1 (const_rtx x, enum machine_mode mode, bool unaligned_mems) { enum rtx_code code = GET_CODE (x); @@ -348,7 +349,7 @@ rtx_addr_can_trap_p_1 (rtx x, enum machine_mode mode, bool unaligned_mems) /* Return nonzero if the use of X as an address in a MEM can cause a trap. */ int -rtx_addr_can_trap_p (rtx x) +rtx_addr_can_trap_p (const_rtx x) { return rtx_addr_can_trap_p_1 (x, VOIDmode, false); } @@ -356,9 +357,9 @@ rtx_addr_can_trap_p (rtx x) /* Return true if X is an address that is known to not be zero. */ bool -nonzero_address_p (rtx x) +nonzero_address_p (const_rtx x) { - enum rtx_code code = GET_CODE (x); + const enum rtx_code code = GET_CODE (x); switch (code) { @@ -428,8 +429,8 @@ nonzero_address_p (rtx x) FOR_ALIAS is nonzero if we are called from alias analysis; if it is zero, we are slightly more conservative. */ -int -rtx_addr_varies_p (rtx x, int for_alias) +bool +rtx_addr_varies_p (const_rtx x, bool for_alias) { enum rtx_code code; int i; @@ -465,7 +466,7 @@ rtx_addr_varies_p (rtx x, int for_alias) This is used in cse.c with the `related_value' field. */ HOST_WIDE_INT -get_integer_term (rtx x) +get_integer_term (const_rtx x) { if (GET_CODE (x) == CONST) x = XEXP (x, 0); @@ -484,7 +485,7 @@ get_integer_term (rtx x) Only obvious integer terms are detected. */ rtx -get_related_value (rtx x) +get_related_value (const_rtx x) { if (GET_CODE (x) != CONST) return 0; @@ -502,7 +503,7 @@ get_related_value (rtx x) to somewhere in the same object or object_block as SYMBOL. */ bool -offset_within_block_p (rtx symbol, HOST_WIDE_INT offset) +offset_within_block_p (const_rtx symbol, HOST_WIDE_INT offset) { tree decl; @@ -557,7 +558,7 @@ split_const (rtx x, rtx *base_out, rtx *offset_out) zero, we do not count occurrences inside the destination of a SET. */ int -count_occurrences (rtx x, rtx find, int count_dest) +count_occurrences (const_rtx x, const_rtx find, int count_dest) { int i, j; enum rtx_code code; @@ -574,6 +575,7 @@ count_occurrences (rtx x, rtx find, int count_dest) case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: @@ -627,7 +629,7 @@ count_occurrences (rtx x, rtx find, int count_dest) for a subexpression of IN that is Lisp "equal" to REG. */ int -reg_mentioned_p (rtx reg, rtx in) +reg_mentioned_p (const_rtx reg, const_rtx in) { const char *fmt; int i; @@ -660,6 +662,7 @@ reg_mentioned_p (rtx reg, rtx in) case CONST_INT: case CONST_VECTOR: case CONST_DOUBLE: + case CONST_FIXED: /* These are kept unique for a given value. */ return 0; @@ -692,7 +695,7 @@ reg_mentioned_p (rtx reg, rtx in) no CODE_LABEL insn. */ int -no_labels_between_p (rtx beg, rtx end) +no_labels_between_p (const_rtx beg, const_rtx end) { rtx p; if (beg == end) @@ -707,7 +710,7 @@ no_labels_between_p (rtx beg, rtx end) FROM_INSN and TO_INSN (exclusive of those two). */ int -reg_used_between_p (rtx reg, rtx from_insn, rtx to_insn) +reg_used_between_p (const_rtx reg, const_rtx from_insn, const_rtx to_insn) { rtx insn; @@ -727,7 +730,7 @@ reg_used_between_p (rtx reg, rtx from_insn, rtx to_insn) we do not consider it a reference. */ int -reg_referenced_p (rtx x, rtx body) +reg_referenced_p (const_rtx x, const_rtx body) { int i; @@ -803,9 +806,9 @@ reg_referenced_p (rtx x, rtx body) FROM_INSN and TO_INSN (exclusive of those two). */ int -reg_set_between_p (rtx reg, rtx from_insn, rtx to_insn) +reg_set_between_p (const_rtx reg, const_rtx from_insn, const_rtx to_insn) { - rtx insn; + const_rtx insn; if (from_insn == to_insn) return 0; @@ -818,7 +821,7 @@ reg_set_between_p (rtx reg, rtx from_insn, rtx to_insn) /* Internals of reg_set_between_p. */ int -reg_set_p (rtx reg, rtx insn) +reg_set_p (const_rtx reg, const_rtx insn) { /* We can be passed an insn or part of one. If we are passed an insn, check if a side-effect of the insn clobbers REG. */ @@ -838,12 +841,12 @@ reg_set_p (rtx reg, rtx insn) /* Similar to reg_set_between_p, but check all registers in X. Return 0 only if none of them are modified between START and END. Return 1 if - X contains a MEM; this routine does usememory aliasing. */ + X contains a MEM; this routine does use memory aliasing. */ int -modified_between_p (rtx x, rtx start, rtx end) +modified_between_p (const_rtx x, const_rtx start, const_rtx end) { - enum rtx_code code = GET_CODE (x); + const enum rtx_code code = GET_CODE (x); const char *fmt; int i, j; rtx insn; @@ -855,6 +858,7 @@ modified_between_p (rtx x, rtx start, rtx end) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case SYMBOL_REF: @@ -903,9 +907,9 @@ modified_between_p (rtx x, rtx start, rtx end) does use memory aliasing. */ int -modified_in_p (rtx x, rtx insn) +modified_in_p (const_rtx x, const_rtx insn) { - enum rtx_code code = GET_CODE (x); + const enum rtx_code code = GET_CODE (x); const char *fmt; int i, j; @@ -913,6 +917,7 @@ modified_in_p (rtx x, rtx insn) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case SYMBOL_REF: @@ -958,23 +963,23 @@ modified_in_p (rtx x, rtx insn) /* Helper function for set_of. */ struct set_of_data { - rtx found; - rtx pat; + const_rtx found; + const_rtx pat; }; static void -set_of_1 (rtx x, rtx pat, void *data1) +set_of_1 (rtx x, const_rtx pat, void *data1) { - struct set_of_data *data = (struct set_of_data *) (data1); - if (rtx_equal_p (x, data->pat) - || (!MEM_P (x) && reg_overlap_mentioned_p (data->pat, x))) - data->found = pat; + struct set_of_data *const data = (struct set_of_data *) (data1); + if (rtx_equal_p (x, data->pat) + || (!MEM_P (x) && reg_overlap_mentioned_p (data->pat, x))) + data->found = pat; } /* Give an INSN, return a SET or CLOBBER expression that does modify PAT (either directly or via STRICT_LOW_PART and similar modifiers). */ -rtx -set_of (rtx pat, rtx insn) +const_rtx +set_of (const_rtx pat, const_rtx insn) { struct set_of_data data; data.found = NULL_RTX; @@ -988,7 +993,7 @@ set_of (rtx pat, rtx insn) will not be used, which we ignore. */ rtx -single_set_2 (rtx insn, rtx pat) +single_set_2 (const_rtx insn, const_rtx pat) { rtx set = NULL; int set_verified = 1; @@ -1041,7 +1046,7 @@ single_set_2 (rtx insn, rtx pat) zero. */ int -multiple_sets (rtx insn) +multiple_sets (const_rtx insn) { int found; int i; @@ -1072,7 +1077,7 @@ multiple_sets (rtx insn) and there are no side effects. */ int -set_noop_p (rtx set) +set_noop_p (const_rtx set) { rtx src = SET_SRC (set); rtx dst = SET_DEST (set); @@ -1107,7 +1112,7 @@ set_noop_p (rtx set) value to itself. */ int -noop_move_p (rtx insn) +noop_move_p (const_rtx insn) { rtx pat = PATTERN (insn); @@ -1119,7 +1124,7 @@ noop_move_p (rtx insn) return 0; /* For now treat an insn with a REG_RETVAL note as a - a special insn which should not be considered a no-op. */ + special insn which should not be considered a no-op. */ if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) return 0; @@ -1203,7 +1208,7 @@ find_last_value (rtx x, rtx *pinsn, rtx valid_to, int allow_hwreg) LOC may be zero, meaning don't ignore anything. */ int -refers_to_regno_p (unsigned int regno, unsigned int endregno, rtx x, +refers_to_regno_p (unsigned int regno, unsigned int endregno, const_rtx x, rtx *loc) { int i; @@ -1312,7 +1317,7 @@ refers_to_regno_p (unsigned int regno, unsigned int endregno, rtx x, conflict because we expect this to be a rare case. */ int -reg_overlap_mentioned_p (rtx x, rtx in) +reg_overlap_mentioned_p (const_rtx x, const_rtx in) { unsigned int regno, endregno; @@ -1408,7 +1413,7 @@ reg_overlap_mentioned_p (rtx x, rtx in) the SUBREG will be passed. */ void -note_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data) +note_stores (const_rtx x, void (*fun) (rtx, const_rtx, void *), void *data) { int i; @@ -1550,7 +1555,7 @@ note_uses (rtx *pbody, void (*fun) (rtx *, void *), void *data) by INSN. */ int -dead_or_set_p (rtx insn, rtx x) +dead_or_set_p (const_rtx insn, const_rtx x) { unsigned int regno, end_regno; unsigned int i; @@ -1575,7 +1580,7 @@ dead_or_set_p (rtx insn, rtx x) part of the register is TEST_REGNO. */ static bool -covers_regno_no_parallel_p (rtx dest, unsigned int test_regno) +covers_regno_no_parallel_p (const_rtx dest, unsigned int test_regno) { unsigned int regno, endregno; @@ -1598,7 +1603,7 @@ covers_regno_no_parallel_p (rtx dest, unsigned int test_regno) any member matches the covers_regno_no_parallel_p criteria. */ static bool -covers_regno_p (rtx dest, unsigned int test_regno) +covers_regno_p (const_rtx dest, unsigned int test_regno) { if (GET_CODE (dest) == PARALLEL) { @@ -1624,9 +1629,9 @@ covers_regno_p (rtx dest, unsigned int test_regno) /* Utility function for dead_or_set_p to check an individual register. */ int -dead_or_set_regno_p (rtx insn, unsigned int test_regno) +dead_or_set_regno_p (const_rtx insn, unsigned int test_regno) { - rtx pattern; + const_rtx pattern; /* See if there is a death note for something that includes TEST_REGNO. */ if (find_regno_note (insn, REG_DEAD, test_regno)) @@ -1667,7 +1672,7 @@ dead_or_set_regno_p (rtx insn, unsigned int test_regno) If DATUM is nonzero, look for one whose datum is DATUM. */ rtx -find_reg_note (rtx insn, enum reg_note kind, rtx datum) +find_reg_note (const_rtx insn, enum reg_note kind, const_rtx datum) { rtx link; @@ -1696,7 +1701,7 @@ find_reg_note (rtx insn, enum reg_note kind, rtx datum) it might be the case that the note overlaps REGNO. */ rtx -find_regno_note (rtx insn, enum reg_note kind, unsigned int regno) +find_regno_note (const_rtx insn, enum reg_note kind, unsigned int regno) { rtx link; @@ -1719,7 +1724,7 @@ find_regno_note (rtx insn, enum reg_note kind, unsigned int regno) has such a note. */ rtx -find_reg_equal_equiv_note (rtx insn) +find_reg_equal_equiv_note (const_rtx insn) { rtx link; @@ -1748,7 +1753,7 @@ find_reg_equal_equiv_note (rtx insn) return null. */ rtx -find_constant_src (rtx insn) +find_constant_src (const_rtx insn) { rtx note, set, x; @@ -1771,7 +1776,7 @@ find_constant_src (rtx insn) in the CALL_INSN_FUNCTION_USAGE information of INSN. */ int -find_reg_fusage (rtx insn, enum rtx_code code, rtx datum) +find_reg_fusage (const_rtx insn, enum rtx_code code, const_rtx datum) { /* If it's not a CALL_INSN, it can't possibly have a CALL_INSN_FUNCTION_USAGE field, so don't bother checking. */ @@ -1816,7 +1821,7 @@ find_reg_fusage (rtx insn, enum rtx_code code, rtx datum) in the CALL_INSN_FUNCTION_USAGE information of INSN. */ int -find_regno_fusage (rtx insn, enum rtx_code code, unsigned int regno) +find_regno_fusage (const_rtx insn, enum rtx_code code, unsigned int regno) { rtx link; @@ -1841,34 +1846,11 @@ find_regno_fusage (rtx insn, enum rtx_code code, unsigned int regno) return 0; } -/* Return true if INSN is a call to a pure function. */ - -int -pure_call_p (rtx insn) -{ - rtx link; - - if (!CALL_P (insn) || ! CONST_OR_PURE_CALL_P (insn)) - return 0; - - /* Look for the note that differentiates const and pure functions. */ - for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1)) - { - rtx u, m; - - if (GET_CODE (u = XEXP (link, 0)) == USE - && MEM_P (m = XEXP (u, 0)) && GET_MODE (m) == BLKmode - && GET_CODE (XEXP (m, 0)) == SCRATCH) - return 1; - } - - return 0; -} /* Remove register note NOTE from the REG_NOTES of INSN. */ void -remove_note (rtx insn, rtx note) +remove_note (rtx insn, const_rtx note) { rtx link; @@ -1919,9 +1901,9 @@ remove_reg_equal_equiv_notes (rtx insn) NODE matches. */ int -in_expr_list_p (rtx listp, rtx node) +in_expr_list_p (const_rtx listp, const_rtx node) { - rtx x; + const_rtx x; for (x = listp; x; x = XEXP (x, 1)) if (node == XEXP (x, 0)) @@ -1936,7 +1918,7 @@ in_expr_list_p (rtx listp, rtx node) A simple equality test is used to determine if NODE matches. */ void -remove_node_from_expr_list (rtx node, rtx *listp) +remove_node_from_expr_list (const_rtx node, rtx *listp) { rtx temp = *listp; rtx prev = NULL_RTX; @@ -1965,11 +1947,9 @@ remove_node_from_expr_list (rtx node, rtx *listp) only volatile asms and UNSPEC_VOLATILE instructions. */ int -volatile_insn_p (rtx x) +volatile_insn_p (const_rtx x) { - RTX_CODE code; - - code = GET_CODE (x); + const RTX_CODE code = GET_CODE (x); switch (code) { case LABEL_REF: @@ -1977,6 +1957,7 @@ volatile_insn_p (rtx x) case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CC0: case PC: @@ -2005,7 +1986,7 @@ volatile_insn_p (rtx x) /* Recursively scan the operands of this expression. */ { - const char *fmt = GET_RTX_FORMAT (code); + const char *const fmt = GET_RTX_FORMAT (code); int i; for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) @@ -2031,11 +2012,9 @@ volatile_insn_p (rtx x) UNSPEC_VOLATILE operations or volatile ASM_OPERANDS expressions. */ int -volatile_refs_p (rtx x) +volatile_refs_p (const_rtx x) { - RTX_CODE code; - - code = GET_CODE (x); + const RTX_CODE code = GET_CODE (x); switch (code) { case LABEL_REF: @@ -2043,6 +2022,7 @@ volatile_refs_p (rtx x) case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CC0: case PC: @@ -2069,7 +2049,7 @@ volatile_refs_p (rtx x) /* Recursively scan the operands of this expression. */ { - const char *fmt = GET_RTX_FORMAT (code); + const char *const fmt = GET_RTX_FORMAT (code); int i; for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) @@ -2095,11 +2075,9 @@ volatile_refs_p (rtx x) incrementing. */ int -side_effects_p (rtx x) +side_effects_p (const_rtx x) { - RTX_CODE code; - - code = GET_CODE (x); + const RTX_CODE code = GET_CODE (x); switch (code) { case LABEL_REF: @@ -2107,6 +2085,7 @@ side_effects_p (rtx x) case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CC0: case PC: @@ -2180,8 +2159,8 @@ enum may_trap_p_flags cannot trap at its current location, but it might become trapping if moved elsewhere. */ -static int -may_trap_p_1 (rtx x, unsigned flags) +int +may_trap_p_1 (const_rtx x, unsigned flags) { int i; enum rtx_code code; @@ -2196,6 +2175,7 @@ may_trap_p_1 (rtx x, unsigned flags) /* Handle these cases quickly. */ case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -2206,8 +2186,11 @@ may_trap_p_1 (rtx x, unsigned flags) case SCRATCH: return 0; - case ASM_INPUT: + case UNSPEC: case UNSPEC_VOLATILE: + return targetm.unspec_may_trap_p (x, flags); + + case ASM_INPUT: case TRAP_IF: return 1; @@ -2317,7 +2300,7 @@ may_trap_p_1 (rtx x, unsigned flags) /* Return nonzero if evaluating rtx X might cause a trap. */ int -may_trap_p (rtx x) +may_trap_p (const_rtx x) { return may_trap_p_1 (x, 0); } @@ -2326,7 +2309,7 @@ may_trap_p (rtx x) is moved from its current location by some optimization. */ int -may_trap_after_code_motion_p (rtx x) +may_trap_after_code_motion_p (const_rtx x) { return may_trap_p_1 (x, MTP_AFTER_MOVE); } @@ -2372,7 +2355,7 @@ may_trap_after_code_motion_p (rtx x) on a strict alignment machine. */ int -may_trap_or_fault_p (rtx x) +may_trap_or_fault_p (const_rtx x) { return may_trap_p_1 (x, MTP_UNALIGNED_MEMS); } @@ -2381,11 +2364,11 @@ may_trap_or_fault_p (rtx x) i.e., an inequality. */ int -inequality_comparisons_p (rtx x) +inequality_comparisons_p (const_rtx x) { const char *fmt; int len, i; - enum rtx_code code = GET_CODE (x); + const enum rtx_code code = GET_CODE (x); switch (code) { @@ -2395,6 +2378,7 @@ inequality_comparisons_p (rtx x) case CC0: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case LABEL_REF: @@ -2604,7 +2588,7 @@ rtx_referenced_p (rtx x, rtx body) *LABELP and the jump table to *TABLEP. LABELP and TABLEP may be NULL. */ bool -tablejump_p (rtx insn, rtx *labelp, rtx *tablep) +tablejump_p (const_rtx insn, rtx *labelp, rtx *tablep) { rtx label, table; @@ -2629,9 +2613,9 @@ tablejump_p (rtx insn, rtx *labelp, rtx *tablep) of an IF_THEN_ELSE. */ static int -computed_jump_p_1 (rtx x) +computed_jump_p_1 (const_rtx x) { - enum rtx_code code = GET_CODE (x); + const enum rtx_code code = GET_CODE (x); int i, j; const char *fmt; @@ -2644,6 +2628,7 @@ computed_jump_p_1 (rtx x) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case REG: @@ -2683,16 +2668,18 @@ computed_jump_p_1 (rtx x) we can recognize them by a (use (label_ref)). */ int -computed_jump_p (rtx insn) +computed_jump_p (const_rtx insn) { int i; if (JUMP_P (insn)) { rtx pat = PATTERN (insn); - if (find_reg_note (insn, REG_LABEL, NULL_RTX)) + /* If we have a JUMP_LABEL set, we're not a computed jump. */ + if (JUMP_LABEL (insn) != NULL) return 0; - else if (GET_CODE (pat) == PARALLEL) + + if (GET_CODE (pat) == PARALLEL) { int len = XVECLEN (pat, 0); int has_use_labelref = 0; @@ -2877,9 +2864,11 @@ commutative_operand_precedence (rtx op) /* Constants always come the second operand. Prefer "nice" constants. */ if (code == CONST_INT) - return -7; + return -8; if (code == CONST_DOUBLE) - return -6; + return -7; + if (code == CONST_FIXED) + return -7; op = avoid_constant_pool_reference (op); code = GET_CODE (op); @@ -2887,22 +2876,26 @@ commutative_operand_precedence (rtx op) { case RTX_CONST_OBJ: if (code == CONST_INT) - return -5; + return -6; if (code == CONST_DOUBLE) - return -4; - return -3; + return -5; + if (code == CONST_FIXED) + return -5; + return -4; case RTX_EXTRA: /* SUBREGs of objects should come second. */ if (code == SUBREG && OBJECT_P (SUBREG_REG (op))) - return -2; - + return -3; return 0; case RTX_OBJ: /* Complex expressions should be the first, so decrease priority - of objects. */ - return -1; + of objects. Prefer pointer objects over non pointer objects. */ + if ((REG_P (op) && REG_POINTER (op)) + || (MEM_P (op) && MEM_POINTER (op))) + return -1; + return -2; case RTX_COMM_ARITH: /* Prefer operands that are themselves commutative to be first. @@ -2929,7 +2922,7 @@ commutative_operand_precedence (rtx op) /* Return 1 iff it is necessary to swap operands of commutative operation in order to canonicalize expression. */ -int +bool swap_commutative_operands_p (rtx x, rtx y) { return (commutative_operand_precedence (x) @@ -2939,7 +2932,7 @@ swap_commutative_operands_p (rtx x, rtx y) /* Return 1 if X is an autoincrement side effect and the register is not the stack pointer. */ int -auto_inc_p (rtx x) +auto_inc_p (const_rtx x) { switch (GET_CODE (x)) { @@ -2960,7 +2953,7 @@ auto_inc_p (rtx x) /* Return nonzero if IN contains a piece of rtl that has the address LOC. */ int -loc_mentioned_in_p (rtx *loc, rtx in) +loc_mentioned_in_p (rtx *loc, const_rtx in) { enum rtx_code code; const char *fmt; @@ -2973,16 +2966,15 @@ loc_mentioned_in_p (rtx *loc, rtx in) fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { - if (loc == &in->u.fld[i].rt_rtx) - return 1; if (fmt[i] == 'e') { - if (loc_mentioned_in_p (loc, XEXP (in, i))) + if (loc == &XEXP (in, i) || loc_mentioned_in_p (loc, XEXP (in, i))) return 1; } else if (fmt[i] == 'E') for (j = XVECLEN (in, i) - 1; j >= 0; j--) - if (loc_mentioned_in_p (loc, XVECEXP (in, i, j))) + if (loc == &XVECEXP (in, i, j) + || loc_mentioned_in_p (loc, XVECEXP (in, i, j))) return 1; } return 0; @@ -3034,7 +3026,7 @@ subreg_lsb_1 (enum machine_mode outer_mode, (counting from the least significant bit of the reg). */ unsigned int -subreg_lsb (rtx x) +subreg_lsb (const_rtx x) { return subreg_lsb_1 (GET_MODE (x), GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); @@ -3231,7 +3223,7 @@ subreg_offset_representable_p (unsigned int xregno, enum machine_mode xmode, /* Return the final regno that a subreg expression refers to. */ unsigned int -subreg_regno (rtx x) +subreg_regno (const_rtx x) { unsigned int ret; rtx subreg = SUBREG_REG (x); @@ -3248,17 +3240,27 @@ subreg_regno (rtx x) /* Return the number of registers that a subreg expression refers to. */ unsigned int -subreg_nregs (rtx x) +subreg_nregs (const_rtx x) +{ + return subreg_nregs_with_regno (REGNO (SUBREG_REG (x)), x); +} + +/* Return the number of registers that a subreg REG with REGNO + expression refers to. This is a copy of the rtlanal.c:subreg_nregs + changed so that the regno can be passed in. */ + +unsigned int +subreg_nregs_with_regno (unsigned int regno, const_rtx x) { struct subreg_info info; rtx subreg = SUBREG_REG (x); - int regno = REGNO (subreg); subreg_get_info (regno, GET_MODE (subreg), SUBREG_BYTE (x), GET_MODE (x), &info); return info.nregs; } + struct parms_set_data { int nregs; @@ -3267,7 +3269,7 @@ struct parms_set_data /* Helper function for noticing stores to parameter registers. */ static void -parms_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data) +parms_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) { struct parms_set_data *d = data; if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER @@ -3352,7 +3354,7 @@ find_first_parameter_load (rtx call_insn, rtx boundary) call instruction. */ bool -keep_with_call_p (rtx insn) +keep_with_call_p (const_rtx insn) { rtx set; @@ -3373,7 +3375,10 @@ keep_with_call_p (rtx insn) if we can break or not. */ if (SET_DEST (set) == stack_pointer_rtx) { - rtx i2 = next_nonnote_insn (insn); + /* This CONST_CAST is okay because next_nonnote_insn just + returns it's argument and we assign it to a const_rtx + variable. */ + const_rtx i2 = next_nonnote_insn (CONST_CAST_RTX(insn)); if (i2 && keep_with_call_p (i2)) return true; } @@ -3387,7 +3392,7 @@ keep_with_call_p (rtx insn) not apply to the fallthru case of a conditional jump. */ bool -label_is_jump_target_p (rtx label, rtx jump_insn) +label_is_jump_target_p (const_rtx label, const_rtx jump_insn) { rtx tmp = JUMP_LABEL (jump_insn); @@ -3405,6 +3410,9 @@ label_is_jump_target_p (rtx label, rtx jump_insn) return true; } + if (find_reg_note (jump_insn, REG_LABEL_TARGET, label)) + return true; + return false; } @@ -3508,13 +3516,13 @@ default_address_cost (rtx x) unsigned HOST_WIDE_INT -nonzero_bits (rtx x, enum machine_mode mode) +nonzero_bits (const_rtx x, enum machine_mode mode) { return cached_nonzero_bits (x, mode, NULL_RTX, VOIDmode, 0); } unsigned int -num_sign_bit_copies (rtx x, enum machine_mode mode) +num_sign_bit_copies (const_rtx x, enum machine_mode mode) { return cached_num_sign_bit_copies (x, mode, NULL_RTX, VOIDmode, 0); } @@ -3524,7 +3532,7 @@ num_sign_bit_copies (rtx x, enum machine_mode mode) identical subexpressions on the first or the second level. */ static unsigned HOST_WIDE_INT -cached_nonzero_bits (rtx x, enum machine_mode mode, rtx known_x, +cached_nonzero_bits (const_rtx x, enum machine_mode mode, const_rtx known_x, enum machine_mode known_mode, unsigned HOST_WIDE_INT known_ret) { @@ -3577,7 +3585,7 @@ cached_nonzero_bits (rtx x, enum machine_mode mode, rtx known_x, an arithmetic operation, we can do better. */ static unsigned HOST_WIDE_INT -nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x, +nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x, enum machine_mode known_mode, unsigned HOST_WIDE_INT known_ret) { @@ -4033,7 +4041,7 @@ nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x, first or the second level. */ static unsigned int -cached_num_sign_bit_copies (rtx x, enum machine_mode mode, rtx known_x, +cached_num_sign_bit_copies (const_rtx x, enum machine_mode mode, const_rtx known_x, enum machine_mode known_mode, unsigned int known_ret) { @@ -4084,7 +4092,7 @@ cached_num_sign_bit_copies (rtx x, enum machine_mode mode, rtx known_x, be between 1 and the number of bits in MODE. */ static unsigned int -num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x, +num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x, enum machine_mode known_mode, unsigned int known_ret) { @@ -4539,7 +4547,7 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest, { enum rtx_code code; rtx prev = insn; - rtx set; + const_rtx set; rtx tem; rtx op0, op1; int reverse_code = 0; @@ -4871,7 +4879,7 @@ init_num_sign_bit_copies_in_rep (void) assume it already contains a truncated value of MODE. */ bool -truncated_to_mode (enum machine_mode mode, rtx x) +truncated_to_mode (enum machine_mode mode, const_rtx x) { /* This register has already been used in MODE without explicit truncation. */