Mercurial > hg > CbC > CbC_gcc
comparison gcc/ifcvt.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 3bfb6c00c1e0 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
45 #include "df.h" | 45 #include "df.h" |
46 #include "vec.h" | 46 #include "vec.h" |
47 #include "vecprim.h" | 47 #include "vecprim.h" |
48 #include "dbgcnt.h" | 48 #include "dbgcnt.h" |
49 | 49 |
50 #ifndef HAVE_conditional_execution | |
51 #define HAVE_conditional_execution 0 | |
52 #endif | |
53 #ifndef HAVE_conditional_move | 50 #ifndef HAVE_conditional_move |
54 #define HAVE_conditional_move 0 | 51 #define HAVE_conditional_move 0 |
55 #endif | 52 #endif |
56 #ifndef HAVE_incscc | 53 #ifndef HAVE_incscc |
57 #define HAVE_incscc 0 | 54 #define HAVE_incscc 0 |
59 #ifndef HAVE_decscc | 56 #ifndef HAVE_decscc |
60 #define HAVE_decscc 0 | 57 #define HAVE_decscc 0 |
61 #endif | 58 #endif |
62 #ifndef HAVE_trap | 59 #ifndef HAVE_trap |
63 #define HAVE_trap 0 | 60 #define HAVE_trap 0 |
64 #endif | |
65 #ifndef HAVE_conditional_trap | |
66 #define HAVE_conditional_trap 0 | |
67 #endif | 61 #endif |
68 | 62 |
69 #ifndef MAX_CONDITIONAL_EXECUTE | 63 #ifndef MAX_CONDITIONAL_EXECUTE |
70 #define MAX_CONDITIONAL_EXECUTE \ | 64 #define MAX_CONDITIONAL_EXECUTE \ |
71 (BRANCH_COST (optimize_function_for_speed_p (cfun), false) \ | 65 (BRANCH_COST (optimize_function_for_speed_p (cfun), false) \ |
195 if (insn == BB_END (bb)) | 189 if (insn == BB_END (bb)) |
196 return NULL_RTX; | 190 return NULL_RTX; |
197 insn = NEXT_INSN (insn); | 191 insn = NEXT_INSN (insn); |
198 } | 192 } |
199 | 193 |
200 while (NOTE_P (insn)) | 194 while (NOTE_P (insn) || DEBUG_INSN_P (insn)) |
201 { | 195 { |
202 if (insn == BB_END (bb)) | 196 if (insn == BB_END (bb)) |
203 return NULL_RTX; | 197 return NULL_RTX; |
204 insn = NEXT_INSN (insn); | 198 insn = NEXT_INSN (insn); |
205 } | 199 } |
218 rtx insn = BB_END (bb); | 212 rtx insn = BB_END (bb); |
219 rtx head = BB_HEAD (bb); | 213 rtx head = BB_HEAD (bb); |
220 | 214 |
221 while (NOTE_P (insn) | 215 while (NOTE_P (insn) |
222 || JUMP_P (insn) | 216 || JUMP_P (insn) |
217 || DEBUG_INSN_P (insn) | |
223 || (skip_use_p | 218 || (skip_use_p |
224 && NONJUMP_INSN_P (insn) | 219 && NONJUMP_INSN_P (insn) |
225 && GET_CODE (PATTERN (insn)) == USE)) | 220 && GET_CODE (PATTERN (insn)) == USE)) |
226 { | 221 { |
227 if (insn == head) | 222 if (insn == head) |
270 if (!start || !end) | 265 if (!start || !end) |
271 return FALSE; | 266 return FALSE; |
272 | 267 |
273 for (insn = start; ; insn = NEXT_INSN (insn)) | 268 for (insn = start; ; insn = NEXT_INSN (insn)) |
274 { | 269 { |
275 if (NOTE_P (insn)) | 270 if (NOTE_P (insn) || DEBUG_INSN_P (insn)) |
276 goto insn_done; | 271 goto insn_done; |
277 | 272 |
278 gcc_assert(NONJUMP_INSN_P (insn) || CALL_P (insn)); | 273 gcc_assert(NONJUMP_INSN_P (insn) || CALL_P (insn)); |
279 | 274 |
280 /* Remove USE insns that get in the way. */ | 275 /* Remove USE insns that get in the way. */ |
906 noce_try_store_flag (struct noce_if_info *if_info) | 901 noce_try_store_flag (struct noce_if_info *if_info) |
907 { | 902 { |
908 int reversep; | 903 int reversep; |
909 rtx target, seq; | 904 rtx target, seq; |
910 | 905 |
911 if (GET_CODE (if_info->b) == CONST_INT | 906 if (CONST_INT_P (if_info->b) |
912 && INTVAL (if_info->b) == STORE_FLAG_VALUE | 907 && INTVAL (if_info->b) == STORE_FLAG_VALUE |
913 && if_info->a == const0_rtx) | 908 && if_info->a == const0_rtx) |
914 reversep = 0; | 909 reversep = 0; |
915 else if (if_info->b == const0_rtx | 910 else if (if_info->b == const0_rtx |
916 && GET_CODE (if_info->a) == CONST_INT | 911 && CONST_INT_P (if_info->a) |
917 && INTVAL (if_info->a) == STORE_FLAG_VALUE | 912 && INTVAL (if_info->a) == STORE_FLAG_VALUE |
918 && (reversed_comparison_code (if_info->cond, if_info->jump) | 913 && (reversed_comparison_code (if_info->cond, if_info->jump) |
919 != UNKNOWN)) | 914 != UNKNOWN)) |
920 reversep = 1; | 915 reversep = 1; |
921 else | 916 else |
953 int reversep; | 948 int reversep; |
954 HOST_WIDE_INT itrue, ifalse, diff, tmp; | 949 HOST_WIDE_INT itrue, ifalse, diff, tmp; |
955 int normalize, can_reverse; | 950 int normalize, can_reverse; |
956 enum machine_mode mode; | 951 enum machine_mode mode; |
957 | 952 |
958 if (GET_CODE (if_info->a) == CONST_INT | 953 if (CONST_INT_P (if_info->a) |
959 && GET_CODE (if_info->b) == CONST_INT) | 954 && CONST_INT_P (if_info->b)) |
960 { | 955 { |
961 mode = GET_MODE (if_info->x); | 956 mode = GET_MODE (if_info->x); |
962 ifalse = INTVAL (if_info->a); | 957 ifalse = INTVAL (if_info->a); |
963 itrue = INTVAL (if_info->b); | 958 itrue = INTVAL (if_info->b); |
964 | 959 |
1329 early because it'll screw alias analysis. Note that we've | 1324 early because it'll screw alias analysis. Note that we've |
1330 already checked for no side effects. */ | 1325 already checked for no side effects. */ |
1331 /* ??? FIXME: Magic number 5. */ | 1326 /* ??? FIXME: Magic number 5. */ |
1332 if (cse_not_expected | 1327 if (cse_not_expected |
1333 && MEM_P (a) && MEM_P (b) | 1328 && MEM_P (a) && MEM_P (b) |
1329 && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b) | |
1334 && if_info->branch_cost >= 5) | 1330 && if_info->branch_cost >= 5) |
1335 { | 1331 { |
1332 enum machine_mode address_mode | |
1333 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (a)); | |
1334 | |
1336 a = XEXP (a, 0); | 1335 a = XEXP (a, 0); |
1337 b = XEXP (b, 0); | 1336 b = XEXP (b, 0); |
1338 x = gen_reg_rtx (Pmode); | 1337 x = gen_reg_rtx (address_mode); |
1339 is_mem = 1; | 1338 is_mem = 1; |
1340 } | 1339 } |
1341 | 1340 |
1342 /* ??? We could handle this if we knew that a load from A or B could | 1341 /* ??? We could handle this if we knew that a load from A or B could |
1343 not fault. This is also true if we've already loaded | 1342 not fault. This is also true if we've already loaded |
1482 if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b)) | 1481 if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b)) |
1483 set_mem_alias_set (tmp, MEM_ALIAS_SET (if_info->a)); | 1482 set_mem_alias_set (tmp, MEM_ALIAS_SET (if_info->a)); |
1484 set_mem_align (tmp, | 1483 set_mem_align (tmp, |
1485 MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b))); | 1484 MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b))); |
1486 | 1485 |
1486 gcc_assert (MEM_ADDR_SPACE (if_info->a) == MEM_ADDR_SPACE (if_info->b)); | |
1487 set_mem_addr_space (tmp, MEM_ADDR_SPACE (if_info->a)); | |
1488 | |
1487 noce_emit_move_insn (if_info->x, tmp); | 1489 noce_emit_move_insn (if_info->x, tmp); |
1488 } | 1490 } |
1489 else if (target != x) | 1491 else if (target != x) |
1490 noce_emit_move_insn (x, target); | 1492 noce_emit_move_insn (x, target); |
1491 | 1493 |
1539 2. GCC may have canonicalized the conditional, for example | 1541 2. GCC may have canonicalized the conditional, for example |
1540 replacing "if x < 4" with "if x <= 3". We can undo that (or | 1542 replacing "if x < 4" with "if x <= 3". We can undo that (or |
1541 make equivalent types of changes) to get the constants we need | 1543 make equivalent types of changes) to get the constants we need |
1542 if they're off by one in the right direction. */ | 1544 if they're off by one in the right direction. */ |
1543 | 1545 |
1544 if (GET_CODE (target) == CONST_INT) | 1546 if (CONST_INT_P (target)) |
1545 { | 1547 { |
1546 enum rtx_code code = GET_CODE (if_info->cond); | 1548 enum rtx_code code = GET_CODE (if_info->cond); |
1547 rtx op_a = XEXP (if_info->cond, 0); | 1549 rtx op_a = XEXP (if_info->cond, 0); |
1548 rtx op_b = XEXP (if_info->cond, 1); | 1550 rtx op_b = XEXP (if_info->cond, 1); |
1549 rtx prev_insn; | 1551 rtx prev_insn; |
1556 && GET_CODE (PATTERN (prev_insn)) == SET) | 1558 && GET_CODE (PATTERN (prev_insn)) == SET) |
1557 { | 1559 { |
1558 rtx src = find_reg_equal_equiv_note (prev_insn); | 1560 rtx src = find_reg_equal_equiv_note (prev_insn); |
1559 if (!src) | 1561 if (!src) |
1560 src = SET_SRC (PATTERN (prev_insn)); | 1562 src = SET_SRC (PATTERN (prev_insn)); |
1561 if (GET_CODE (src) == CONST_INT) | 1563 if (CONST_INT_P (src)) |
1562 { | 1564 { |
1563 if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn)))) | 1565 if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn)))) |
1564 op_a = src; | 1566 op_a = src; |
1565 else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn)))) | 1567 else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn)))) |
1566 op_b = src; | 1568 op_b = src; |
1567 | 1569 |
1568 if (GET_CODE (op_a) == CONST_INT) | 1570 if (CONST_INT_P (op_a)) |
1569 { | 1571 { |
1570 rtx tmp = op_a; | 1572 rtx tmp = op_a; |
1571 op_a = op_b; | 1573 op_a = op_b; |
1572 op_b = tmp; | 1574 op_b = tmp; |
1573 code = swap_condition (code); | 1575 code = swap_condition (code); |
1575 } | 1577 } |
1576 } | 1578 } |
1577 | 1579 |
1578 /* Now, look to see if we can get the right constant by | 1580 /* Now, look to see if we can get the right constant by |
1579 adjusting the conditional. */ | 1581 adjusting the conditional. */ |
1580 if (GET_CODE (op_b) == CONST_INT) | 1582 if (CONST_INT_P (op_b)) |
1581 { | 1583 { |
1582 HOST_WIDE_INT desired_val = INTVAL (target); | 1584 HOST_WIDE_INT desired_val = INTVAL (target); |
1583 HOST_WIDE_INT actual_val = INTVAL (op_b); | 1585 HOST_WIDE_INT actual_val = INTVAL (op_b); |
1584 | 1586 |
1585 switch (code) | 1587 switch (code) |
1744 if_info->cond_earliest = earliest; | 1746 if_info->cond_earliest = earliest; |
1745 | 1747 |
1746 return TRUE; | 1748 return TRUE; |
1747 } | 1749 } |
1748 | 1750 |
1749 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc. */ | 1751 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", |
1752 "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);", | |
1753 etc. */ | |
1750 | 1754 |
1751 static int | 1755 static int |
1752 noce_try_abs (struct noce_if_info *if_info) | 1756 noce_try_abs (struct noce_if_info *if_info) |
1753 { | 1757 { |
1754 rtx cond, earliest, target, seq, a, b, c; | 1758 rtx cond, earliest, target, seq, a, b, c; |
1755 int negate; | 1759 int negate; |
1760 bool one_cmpl = false; | |
1756 | 1761 |
1757 /* Reject modes with signed zeros. */ | 1762 /* Reject modes with signed zeros. */ |
1758 if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x))) | 1763 if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x))) |
1759 return FALSE; | 1764 return FALSE; |
1760 | 1765 |
1767 negate = 0; | 1772 negate = 0; |
1768 else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a)) | 1773 else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a)) |
1769 { | 1774 { |
1770 c = a; a = b; b = c; | 1775 c = a; a = b; b = c; |
1771 negate = 1; | 1776 negate = 1; |
1777 } | |
1778 else if (GET_CODE (a) == NOT && rtx_equal_p (XEXP (a, 0), b)) | |
1779 { | |
1780 negate = 0; | |
1781 one_cmpl = true; | |
1782 } | |
1783 else if (GET_CODE (b) == NOT && rtx_equal_p (XEXP (b, 0), a)) | |
1784 { | |
1785 c = a; a = b; b = c; | |
1786 negate = 1; | |
1787 one_cmpl = true; | |
1772 } | 1788 } |
1773 else | 1789 else |
1774 return FALSE; | 1790 return FALSE; |
1775 | 1791 |
1776 cond = noce_get_alt_condition (if_info, b, &earliest); | 1792 cond = noce_get_alt_condition (if_info, b, &earliest); |
1839 default: | 1855 default: |
1840 return FALSE; | 1856 return FALSE; |
1841 } | 1857 } |
1842 | 1858 |
1843 start_sequence (); | 1859 start_sequence (); |
1844 | 1860 if (one_cmpl) |
1845 target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1); | 1861 target = expand_one_cmpl_abs_nojump (GET_MODE (if_info->x), b, |
1862 if_info->x); | |
1863 else | |
1864 target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1); | |
1846 | 1865 |
1847 /* ??? It's a quandary whether cmove would be better here, especially | 1866 /* ??? It's a quandary whether cmove would be better here, especially |
1848 for integers. Perhaps combine will clean things up. */ | 1867 for integers. Perhaps combine will clean things up. */ |
1849 if (target && negate) | 1868 if (target && negate) |
1850 target = expand_simple_unop (GET_MODE (target), NEG, target, if_info->x, 0); | 1869 { |
1870 if (one_cmpl) | |
1871 target = expand_simple_unop (GET_MODE (target), NOT, target, | |
1872 if_info->x, 0); | |
1873 else | |
1874 target = expand_simple_unop (GET_MODE (target), NEG, target, | |
1875 if_info->x, 0); | |
1876 } | |
1851 | 1877 |
1852 if (! target) | 1878 if (! target) |
1853 { | 1879 { |
1854 end_sequence (); | 1880 end_sequence (); |
1855 return FALSE; | 1881 return FALSE; |
1974 | 2000 |
1975 /* ??? We could also handle AND here. */ | 2001 /* ??? We could also handle AND here. */ |
1976 if (GET_CODE (cond) == ZERO_EXTRACT) | 2002 if (GET_CODE (cond) == ZERO_EXTRACT) |
1977 { | 2003 { |
1978 if (XEXP (cond, 1) != const1_rtx | 2004 if (XEXP (cond, 1) != const1_rtx |
1979 || GET_CODE (XEXP (cond, 2)) != CONST_INT | 2005 || !CONST_INT_P (XEXP (cond, 2)) |
1980 || ! rtx_equal_p (x, XEXP (cond, 0))) | 2006 || ! rtx_equal_p (x, XEXP (cond, 0))) |
1981 return FALSE; | 2007 return FALSE; |
1982 bitnum = INTVAL (XEXP (cond, 2)); | 2008 bitnum = INTVAL (XEXP (cond, 2)); |
1983 mode = GET_MODE (x); | 2009 mode = GET_MODE (x); |
1984 if (BITS_BIG_ENDIAN) | 2010 if (BITS_BIG_ENDIAN) |
1992 a = if_info->a; | 2018 a = if_info->a; |
1993 if (GET_CODE (a) == IOR || GET_CODE (a) == XOR) | 2019 if (GET_CODE (a) == IOR || GET_CODE (a) == XOR) |
1994 { | 2020 { |
1995 /* Check for "if (X & C) x = x op C". */ | 2021 /* Check for "if (X & C) x = x op C". */ |
1996 if (! rtx_equal_p (x, XEXP (a, 0)) | 2022 if (! rtx_equal_p (x, XEXP (a, 0)) |
1997 || GET_CODE (XEXP (a, 1)) != CONST_INT | 2023 || !CONST_INT_P (XEXP (a, 1)) |
1998 || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) | 2024 || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) |
1999 != (unsigned HOST_WIDE_INT) 1 << bitnum) | 2025 != (unsigned HOST_WIDE_INT) 1 << bitnum) |
2000 return FALSE; | 2026 return FALSE; |
2001 | 2027 |
2002 /* if ((x & C) == 0) x |= C; is transformed to x |= C. */ | 2028 /* if ((x & C) == 0) x |= C; is transformed to x |= C. */ |
2018 } | 2044 } |
2019 else if (GET_CODE (a) == AND) | 2045 else if (GET_CODE (a) == AND) |
2020 { | 2046 { |
2021 /* Check for "if (X & C) x &= ~C". */ | 2047 /* Check for "if (X & C) x &= ~C". */ |
2022 if (! rtx_equal_p (x, XEXP (a, 0)) | 2048 if (! rtx_equal_p (x, XEXP (a, 0)) |
2023 || GET_CODE (XEXP (a, 1)) != CONST_INT | 2049 || !CONST_INT_P (XEXP (a, 1)) |
2024 || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) | 2050 || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode)) |
2025 != (~((HOST_WIDE_INT) 1 << bitnum) & GET_MODE_MASK (mode))) | 2051 != (~((HOST_WIDE_INT) 1 << bitnum) & GET_MODE_MASK (mode))) |
2026 return FALSE; | 2052 return FALSE; |
2027 | 2053 |
2028 /* if ((x & C) == 0) x &= ~C; is transformed to nothing. */ | 2054 /* if ((x & C) == 0) x &= ~C; is transformed to nothing. */ |
2143 case LO_SUM: | 2169 case LO_SUM: |
2144 case PRE_MODIFY: | 2170 case PRE_MODIFY: |
2145 addr = XEXP (addr, 1); | 2171 addr = XEXP (addr, 1); |
2146 break; | 2172 break; |
2147 case PLUS: | 2173 case PLUS: |
2148 if (GET_CODE (XEXP (addr, 1)) == CONST_INT) | 2174 if (CONST_INT_P (XEXP (addr, 1))) |
2149 addr = XEXP (addr, 0); | 2175 addr = XEXP (addr, 0); |
2150 else | 2176 else |
2151 return false; | 2177 return false; |
2152 break; | 2178 break; |
2153 case LABEL_REF: | 2179 case LABEL_REF: |
2257 return FALSE; | 2283 return FALSE; |
2258 } | 2284 } |
2259 else | 2285 else |
2260 { | 2286 { |
2261 insn_b = prev_nonnote_insn (if_info->cond_earliest); | 2287 insn_b = prev_nonnote_insn (if_info->cond_earliest); |
2288 while (insn_b && DEBUG_INSN_P (insn_b)) | |
2289 insn_b = prev_nonnote_insn (insn_b); | |
2262 /* We're going to be moving the evaluation of B down from above | 2290 /* We're going to be moving the evaluation of B down from above |
2263 COND_EARLIEST to JUMP. Make sure the relevant data is still | 2291 COND_EARLIEST to JUMP. Make sure the relevant data is still |
2264 intact. */ | 2292 intact. */ |
2265 if (! insn_b | 2293 if (! insn_b |
2266 || BLOCK_NUM (insn_b) != BLOCK_NUM (if_info->cond_earliest) | 2294 || BLOCK_NUM (insn_b) != BLOCK_NUM (if_info->cond_earliest) |
2267 || !NONJUMP_INSN_P (insn_b) | 2295 || !NONJUMP_INSN_P (insn_b) |
2268 || (set_b = single_set (insn_b)) == NULL_RTX | 2296 || (set_b = single_set (insn_b)) == NULL_RTX |
2269 || ! rtx_equal_p (x, SET_DEST (set_b)) | 2297 || ! rtx_equal_p (x, SET_DEST (set_b)) |
2270 || ! noce_operand_ok (SET_SRC (set_b)) | 2298 || ! noce_operand_ok (SET_SRC (set_b)) |
2271 || reg_overlap_mentioned_p (x, SET_SRC (set_b)) | 2299 || reg_overlap_mentioned_p (x, SET_SRC (set_b)) |
2272 || modified_between_p (SET_SRC (set_b), | 2300 || modified_between_p (SET_SRC (set_b), insn_b, jump) |
2273 PREV_INSN (if_info->cond_earliest), jump) | |
2274 /* Likewise with X. In particular this can happen when | 2301 /* Likewise with X. In particular this can happen when |
2275 noce_get_condition looks farther back in the instruction | 2302 noce_get_condition looks farther back in the instruction |
2276 stream than one might expect. */ | 2303 stream than one might expect. */ |
2277 || reg_overlap_mentioned_p (x, cond) | 2304 || reg_overlap_mentioned_p (x, cond) |
2278 || reg_overlap_mentioned_p (x, a) | 2305 || reg_overlap_mentioned_p (x, a) |
2279 || modified_between_p (x, PREV_INSN (if_info->cond_earliest), jump)) | 2306 || modified_between_p (x, insn_b, jump)) |
2280 insn_b = set_b = NULL_RTX; | 2307 insn_b = set_b = NULL_RTX; |
2281 } | 2308 } |
2282 | 2309 |
2283 /* If x has side effects then only the if-then-else form is safe to | 2310 /* If x has side effects then only the if-then-else form is safe to |
2284 convert. But even in that case we would need to restore any notes | 2311 convert. But even in that case we would need to restore any notes |
2299 { | 2326 { |
2300 if (GET_MODE (x) == BLKmode) | 2327 if (GET_MODE (x) == BLKmode) |
2301 return FALSE; | 2328 return FALSE; |
2302 | 2329 |
2303 if (GET_CODE (x) == ZERO_EXTRACT | 2330 if (GET_CODE (x) == ZERO_EXTRACT |
2304 && (GET_CODE (XEXP (x, 1)) != CONST_INT | 2331 && (!CONST_INT_P (XEXP (x, 1)) |
2305 || GET_CODE (XEXP (x, 2)) != CONST_INT)) | 2332 || !CONST_INT_P (XEXP (x, 2)))) |
2306 return FALSE; | 2333 return FALSE; |
2307 | 2334 |
2308 x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART | 2335 x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART |
2309 ? XEXP (x, 0) : x)); | 2336 ? XEXP (x, 0) : x)); |
2310 } | 2337 } |
2394 if (noce_try_abs (if_info)) | 2421 if (noce_try_abs (if_info)) |
2395 goto success; | 2422 goto success; |
2396 if (HAVE_conditional_move | 2423 if (HAVE_conditional_move |
2397 && noce_try_cmove (if_info)) | 2424 && noce_try_cmove (if_info)) |
2398 goto success; | 2425 goto success; |
2399 if (! HAVE_conditional_execution) | 2426 if (! targetm.have_conditional_execution ()) |
2400 { | 2427 { |
2401 if (noce_try_store_flag_constants (if_info)) | 2428 if (noce_try_store_flag_constants (if_info)) |
2402 goto success; | 2429 goto success; |
2403 if (noce_try_addcc (if_info)) | 2430 if (noce_try_addcc (if_info)) |
2404 goto success; | 2431 goto success; |
2482 | 2509 |
2483 FOR_BB_INSNS (bb, insn) | 2510 FOR_BB_INSNS (bb, insn) |
2484 { | 2511 { |
2485 rtx set, dest, src; | 2512 rtx set, dest, src; |
2486 | 2513 |
2487 if (!INSN_P (insn) || JUMP_P (insn)) | 2514 if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn)) |
2488 continue; | 2515 continue; |
2489 set = single_set (insn); | 2516 set = single_set (insn); |
2490 if (!set) | 2517 if (!set) |
2491 return FALSE; | 2518 return FALSE; |
2492 | 2519 |
2560 FOR_BB_INSNS (bb, insn) | 2587 FOR_BB_INSNS (bb, insn) |
2561 { | 2588 { |
2562 rtx set, target, dest, t, e; | 2589 rtx set, target, dest, t, e; |
2563 unsigned int regno; | 2590 unsigned int regno; |
2564 | 2591 |
2565 if (!INSN_P (insn) || JUMP_P (insn)) | 2592 /* ??? Maybe emit conditional debug insn? */ |
2593 if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn)) | |
2566 continue; | 2594 continue; |
2567 set = single_set (insn); | 2595 set = single_set (insn); |
2568 gcc_assert (set && REG_P (SET_DEST (set))); | 2596 gcc_assert (set && REG_P (SET_DEST (set))); |
2569 | 2597 |
2570 dest = SET_DEST (set); | 2598 dest = SET_DEST (set); |
3037 | 3065 |
3038 if (! reload_completed | 3066 if (! reload_completed |
3039 && noce_find_if_block (test_bb, then_edge, else_edge, pass)) | 3067 && noce_find_if_block (test_bb, then_edge, else_edge, pass)) |
3040 goto success; | 3068 goto success; |
3041 | 3069 |
3042 if (HAVE_conditional_execution && reload_completed | 3070 if (targetm.have_conditional_execution () && reload_completed |
3043 && cond_exec_find_if_block (&ce_info)) | 3071 && cond_exec_find_if_block (&ce_info)) |
3044 goto success; | 3072 goto success; |
3045 | 3073 |
3046 if (HAVE_trap && HAVE_conditional_trap | 3074 if (HAVE_trap |
3075 && optab_handler (ctrap_optab, word_mode)->insn_code != CODE_FOR_nothing | |
3047 && find_cond_trap (test_bb, then_edge, else_edge)) | 3076 && find_cond_trap (test_bb, then_edge, else_edge)) |
3048 goto success; | 3077 goto success; |
3049 | 3078 |
3050 if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY | 3079 if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY |
3051 && (! HAVE_conditional_execution || reload_completed)) | 3080 && (! targetm.have_conditional_execution () || reload_completed)) |
3052 { | 3081 { |
3053 if (find_if_case_1 (test_bb, then_edge, else_edge)) | 3082 if (find_if_case_1 (test_bb, then_edge, else_edge)) |
3054 goto success; | 3083 goto success; |
3055 if (find_if_case_2 (test_bb, then_edge, else_edge)) | 3084 if (find_if_case_2 (test_bb, then_edge, else_edge)) |
3056 goto success; | 3085 goto success; |
3120 if (CALL_P (insn)) | 3149 if (CALL_P (insn)) |
3121 return -1; | 3150 return -1; |
3122 | 3151 |
3123 if (INSN_P (insn) | 3152 if (INSN_P (insn) |
3124 && !JUMP_P (insn) | 3153 && !JUMP_P (insn) |
3154 && !DEBUG_INSN_P (insn) | |
3125 && GET_CODE (PATTERN (insn)) != USE | 3155 && GET_CODE (PATTERN (insn)) != USE |
3126 && GET_CODE (PATTERN (insn)) != CLOBBER) | 3156 && GET_CODE (PATTERN (insn)) != CLOBBER) |
3127 n_insns++; | 3157 n_insns++; |
3128 | 3158 |
3129 if (insn == end) | 3159 if (insn == end) |
3152 | 3182 |
3153 ce_info->last_test_bb = test_bb; | 3183 ce_info->last_test_bb = test_bb; |
3154 | 3184 |
3155 /* We only ever should get here after reload, | 3185 /* We only ever should get here after reload, |
3156 and only if we have conditional execution. */ | 3186 and only if we have conditional execution. */ |
3157 gcc_assert (HAVE_conditional_execution && reload_completed); | 3187 gcc_assert (targetm.have_conditional_execution () && reload_completed); |
3158 | 3188 |
3159 /* Discover if any fall through predecessors of the current test basic block | 3189 /* Discover if any fall through predecessors of the current test basic block |
3160 were && tests (which jump to the else block) or || tests (which jump to | 3190 were && tests (which jump to the else block) or || tests (which jump to |
3161 the then block). */ | 3191 the then block). */ |
3162 if (single_pred_p (test_bb) | 3192 if (single_pred_p (test_bb) |
3733 fprintf (dump_file, | 3763 fprintf (dump_file, |
3734 "\nIF-CASE-2 found, start %d, else %d\n", | 3764 "\nIF-CASE-2 found, start %d, else %d\n", |
3735 test_bb->index, else_bb->index); | 3765 test_bb->index, else_bb->index); |
3736 | 3766 |
3737 /* ELSE is small. */ | 3767 /* ELSE is small. */ |
3738 if (! cheap_bb_rtx_cost_p (else_bb, | 3768 if (! cheap_bb_rtx_cost_p (else_bb, |
3739 COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge->src), | 3769 COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge->src), |
3740 predictable_edge_p (else_edge))))) | 3770 predictable_edge_p (else_edge))))) |
3741 return FALSE; | 3771 return FALSE; |
3742 | 3772 |
3743 /* Registers set are dead, or are predicable. */ | 3773 /* Registers set are dead, or are predicable. */ |
3780 static int | 3810 static int |
3781 dead_or_predicable (basic_block test_bb, basic_block merge_bb, | 3811 dead_or_predicable (basic_block test_bb, basic_block merge_bb, |
3782 basic_block other_bb, basic_block new_dest, int reversep) | 3812 basic_block other_bb, basic_block new_dest, int reversep) |
3783 { | 3813 { |
3784 rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX; | 3814 rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX; |
3815 /* Number of pending changes. */ | |
3816 int n_validated_changes = 0; | |
3785 | 3817 |
3786 jump = BB_END (test_bb); | 3818 jump = BB_END (test_bb); |
3787 | 3819 |
3788 /* Find the extent of the real code in the merge block. */ | 3820 /* Find the extent of the real code in the merge block. */ |
3789 head = BB_HEAD (merge_bb); | 3821 head = BB_HEAD (merge_bb); |
3790 end = BB_END (merge_bb); | 3822 end = BB_END (merge_bb); |
3823 | |
3824 while (DEBUG_INSN_P (end) && end != head) | |
3825 end = PREV_INSN (end); | |
3791 | 3826 |
3792 /* If merge_bb ends with a tablejump, predicating/moving insn's | 3827 /* If merge_bb ends with a tablejump, predicating/moving insn's |
3793 into test_bb and then deleting merge_bb will result in the jumptable | 3828 into test_bb and then deleting merge_bb will result in the jumptable |
3794 that follows merge_bb being removed along with merge_bb and then we | 3829 that follows merge_bb being removed along with merge_bb and then we |
3795 get an unresolved reference to the jumptable. */ | 3830 get an unresolved reference to the jumptable. */ |
3796 if (tablejump_p (end, NULL, NULL)) | 3831 if (tablejump_p (end, NULL, NULL)) |
3797 return FALSE; | 3832 return FALSE; |
3798 | 3833 |
3799 if (LABEL_P (head)) | 3834 if (LABEL_P (head)) |
3800 head = NEXT_INSN (head); | 3835 head = NEXT_INSN (head); |
3836 while (DEBUG_INSN_P (head) && head != end) | |
3837 head = NEXT_INSN (head); | |
3801 if (NOTE_P (head)) | 3838 if (NOTE_P (head)) |
3802 { | 3839 { |
3803 if (head == end) | 3840 if (head == end) |
3804 { | 3841 { |
3805 head = end = NULL_RTX; | 3842 head = end = NULL_RTX; |
3806 goto no_body; | 3843 goto no_body; |
3807 } | 3844 } |
3808 head = NEXT_INSN (head); | 3845 head = NEXT_INSN (head); |
3846 while (DEBUG_INSN_P (head) && head != end) | |
3847 head = NEXT_INSN (head); | |
3809 } | 3848 } |
3810 | 3849 |
3811 if (JUMP_P (end)) | 3850 if (JUMP_P (end)) |
3812 { | 3851 { |
3813 if (head == end) | 3852 if (head == end) |
3814 { | 3853 { |
3815 head = end = NULL_RTX; | 3854 head = end = NULL_RTX; |
3816 goto no_body; | 3855 goto no_body; |
3817 } | 3856 } |
3818 end = PREV_INSN (end); | 3857 end = PREV_INSN (end); |
3858 while (DEBUG_INSN_P (end) && end != head) | |
3859 end = PREV_INSN (end); | |
3819 } | 3860 } |
3820 | 3861 |
3821 /* Disable handling dead code by conditional execution if the machine needs | 3862 /* Disable handling dead code by conditional execution if the machine needs |
3822 to do anything funny with the tests, etc. */ | 3863 to do anything funny with the tests, etc. */ |
3823 #ifndef IFCVT_MODIFY_TESTS | 3864 #ifndef IFCVT_MODIFY_TESTS |
3824 if (HAVE_conditional_execution) | 3865 if (targetm.have_conditional_execution ()) |
3825 { | 3866 { |
3826 /* In the conditional execution case, we have things easy. We know | 3867 /* In the conditional execution case, we have things easy. We know |
3827 the condition is reversible. We don't have to check life info | 3868 the condition is reversible. We don't have to check life info |
3828 because we're going to conditionally execute the code anyway. | 3869 because we're going to conditionally execute the code anyway. |
3829 All that's left is making sure the insns involved can actually | 3870 All that's left is making sure the insns involved can actually |
3848 XEXP (cond, 1)); | 3889 XEXP (cond, 1)); |
3849 if (prob_val) | 3890 if (prob_val) |
3850 prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val)); | 3891 prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val)); |
3851 } | 3892 } |
3852 | 3893 |
3853 if (! cond_exec_process_insns ((ce_if_block_t *)0, head, end, cond, | 3894 if (cond_exec_process_insns (NULL, head, end, cond, prob_val, 0) |
3854 prob_val, 0)) | 3895 && verify_changes (0)) |
3855 goto cancel; | 3896 n_validated_changes = num_validated_changes (); |
3897 else | |
3898 cancel_changes (0); | |
3856 | 3899 |
3857 earliest = jump; | 3900 earliest = jump; |
3858 } | 3901 } |
3859 else | |
3860 #endif | 3902 #endif |
3903 /* Try the NCE path if the CE path did not result in any changes. */ | |
3904 if (n_validated_changes == 0) | |
3861 { | 3905 { |
3862 /* In the non-conditional execution case, we have to verify that there | 3906 /* In the non-conditional execution case, we have to verify that there |
3863 are no trapping operations, no calls, no references to memory, and | 3907 are no trapping operations, no calls, no references to memory, and |
3864 that any registers modified are dead at the branch site. */ | 3908 that any registers modified are dead at the branch site. */ |
3865 | 3909 |
3871 /* Check for no calls or trapping operations. */ | 3915 /* Check for no calls or trapping operations. */ |
3872 for (insn = head; ; insn = NEXT_INSN (insn)) | 3916 for (insn = head; ; insn = NEXT_INSN (insn)) |
3873 { | 3917 { |
3874 if (CALL_P (insn)) | 3918 if (CALL_P (insn)) |
3875 return FALSE; | 3919 return FALSE; |
3876 if (INSN_P (insn)) | 3920 if (NONDEBUG_INSN_P (insn)) |
3877 { | 3921 { |
3878 if (may_trap_p (PATTERN (insn))) | 3922 if (may_trap_p (PATTERN (insn))) |
3879 return FALSE; | 3923 return FALSE; |
3880 | 3924 |
3881 /* ??? Even non-trapping memories such as stack frame | 3925 /* ??? Even non-trapping memories such as stack frame |
3917 if (max_regno < max_reg_num ()) | 3961 if (max_regno < max_reg_num ()) |
3918 max_regno = max_reg_num (); | 3962 max_regno = max_reg_num (); |
3919 | 3963 |
3920 FOR_BB_INSNS (merge_bb, insn) | 3964 FOR_BB_INSNS (merge_bb, insn) |
3921 { | 3965 { |
3922 if (INSN_P (insn)) | 3966 if (NONDEBUG_INSN_P (insn)) |
3923 { | 3967 { |
3924 unsigned int uid = INSN_UID (insn); | 3968 unsigned int uid = INSN_UID (insn); |
3925 df_ref *def_rec; | 3969 df_ref *def_rec; |
3926 for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) | 3970 for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) |
3927 { | 3971 { |
3941 && ! fixed_regs[i] | 3985 && ! fixed_regs[i] |
3942 && ! global_regs[i]) | 3986 && ! global_regs[i]) |
3943 fail = 1; | 3987 fail = 1; |
3944 } | 3988 } |
3945 } | 3989 } |
3946 | 3990 |
3947 /* For TEST, we're interested in a range of insns, not a whole block. | 3991 /* For TEST, we're interested in a range of insns, not a whole block. |
3948 Moreover, we're interested in the insns live from OTHER_BB. */ | 3992 Moreover, we're interested in the insns live from OTHER_BB. */ |
3949 | 3993 |
3950 /* The loop below takes the set of live registers | 3994 /* The loop below takes the set of live registers |
3951 after JUMP, and calculates the live set before EARLIEST. */ | 3995 after JUMP, and calculates the live set before EARLIEST. */ |
3952 bitmap_copy (test_live, df_get_live_in (other_bb)); | 3996 bitmap_copy (test_live, df_get_live_in (other_bb)); |
3953 df_simulate_initialize_backwards (test_bb, test_live); | 3997 df_simulate_initialize_backwards (test_bb, test_live); |
3954 for (insn = jump; ; insn = prev) | 3998 for (insn = jump; ; insn = prev) |
3955 { | 3999 { |
3995 ? ! invert_jump_1 (jump, new_label) | 4039 ? ! invert_jump_1 (jump, new_label) |
3996 : ! redirect_jump_1 (jump, new_label)) | 4040 : ! redirect_jump_1 (jump, new_label)) |
3997 goto cancel; | 4041 goto cancel; |
3998 } | 4042 } |
3999 | 4043 |
4000 if (! apply_change_group ()) | 4044 if (verify_changes (n_validated_changes)) |
4001 return FALSE; | 4045 confirm_change_group (); |
4046 else | |
4047 goto cancel; | |
4002 | 4048 |
4003 if (other_bb != new_dest) | 4049 if (other_bb != new_dest) |
4004 { | 4050 { |
4005 redirect_jump_2 (jump, old_dest, new_label, 0, reversep); | 4051 redirect_jump_2 (jump, old_dest, new_label, 0, reversep); |
4006 | 4052 |
4038 continue; | 4084 continue; |
4039 note = find_reg_note (insn, REG_EQUAL, NULL_RTX); | 4085 note = find_reg_note (insn, REG_EQUAL, NULL_RTX); |
4040 if (! note) | 4086 if (! note) |
4041 continue; | 4087 continue; |
4042 set = single_set (insn); | 4088 set = single_set (insn); |
4043 if (!set || !function_invariant_p (SET_SRC (set)) | 4089 if (!set || !function_invariant_p (SET_SRC (set))) |
4044 || !function_invariant_p (XEXP (note, 0))) | |
4045 remove_note (insn, note); | 4090 remove_note (insn, note); |
4046 } while (insn != end && (insn = NEXT_INSN (insn))); | 4091 } while (insn != end && (insn = NEXT_INSN (insn))); |
4047 | 4092 |
4048 reorder_insns (head, end, PREV_INSN (earliest)); | 4093 reorder_insns (head, end, PREV_INSN (earliest)); |
4049 } | 4094 } |
4110 #endif | 4155 #endif |
4111 | 4156 |
4112 FOR_EACH_BB (bb) | 4157 FOR_EACH_BB (bb) |
4113 { | 4158 { |
4114 basic_block new_bb; | 4159 basic_block new_bb; |
4115 while (!df_get_bb_dirty (bb) | 4160 while (!df_get_bb_dirty (bb) |
4116 && (new_bb = find_if_header (bb, pass)) != NULL) | 4161 && (new_bb = find_if_header (bb, pass)) != NULL) |
4117 bb = new_bb; | 4162 bb = new_bb; |
4118 } | 4163 } |
4119 | 4164 |
4120 #ifdef IFCVT_MULTIPLE_DUMPS | 4165 #ifdef IFCVT_MULTIPLE_DUMPS |
4121 if (dump_file && cond_exec_changed_p) | 4166 if (dump_file && cond_exec_changed_p) |
4122 { | 4167 print_rtl_with_bb (dump_file, get_insns ()); |
4123 if (dump_flags & TDF_SLIM) | |
4124 print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); | |
4125 else | |
4126 print_rtl_with_bb (dump_file, get_insns ()); | |
4127 } | |
4128 #endif | 4168 #endif |
4129 } | 4169 } |
4130 while (cond_exec_changed_p); | 4170 while (cond_exec_changed_p); |
4131 | 4171 |
4132 #ifdef IFCVT_MULTIPLE_DUMPS | 4172 #ifdef IFCVT_MULTIPLE_DUMPS |