Mercurial > hg > CbC > CbC_gcc
comparison gcc/cse.c @ 146:351920fa3827
merge
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 01 Mar 2020 16:13:28 +0900 |
parents | 1830386684a0 |
children |
comparison
equal
deleted
inserted
replaced
144:8f4e72ab4e11 | 146:351920fa3827 |
---|---|
1 /* Common subexpression elimination for GNU compiler. | 1 /* Common subexpression elimination for GNU compiler. |
2 Copyright (C) 1987-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1987-2020 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
35 #include "cfgrtl.h" | 35 #include "cfgrtl.h" |
36 #include "cfganal.h" | 36 #include "cfganal.h" |
37 #include "cfgcleanup.h" | 37 #include "cfgcleanup.h" |
38 #include "alias.h" | 38 #include "alias.h" |
39 #include "toplev.h" | 39 #include "toplev.h" |
40 #include "params.h" | |
41 #include "rtlhooks-def.h" | 40 #include "rtlhooks-def.h" |
42 #include "tree-pass.h" | 41 #include "tree-pass.h" |
43 #include "dbgcnt.h" | 42 #include "dbgcnt.h" |
44 #include "rtl-iter.h" | 43 #include "rtl-iter.h" |
44 #include "regs.h" | |
45 #include "function-abi.h" | |
45 | 46 |
46 /* The basic idea of common subexpression elimination is to go | 47 /* The basic idea of common subexpression elimination is to go |
47 through the code, keeping a record of expressions that would | 48 through the code, keeping a record of expressions that would |
48 have the same value at the current scan point, and replacing | 49 have the same value at the current scan point, and replacing |
49 expressions encountered with the cheapest equivalent expression. | 50 expressions encountered with the cheapest equivalent expression. |
557 static struct table_elt *insert_with_costs (rtx, struct table_elt *, unsigned, | 558 static struct table_elt *insert_with_costs (rtx, struct table_elt *, unsigned, |
558 machine_mode, int, int); | 559 machine_mode, int, int); |
559 static struct table_elt *insert (rtx, struct table_elt *, unsigned, | 560 static struct table_elt *insert (rtx, struct table_elt *, unsigned, |
560 machine_mode); | 561 machine_mode); |
561 static void merge_equiv_classes (struct table_elt *, struct table_elt *); | 562 static void merge_equiv_classes (struct table_elt *, struct table_elt *); |
562 static void invalidate_reg (rtx, bool); | |
563 static void invalidate (rtx, machine_mode); | 563 static void invalidate (rtx, machine_mode); |
564 static void remove_invalid_refs (unsigned int); | 564 static void remove_invalid_refs (unsigned int); |
565 static void remove_invalid_subreg_refs (unsigned int, poly_uint64, | 565 static void remove_invalid_subreg_refs (unsigned int, poly_uint64, |
566 machine_mode); | 566 machine_mode); |
567 static void rehash_using_reg (rtx); | 567 static void rehash_using_reg (rtx); |
568 static void invalidate_memory (void); | 568 static void invalidate_memory (void); |
569 static void invalidate_for_call (void); | |
570 static rtx use_related_value (rtx, struct table_elt *); | 569 static rtx use_related_value (rtx, struct table_elt *); |
571 | 570 |
572 static inline unsigned canon_hash (rtx, machine_mode); | 571 static inline unsigned canon_hash (rtx, machine_mode); |
573 static inline unsigned safe_hash (rtx, machine_mode); | 572 static inline unsigned safe_hash (rtx, machine_mode); |
574 static inline unsigned hash_rtx_string (const char *); | 573 static inline unsigned hash_rtx_string (const char *); |
1819 } | 1818 } |
1820 return false; | 1819 return false; |
1821 } | 1820 } |
1822 | 1821 |
1823 /* Remove from the hash table, or mark as invalid, all expressions whose | 1822 /* Remove from the hash table, or mark as invalid, all expressions whose |
1824 values could be altered by storing in register X. | 1823 values could be altered by storing in register X. */ |
1825 | |
1826 CLOBBER_HIGH is set if X was part of a CLOBBER_HIGH expression. */ | |
1827 | 1824 |
1828 static void | 1825 static void |
1829 invalidate_reg (rtx x, bool clobber_high) | 1826 invalidate_reg (rtx x) |
1830 { | 1827 { |
1831 gcc_assert (GET_CODE (x) == REG); | 1828 gcc_assert (GET_CODE (x) == REG); |
1832 | 1829 |
1833 /* If X is a register, dependencies on its contents are recorded | 1830 /* If X is a register, dependencies on its contents are recorded |
1834 through the qty number mechanism. Just change the qty number of | 1831 through the qty number mechanism. Just change the qty number of |
1849 delete_reg_equiv (regno); | 1846 delete_reg_equiv (regno); |
1850 REG_TICK (regno)++; | 1847 REG_TICK (regno)++; |
1851 SUBREG_TICKED (regno) = -1; | 1848 SUBREG_TICKED (regno) = -1; |
1852 | 1849 |
1853 if (regno >= FIRST_PSEUDO_REGISTER) | 1850 if (regno >= FIRST_PSEUDO_REGISTER) |
1854 { | 1851 remove_pseudo_from_table (x, hash); |
1855 gcc_assert (!clobber_high); | |
1856 remove_pseudo_from_table (x, hash); | |
1857 } | |
1858 else | 1852 else |
1859 { | 1853 { |
1860 HOST_WIDE_INT in_table = TEST_HARD_REG_BIT (hard_regs_in_table, regno); | 1854 HOST_WIDE_INT in_table = TEST_HARD_REG_BIT (hard_regs_in_table, regno); |
1861 unsigned int endregno = END_REGNO (x); | 1855 unsigned int endregno = END_REGNO (x); |
1862 unsigned int rn; | 1856 unsigned int rn; |
1880 next = p->next_same_hash; | 1874 next = p->next_same_hash; |
1881 | 1875 |
1882 if (!REG_P (p->exp) || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) | 1876 if (!REG_P (p->exp) || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) |
1883 continue; | 1877 continue; |
1884 | 1878 |
1885 if (clobber_high) | 1879 unsigned int tregno = REGNO (p->exp); |
1886 { | 1880 unsigned int tendregno = END_REGNO (p->exp); |
1887 if (reg_is_clobbered_by_clobber_high (p->exp, x)) | 1881 if (tendregno > regno && tregno < endregno) |
1888 remove_from_table (p, hash); | 1882 remove_from_table (p, hash); |
1889 } | |
1890 else | |
1891 { | |
1892 unsigned int tregno = REGNO (p->exp); | |
1893 unsigned int tendregno = END_REGNO (p->exp); | |
1894 if (tendregno > regno && tregno < endregno) | |
1895 remove_from_table (p, hash); | |
1896 } | |
1897 } | 1883 } |
1898 } | 1884 } |
1899 } | 1885 } |
1900 | 1886 |
1901 /* Remove from the hash table, or mark as invalid, all expressions whose | 1887 /* Remove from the hash table, or mark as invalid, all expressions whose |
1918 rtx addr; | 1904 rtx addr; |
1919 | 1905 |
1920 switch (GET_CODE (x)) | 1906 switch (GET_CODE (x)) |
1921 { | 1907 { |
1922 case REG: | 1908 case REG: |
1923 invalidate_reg (x, false); | 1909 invalidate_reg (x); |
1924 return; | 1910 return; |
1925 | 1911 |
1926 case SUBREG: | 1912 case SUBREG: |
1927 invalidate (SUBREG_REG (x), VOIDmode); | 1913 invalidate (SUBREG_REG (x), VOIDmode); |
1928 return; | 1914 return; |
2089 } | 2075 } |
2090 } | 2076 } |
2091 } | 2077 } |
2092 | 2078 |
2093 /* Remove from the hash table any expression that is a call-clobbered | 2079 /* Remove from the hash table any expression that is a call-clobbered |
2094 register. Also update their TICK values. */ | 2080 register in INSN. Also update their TICK values. */ |
2095 | 2081 |
2096 static void | 2082 static void |
2097 invalidate_for_call (void) | 2083 invalidate_for_call (rtx_insn *insn) |
2098 { | 2084 { |
2099 unsigned int regno, endregno; | 2085 unsigned int regno; |
2100 unsigned int i; | |
2101 unsigned hash; | 2086 unsigned hash; |
2102 struct table_elt *p, *next; | 2087 struct table_elt *p, *next; |
2103 int in_table = 0; | 2088 int in_table = 0; |
2104 hard_reg_set_iterator hrsi; | 2089 hard_reg_set_iterator hrsi; |
2105 | 2090 |
2106 /* Go through all the hard registers. For each that is clobbered in | 2091 /* Go through all the hard registers. For each that might be clobbered |
2107 a CALL_INSN, remove the register from quantity chains and update | 2092 in call insn INSN, remove the register from quantity chains and update |
2108 reg_tick if defined. Also see if any of these registers is currently | 2093 reg_tick if defined. Also see if any of these registers is currently |
2109 in the table. */ | 2094 in the table. |
2110 EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, hrsi) | 2095 |
2096 ??? We could be more precise for partially-clobbered registers, | |
2097 and only invalidate values that actually occupy the clobbered part | |
2098 of the registers. It doesn't seem worth the effort though, since | |
2099 we shouldn't see this situation much before RA. Whatever choice | |
2100 we make here has to be consistent with the table walk below, | |
2101 so any change to this test will require a change there too. */ | |
2102 HARD_REG_SET callee_clobbers | |
2103 = insn_callee_abi (insn).full_and_partial_reg_clobbers (); | |
2104 EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, regno, hrsi) | |
2111 { | 2105 { |
2112 delete_reg_equiv (regno); | 2106 delete_reg_equiv (regno); |
2113 if (REG_TICK (regno) >= 0) | 2107 if (REG_TICK (regno) >= 0) |
2114 { | 2108 { |
2115 REG_TICK (regno)++; | 2109 REG_TICK (regno)++; |
2130 | 2124 |
2131 if (!REG_P (p->exp) | 2125 if (!REG_P (p->exp) |
2132 || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) | 2126 || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) |
2133 continue; | 2127 continue; |
2134 | 2128 |
2135 regno = REGNO (p->exp); | 2129 /* This must use the same test as above rather than the |
2136 endregno = END_REGNO (p->exp); | 2130 more accurate clobbers_reg_p. */ |
2137 | 2131 if (overlaps_hard_reg_set_p (callee_clobbers, GET_MODE (p->exp), |
2138 for (i = regno; i < endregno; i++) | 2132 REGNO (p->exp))) |
2139 if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) | 2133 remove_from_table (p, hash); |
2140 { | |
2141 remove_from_table (p, hash); | |
2142 break; | |
2143 } | |
2144 } | 2134 } |
2145 } | 2135 } |
2146 | 2136 |
2147 /* Given an expression X of type CONST, | 2137 /* Given an expression X of type CONST, |
2148 and ELT which is its table entry (or 0 if it | 2138 and ELT which is its table entry (or 0 if it |
4418 This does nothing when a register is clobbered | 4408 This does nothing when a register is clobbered |
4419 because we have already invalidated the reg. */ | 4409 because we have already invalidated the reg. */ |
4420 if (MEM_P (XEXP (x, 0))) | 4410 if (MEM_P (XEXP (x, 0))) |
4421 canon_reg (XEXP (x, 0), insn); | 4411 canon_reg (XEXP (x, 0), insn); |
4422 } | 4412 } |
4423 else if (GET_CODE (x) == CLOBBER_HIGH) | |
4424 gcc_assert (REG_P (XEXP (x, 0))); | |
4425 else if (GET_CODE (x) == USE | 4413 else if (GET_CODE (x) == USE |
4426 && ! (REG_P (XEXP (x, 0)) | 4414 && ! (REG_P (XEXP (x, 0)) |
4427 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)) | 4415 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)) |
4428 /* Canonicalize a USE of a pseudo register or memory location. */ | 4416 /* Canonicalize a USE of a pseudo register or memory location. */ |
4429 canon_reg (x, insn); | 4417 canon_reg (x, insn); |
4451 else if (GET_CODE (y) == CLOBBER) | 4439 else if (GET_CODE (y) == CLOBBER) |
4452 { | 4440 { |
4453 if (MEM_P (XEXP (y, 0))) | 4441 if (MEM_P (XEXP (y, 0))) |
4454 canon_reg (XEXP (y, 0), insn); | 4442 canon_reg (XEXP (y, 0), insn); |
4455 } | 4443 } |
4456 else if (GET_CODE (y) == CLOBBER_HIGH) | |
4457 gcc_assert (REG_P (XEXP (y, 0))); | |
4458 else if (GET_CODE (y) == USE | 4444 else if (GET_CODE (y) == USE |
4459 && ! (REG_P (XEXP (y, 0)) | 4445 && ! (REG_P (XEXP (y, 0)) |
4460 && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER)) | 4446 && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER)) |
4461 canon_reg (y, insn); | 4447 canon_reg (y, insn); |
4462 else if (GET_CODE (y) == ASM_OPERANDS) | 4448 else if (GET_CODE (y) == ASM_OPERANDS) |
5234 else | 5220 else |
5235 { | 5221 { |
5236 trial = elt->exp; | 5222 trial = elt->exp; |
5237 elt = elt->next_same_value; | 5223 elt = elt->next_same_value; |
5238 src_elt_cost = MAX_COST; | 5224 src_elt_cost = MAX_COST; |
5239 } | |
5240 | |
5241 /* Avoid creation of overlapping memory moves. */ | |
5242 if (MEM_P (trial) && MEM_P (dest) && !rtx_equal_p (trial, dest)) | |
5243 { | |
5244 rtx src, dest; | |
5245 | |
5246 /* BLKmode moves are not handled by cse anyway. */ | |
5247 if (GET_MODE (trial) == BLKmode) | |
5248 break; | |
5249 | |
5250 src = canon_rtx (trial); | |
5251 dest = canon_rtx (SET_DEST (sets[i].rtl)); | |
5252 | |
5253 if (!MEM_P (src) || !MEM_P (dest) | |
5254 || !nonoverlapping_memrefs_p (src, dest, false)) | |
5255 break; | |
5256 } | 5225 } |
5257 | 5226 |
5258 /* Try to optimize | 5227 /* Try to optimize |
5259 (set (reg:M N) (const_int A)) | 5228 (set (reg:M N) (const_int A)) |
5260 (set (reg:M2 O) (const_int B)) | 5229 (set (reg:M2 O) (const_int B)) |
5383 && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF | 5352 && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF |
5384 && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF))) | 5353 && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF))) |
5385 /* Do nothing for this case. */ | 5354 /* Do nothing for this case. */ |
5386 ; | 5355 ; |
5387 | 5356 |
5357 /* Do not replace anything with a MEM, except the replacement | |
5358 is a no-op. This allows this loop to terminate. */ | |
5359 else if (MEM_P (trial) && !rtx_equal_p (trial, SET_SRC(sets[i].rtl))) | |
5360 /* Do nothing for this case. */ | |
5361 ; | |
5362 | |
5388 /* Look for a substitution that makes a valid insn. */ | 5363 /* Look for a substitution that makes a valid insn. */ |
5389 else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl), | 5364 else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl), |
5390 trial, 0)) | 5365 trial, 0)) |
5391 { | 5366 { |
5392 rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn); | 5367 rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn); |
5832 those are owned by the callee. */ | 5807 those are owned by the callee. */ |
5833 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) | 5808 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) |
5834 if (GET_CODE (XEXP (tem, 0)) == USE | 5809 if (GET_CODE (XEXP (tem, 0)) == USE |
5835 && MEM_P (XEXP (XEXP (tem, 0), 0))) | 5810 && MEM_P (XEXP (XEXP (tem, 0), 0))) |
5836 invalidate (XEXP (XEXP (tem, 0), 0), VOIDmode); | 5811 invalidate (XEXP (XEXP (tem, 0), 0), VOIDmode); |
5837 invalidate_for_call (); | 5812 invalidate_for_call (insn); |
5838 } | 5813 } |
5839 | 5814 |
5840 /* Now invalidate everything set by this instruction. | 5815 /* Now invalidate everything set by this instruction. |
5841 If a SUBREG or other funny destination is being set, | 5816 If a SUBREG or other funny destination is being set, |
5842 sets[i].rtl is still nonzero, so here we invalidate the reg | 5817 sets[i].rtl is still nonzero, so here we invalidate the reg |
6153 else if (GET_CODE (ref) == STRICT_LOW_PART | 6128 else if (GET_CODE (ref) == STRICT_LOW_PART |
6154 || GET_CODE (ref) == ZERO_EXTRACT) | 6129 || GET_CODE (ref) == ZERO_EXTRACT) |
6155 invalidate (XEXP (ref, 0), GET_MODE (ref)); | 6130 invalidate (XEXP (ref, 0), GET_MODE (ref)); |
6156 } | 6131 } |
6157 } | 6132 } |
6158 if (GET_CODE (x) == CLOBBER_HIGH) | |
6159 { | |
6160 rtx ref = XEXP (x, 0); | |
6161 gcc_assert (REG_P (ref)); | |
6162 invalidate_reg (ref, true); | |
6163 } | |
6164 else if (GET_CODE (x) == PARALLEL) | 6133 else if (GET_CODE (x) == PARALLEL) |
6165 { | 6134 { |
6166 int i; | 6135 int i; |
6167 for (i = XVECLEN (x, 0) - 1; i >= 0; i--) | 6136 for (i = XVECLEN (x, 0) - 1; i >= 0; i--) |
6168 { | 6137 { |
6175 invalidate (ref, VOIDmode); | 6144 invalidate (ref, VOIDmode); |
6176 else if (GET_CODE (ref) == STRICT_LOW_PART | 6145 else if (GET_CODE (ref) == STRICT_LOW_PART |
6177 || GET_CODE (ref) == ZERO_EXTRACT) | 6146 || GET_CODE (ref) == ZERO_EXTRACT) |
6178 invalidate (XEXP (ref, 0), GET_MODE (ref)); | 6147 invalidate (XEXP (ref, 0), GET_MODE (ref)); |
6179 } | 6148 } |
6180 else if (GET_CODE (y) == CLOBBER_HIGH) | |
6181 { | |
6182 rtx ref = XEXP (y, 0); | |
6183 gcc_assert (REG_P (ref)); | |
6184 invalidate_reg (ref, true); | |
6185 } | |
6186 } | 6149 } |
6187 } | 6150 } |
6188 } | 6151 } |
6189 | 6152 |
6190 /* Perform invalidation on the basis of everything about INSN. | 6153 /* Perform invalidation on the basis of everything about INSN. |
6202 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) | 6165 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1)) |
6203 { | 6166 { |
6204 rtx temx = XEXP (tem, 0); | 6167 rtx temx = XEXP (tem, 0); |
6205 if (GET_CODE (temx) == CLOBBER) | 6168 if (GET_CODE (temx) == CLOBBER) |
6206 invalidate (SET_DEST (temx), VOIDmode); | 6169 invalidate (SET_DEST (temx), VOIDmode); |
6207 else if (GET_CODE (temx) == CLOBBER_HIGH) | |
6208 { | |
6209 rtx temref = XEXP (temx, 0); | |
6210 gcc_assert (REG_P (temref)); | |
6211 invalidate_reg (temref, true); | |
6212 } | |
6213 } | 6170 } |
6214 } | 6171 } |
6215 | 6172 |
6216 /* Ensure we invalidate the destination register of a CALL insn. | 6173 /* Ensure we invalidate the destination register of a CALL insn. |
6217 This is necessary for machines where this register is a fixed_reg, | 6174 This is necessary for machines where this register is a fixed_reg, |
6234 || GET_CODE (clobbered) == SUBREG) | 6191 || GET_CODE (clobbered) == SUBREG) |
6235 invalidate (clobbered, VOIDmode); | 6192 invalidate (clobbered, VOIDmode); |
6236 else if (GET_CODE (clobbered) == STRICT_LOW_PART | 6193 else if (GET_CODE (clobbered) == STRICT_LOW_PART |
6237 || GET_CODE (clobbered) == ZERO_EXTRACT) | 6194 || GET_CODE (clobbered) == ZERO_EXTRACT) |
6238 invalidate (XEXP (clobbered, 0), GET_MODE (clobbered)); | 6195 invalidate (XEXP (clobbered, 0), GET_MODE (clobbered)); |
6239 } | |
6240 else if (GET_CODE (y) == CLOBBER_HIGH) | |
6241 { | |
6242 rtx ref = XEXP (y, 0); | |
6243 gcc_assert (REG_P (ref)); | |
6244 invalidate_reg (ref, true); | |
6245 } | 6196 } |
6246 else if (GET_CODE (y) == SET && GET_CODE (SET_SRC (y)) == CALL) | 6197 else if (GET_CODE (y) == SET && GET_CODE (SET_SRC (y)) == CALL) |
6247 invalidate (SET_DEST (y), VOIDmode); | 6198 invalidate (SET_DEST (y), VOIDmode); |
6248 } | 6199 } |
6249 } | 6200 } |
6460 | 6411 |
6461 /* Extend the path if possible. */ | 6412 /* Extend the path if possible. */ |
6462 if (follow_jumps) | 6413 if (follow_jumps) |
6463 { | 6414 { |
6464 bb = data->path[path_size - 1].bb; | 6415 bb = data->path[path_size - 1].bb; |
6465 while (bb && path_size < PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH)) | 6416 while (bb && path_size < param_max_cse_path_length) |
6466 { | 6417 { |
6467 if (single_succ_p (bb)) | 6418 if (single_succ_p (bb)) |
6468 e = single_succ_edge (bb); | 6419 e = single_succ_edge (bb); |
6469 else if (EDGE_COUNT (bb->succs) == 2 | 6420 else if (EDGE_COUNT (bb->succs) == 2 |
6470 && any_condjump_p (BB_END (bb))) | 6421 && any_condjump_p (BB_END (bb))) |
6510 int path_entry; | 6461 int path_entry; |
6511 | 6462 |
6512 fprintf (f, ";; Following path with %d sets: ", nsets); | 6463 fprintf (f, ";; Following path with %d sets: ", nsets); |
6513 for (path_entry = 0; path_entry < data->path_size; path_entry++) | 6464 for (path_entry = 0; path_entry < data->path_size; path_entry++) |
6514 fprintf (f, "%d ", (data->path[path_entry].bb)->index); | 6465 fprintf (f, "%d ", (data->path[path_entry].bb)->index); |
6515 fputc ('\n', dump_file); | 6466 fputc ('\n', f); |
6516 fflush (f); | 6467 fflush (f); |
6517 } | 6468 } |
6518 | 6469 |
6519 | 6470 |
6520 /* Return true if BB has exception handling successor edges. */ | 6471 /* Return true if BB has exception handling successor edges. */ |
6638 generated with -O but not -g. | 6589 generated with -O but not -g. |
6639 | 6590 |
6640 FIXME: This is a real kludge and needs to be done some other | 6591 FIXME: This is a real kludge and needs to be done some other |
6641 way. */ | 6592 way. */ |
6642 if (NONDEBUG_INSN_P (insn) | 6593 if (NONDEBUG_INSN_P (insn) |
6643 && num_insns++ > PARAM_VALUE (PARAM_MAX_CSE_INSNS)) | 6594 && num_insns++ > param_max_cse_insns) |
6644 { | 6595 { |
6645 flush_hash_table (); | 6596 flush_hash_table (); |
6646 num_insns = 0; | 6597 num_insns = 0; |
6647 } | 6598 } |
6648 | 6599 |
6782 | 6733 |
6783 reg_scan (get_insns (), max_reg_num ()); | 6734 reg_scan (get_insns (), max_reg_num ()); |
6784 init_cse_reg_info (nregs); | 6735 init_cse_reg_info (nregs); |
6785 | 6736 |
6786 ebb_data.path = XNEWVEC (struct branch_path, | 6737 ebb_data.path = XNEWVEC (struct branch_path, |
6787 PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH)); | 6738 param_max_cse_path_length); |
6788 | 6739 |
6789 cse_cfg_altered = false; | 6740 cse_cfg_altered = false; |
6790 cse_jumps_altered = false; | 6741 cse_jumps_altered = false; |
6791 recorded_label_ref = false; | 6742 recorded_label_ref = false; |
6792 constant_pool_entries_cost = 0; | 6743 constant_pool_entries_cost = 0; |
6898 case CLOBBER: | 6849 case CLOBBER: |
6899 /* If we are clobbering a MEM, mark any registers inside the address | 6850 /* If we are clobbering a MEM, mark any registers inside the address |
6900 as being used. */ | 6851 as being used. */ |
6901 if (MEM_P (XEXP (x, 0))) | 6852 if (MEM_P (XEXP (x, 0))) |
6902 count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr); | 6853 count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr); |
6903 return; | |
6904 | |
6905 case CLOBBER_HIGH: | |
6906 gcc_assert (REG_P ((XEXP (x, 0)))); | |
6907 return; | 6854 return; |
6908 | 6855 |
6909 case SET: | 6856 case SET: |
6910 /* Unless we are setting a REG, count everything in SET_DEST. */ | 6857 /* Unless we are setting a REG, count everything in SET_DEST. */ |
6911 if (!REG_P (SET_DEST (x))) | 6858 if (!REG_P (SET_DEST (x))) |
6956 case EXPR_LIST: | 6903 case EXPR_LIST: |
6957 if (REG_NOTE_KIND (x) == REG_EQUAL | 6904 if (REG_NOTE_KIND (x) == REG_EQUAL |
6958 || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE) | 6905 || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE) |
6959 /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)), | 6906 /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)), |
6960 involving registers in the address. */ | 6907 involving registers in the address. */ |
6961 || GET_CODE (XEXP (x, 0)) == CLOBBER | 6908 || GET_CODE (XEXP (x, 0)) == CLOBBER) |
6962 || GET_CODE (XEXP (x, 0)) == CLOBBER_HIGH) | |
6963 count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr); | 6909 count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr); |
6964 | 6910 |
6965 count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); | 6911 count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); |
6966 return; | 6912 return; |
6967 | 6913 |
7041 if (GET_CODE (elt) == SET) | 6987 if (GET_CODE (elt) == SET) |
7042 { | 6988 { |
7043 if (set_live_p (elt, insn, counts)) | 6989 if (set_live_p (elt, insn, counts)) |
7044 return true; | 6990 return true; |
7045 } | 6991 } |
7046 else if (GET_CODE (elt) != CLOBBER | 6992 else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE) |
7047 && GET_CODE (elt) != CLOBBER_HIGH | |
7048 && GET_CODE (elt) != USE) | |
7049 return true; | 6993 return true; |
7050 } | 6994 } |
7051 return false; | 6995 return false; |
7052 } | 6996 } |
7053 else if (DEBUG_INSN_P (insn)) | 6997 else if (DEBUG_INSN_P (insn)) |
7156 count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg, | 7100 count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg, |
7157 NULL_RTX, 1); | 7101 NULL_RTX, 1); |
7158 else if (INSN_P (insn)) | 7102 else if (INSN_P (insn)) |
7159 { | 7103 { |
7160 count_reg_usage (insn, counts, NULL_RTX, 1); | 7104 count_reg_usage (insn, counts, NULL_RTX, 1); |
7161 note_stores (PATTERN (insn), count_stores, counts + nreg * 2); | 7105 note_stores (insn, count_stores, counts + nreg * 2); |
7162 } | 7106 } |
7163 /* If there can be debug insns, COUNTS are 3 consecutive arrays. | 7107 /* If there can be debug insns, COUNTS are 3 consecutive arrays. |
7164 First one counts how many times each pseudo is used outside | 7108 First one counts how many times each pseudo is used outside |
7165 of debug insns, second counts how many times each pseudo is | 7109 of debug insns, second counts how many times each pseudo is |
7166 used in debug insns and third counts how many times a pseudo | 7110 used in debug insns and third counts how many times a pseudo |
7755 timevar_push (TV_JUMP); | 7699 timevar_push (TV_JUMP); |
7756 rebuild_jump_labels (get_insns ()); | 7700 rebuild_jump_labels (get_insns ()); |
7757 cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED); | 7701 cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED); |
7758 timevar_pop (TV_JUMP); | 7702 timevar_pop (TV_JUMP); |
7759 } | 7703 } |
7760 else if (tem == 1) | 7704 else if (tem == 1 || cse_cfg_altered) |
7761 cse_cfg_altered |= cleanup_cfg (0); | 7705 cse_cfg_altered |= cleanup_cfg (0); |
7762 | 7706 |
7763 cse_not_expected = 1; | 7707 cse_not_expected = 1; |
7764 return 0; | 7708 return 0; |
7765 } | 7709 } |
7829 timevar_push (TV_JUMP); | 7773 timevar_push (TV_JUMP); |
7830 rebuild_jump_labels (get_insns ()); | 7774 rebuild_jump_labels (get_insns ()); |
7831 cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED); | 7775 cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED); |
7832 timevar_pop (TV_JUMP); | 7776 timevar_pop (TV_JUMP); |
7833 } | 7777 } |
7834 else if (tem == 1) | 7778 else if (tem == 1 || cse_cfg_altered) |
7835 cse_cfg_altered |= cleanup_cfg (0); | 7779 cse_cfg_altered |= cleanup_cfg (0); |
7836 | 7780 |
7837 flag_cse_follow_jumps = save_cfj; | 7781 flag_cse_follow_jumps = save_cfj; |
7838 return 0; | 7782 return 0; |
7839 } | 7783 } |