Mercurial > hg > CbC > CbC_gcc
comparison gcc/recog.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Subroutines used by or related to instruction recognition. | 1 /* Subroutines used by or related to instruction recognition. |
2 Copyright (C) 1987-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1987-2018 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 |
1004 may result in incorrect reference. We should simplify all valid | 1004 may result in incorrect reference. We should simplify all valid |
1005 subregs of MEM anyway. But allow this after reload because we | 1005 subregs of MEM anyway. But allow this after reload because we |
1006 might be called from cleanup_subreg_operands. | 1006 might be called from cleanup_subreg_operands. |
1007 | 1007 |
1008 ??? This is a kludge. */ | 1008 ??? This is a kludge. */ |
1009 if (!reload_completed && SUBREG_BYTE (op) != 0 | 1009 if (!reload_completed |
1010 && maybe_ne (SUBREG_BYTE (op), 0) | |
1010 && MEM_P (sub)) | 1011 && MEM_P (sub)) |
1011 return 0; | 1012 return 0; |
1012 | 1013 |
1013 if (REG_P (sub) | 1014 if (REG_P (sub) |
1014 && REGNO (sub) < FIRST_PSEUDO_REGISTER | 1015 && REGNO (sub) < FIRST_PSEUDO_REGISTER |
1255 expressions in the machine description. */ | 1256 expressions in the machine description. */ |
1256 | 1257 |
1257 int | 1258 int |
1258 push_operand (rtx op, machine_mode mode) | 1259 push_operand (rtx op, machine_mode mode) |
1259 { | 1260 { |
1260 unsigned int rounded_size = GET_MODE_SIZE (mode); | |
1261 | |
1262 #ifdef PUSH_ROUNDING | |
1263 rounded_size = PUSH_ROUNDING (rounded_size); | |
1264 #endif | |
1265 | |
1266 if (!MEM_P (op)) | 1261 if (!MEM_P (op)) |
1267 return 0; | 1262 return 0; |
1268 | 1263 |
1269 if (mode != VOIDmode && GET_MODE (op) != mode) | 1264 if (mode != VOIDmode && GET_MODE (op) != mode) |
1270 return 0; | 1265 return 0; |
1271 | 1266 |
1267 poly_int64 rounded_size = GET_MODE_SIZE (mode); | |
1268 | |
1269 #ifdef PUSH_ROUNDING | |
1270 rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size)); | |
1271 #endif | |
1272 | |
1272 op = XEXP (op, 0); | 1273 op = XEXP (op, 0); |
1273 | 1274 |
1274 if (rounded_size == GET_MODE_SIZE (mode)) | 1275 if (known_eq (rounded_size, GET_MODE_SIZE (mode))) |
1275 { | 1276 { |
1276 if (GET_CODE (op) != STACK_PUSH_CODE) | 1277 if (GET_CODE (op) != STACK_PUSH_CODE) |
1277 return 0; | 1278 return 0; |
1278 } | 1279 } |
1279 else | 1280 else |
1280 { | 1281 { |
1282 poly_int64 offset; | |
1281 if (GET_CODE (op) != PRE_MODIFY | 1283 if (GET_CODE (op) != PRE_MODIFY |
1282 || GET_CODE (XEXP (op, 1)) != PLUS | 1284 || GET_CODE (XEXP (op, 1)) != PLUS |
1283 || XEXP (XEXP (op, 1), 0) != XEXP (op, 0) | 1285 || XEXP (XEXP (op, 1), 0) != XEXP (op, 0) |
1284 || !CONST_INT_P (XEXP (XEXP (op, 1), 1)) | 1286 || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset) |
1285 || INTVAL (XEXP (XEXP (op, 1), 1)) | 1287 || (STACK_GROWS_DOWNWARD |
1286 != ((STACK_GROWS_DOWNWARD ? -1 : 1) * (int) rounded_size)) | 1288 ? maybe_ne (offset, -rounded_size) |
1289 : maybe_ne (offset, rounded_size))) | |
1287 return 0; | 1290 return 0; |
1288 } | 1291 } |
1289 | 1292 |
1290 return XEXP (op, 0) == stack_pointer_rtx; | 1293 return XEXP (op, 0) == stack_pointer_rtx; |
1291 } | 1294 } |
1366 { | 1369 { |
1367 /* Before reload, a SUBREG isn't in memory (see memory_operand, above). */ | 1370 /* Before reload, a SUBREG isn't in memory (see memory_operand, above). */ |
1368 if (! reload_completed | 1371 if (! reload_completed |
1369 && GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))) | 1372 && GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))) |
1370 { | 1373 { |
1371 int offset = SUBREG_BYTE (op); | |
1372 rtx inner = SUBREG_REG (op); | |
1373 | |
1374 if (mode != VOIDmode && GET_MODE (op) != mode) | 1374 if (mode != VOIDmode && GET_MODE (op) != mode) |
1375 return 0; | 1375 return 0; |
1376 | 1376 |
1377 /* The only way that we can have a general_operand as the resulting | 1377 /* The only way that we can have a general_operand as the resulting |
1378 address is if OFFSET is zero and the address already is an operand | 1378 address is if OFFSET is zero and the address already is an operand |
1379 or if the address is (plus Y (const_int -OFFSET)) and Y is an | 1379 or if the address is (plus Y (const_int -OFFSET)) and Y is an |
1380 operand. */ | 1380 operand. */ |
1381 | 1381 poly_int64 offset; |
1382 return ((offset == 0 && general_operand (XEXP (inner, 0), Pmode)) | 1382 rtx addr = strip_offset (XEXP (SUBREG_REG (op), 0), &offset); |
1383 || (GET_CODE (XEXP (inner, 0)) == PLUS | 1383 return (known_eq (offset + SUBREG_BYTE (op), 0) |
1384 && CONST_INT_P (XEXP (XEXP (inner, 0), 1)) | 1384 && general_operand (addr, Pmode)); |
1385 && INTVAL (XEXP (XEXP (inner, 0), 1)) == -offset | |
1386 && general_operand (XEXP (XEXP (inner, 0), 0), Pmode))); | |
1387 } | 1385 } |
1388 | 1386 |
1389 return (MEM_P (op) | 1387 return (MEM_P (op) |
1390 && memory_operand (op, mode) | 1388 && memory_operand (op, mode) |
1391 && general_operand (XEXP (op, 0), Pmode)); | 1389 && general_operand (XEXP (op, 0), Pmode)); |
1600 the SETs. Their constraints are in the ASM_OPERANDS itself. */ | 1598 the SETs. Their constraints are in the ASM_OPERANDS itself. */ |
1601 for (i = 0; i < nparallel; i++) | 1599 for (i = 0; i < nparallel; i++) |
1602 { | 1600 { |
1603 if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER) | 1601 if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER) |
1604 break; /* Past last SET */ | 1602 break; /* Past last SET */ |
1603 gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET); | |
1605 if (operands) | 1604 if (operands) |
1606 operands[i] = SET_DEST (XVECEXP (body, 0, i)); | 1605 operands[i] = SET_DEST (XVECEXP (body, 0, i)); |
1607 if (operand_locs) | 1606 if (operand_locs) |
1608 operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i)); | 1607 operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i)); |
1609 if (constraints) | 1608 if (constraints) |
1825 break; | 1824 break; |
1826 } | 1825 } |
1827 len = CONSTRAINT_LEN (c, constraint); | 1826 len = CONSTRAINT_LEN (c, constraint); |
1828 do | 1827 do |
1829 constraint++; | 1828 constraint++; |
1830 while (--len && *constraint); | 1829 while (--len && *constraint && *constraint != ','); |
1831 if (len) | 1830 if (len) |
1832 return 0; | 1831 return 0; |
1833 } | 1832 } |
1834 | 1833 |
1835 /* For operands without < or > constraints reject side-effects. */ | 1834 /* For operands without < or > constraints reject side-effects. */ |
1945 rtx y1 = y; | 1944 rtx y1 = y; |
1946 rtx *y2; | 1945 rtx *y2; |
1947 int (*addressp) (machine_mode, rtx, addr_space_t) = | 1946 int (*addressp) (machine_mode, rtx, addr_space_t) = |
1948 (strictp ? strict_memory_address_addr_space_p | 1947 (strictp ? strict_memory_address_addr_space_p |
1949 : memory_address_addr_space_p); | 1948 : memory_address_addr_space_p); |
1950 unsigned int mode_sz = GET_MODE_SIZE (mode); | 1949 poly_int64 mode_sz = GET_MODE_SIZE (mode); |
1951 | 1950 |
1952 if (CONSTANT_ADDRESS_P (y)) | 1951 if (CONSTANT_ADDRESS_P (y)) |
1953 return 1; | 1952 return 1; |
1954 | 1953 |
1955 /* Adjusting an offsettable address involves changing to a narrower mode. | 1954 /* Adjusting an offsettable address involves changing to a narrower mode. |
1967 | 1966 |
1968 /* ??? How much offset does an offsettable BLKmode reference need? | 1967 /* ??? How much offset does an offsettable BLKmode reference need? |
1969 Clearly that depends on the situation in which it's being used. | 1968 Clearly that depends on the situation in which it's being used. |
1970 However, the current situation in which we test 0xffffffff is | 1969 However, the current situation in which we test 0xffffffff is |
1971 less than ideal. Caveat user. */ | 1970 less than ideal. Caveat user. */ |
1972 if (mode_sz == 0) | 1971 if (known_eq (mode_sz, 0)) |
1973 mode_sz = BIGGEST_ALIGNMENT / BITS_PER_UNIT; | 1972 mode_sz = BIGGEST_ALIGNMENT / BITS_PER_UNIT; |
1974 | 1973 |
1975 /* If the expression contains a constant term, | 1974 /* If the expression contains a constant term, |
1976 see if it remains valid when max possible offset is added. */ | 1975 see if it remains valid when max possible offset is added. */ |
1977 | 1976 |
1998 of the specified mode. We assume that if Y and Y+c are | 1997 of the specified mode. We assume that if Y and Y+c are |
1999 valid addresses then so is Y+d for all 0<d<c. adjust_address will | 1998 valid addresses then so is Y+d for all 0<d<c. adjust_address will |
2000 go inside a LO_SUM here, so we do so as well. */ | 1999 go inside a LO_SUM here, so we do so as well. */ |
2001 if (GET_CODE (y) == LO_SUM | 2000 if (GET_CODE (y) == LO_SUM |
2002 && mode != BLKmode | 2001 && mode != BLKmode |
2003 && mode_sz <= GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT) | 2002 && known_le (mode_sz, GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT)) |
2004 z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0), | 2003 z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0), |
2005 plus_constant (address_mode, XEXP (y, 1), | 2004 plus_constant (address_mode, XEXP (y, 1), |
2006 mode_sz - 1)); | 2005 mode_sz - 1)); |
2007 #ifdef POINTERS_EXTEND_UNSIGNED | 2006 #ifdef POINTERS_EXTEND_UNSIGNED |
2008 /* Likewise for a ZERO_EXTEND from pointer_mode. */ | 2007 /* Likewise for a ZERO_EXTEND from pointer_mode. */ |
2250 case CLOBBER: | 2249 case CLOBBER: |
2251 case ASM_INPUT: | 2250 case ASM_INPUT: |
2252 case ADDR_VEC: | 2251 case ADDR_VEC: |
2253 case ADDR_DIFF_VEC: | 2252 case ADDR_DIFF_VEC: |
2254 case VAR_LOCATION: | 2253 case VAR_LOCATION: |
2254 case DEBUG_MARKER: | |
2255 return; | 2255 return; |
2256 | 2256 |
2257 case SET: | 2257 case SET: |
2258 if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS) | 2258 if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS) |
2259 goto asm_insn; | 2259 goto asm_insn; |
2330 | 2330 |
2331 recog_data.insn = NULL; | 2331 recog_data.insn = NULL; |
2332 which_alternative = -1; | 2332 which_alternative = -1; |
2333 } | 2333 } |
2334 | 2334 |
2335 /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS operands, | 2335 /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS |
2336 N_ALTERNATIVES alternatives and constraint strings CONSTRAINTS. | 2336 operands, N_ALTERNATIVES alternatives and constraint strings |
2337 OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries and CONSTRAINTS | 2337 CONSTRAINTS. OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries |
2338 has N_OPERANDS entries. */ | 2338 and CONSTRAINTS has N_OPERANDS entries. OPLOC should be passed in |
2339 if the insn is an asm statement and preprocessing should take the | |
2340 asm operands into account, e.g. to determine whether they could be | |
2341 addresses in constraints that require addresses; it should then | |
2342 point to an array of pointers to each operand. */ | |
2339 | 2343 |
2340 void | 2344 void |
2341 preprocess_constraints (int n_operands, int n_alternatives, | 2345 preprocess_constraints (int n_operands, int n_alternatives, |
2342 const char **constraints, | 2346 const char **constraints, |
2343 operand_alternative *op_alt_base) | 2347 operand_alternative *op_alt_base, |
2348 rtx **oploc) | |
2344 { | 2349 { |
2345 for (int i = 0; i < n_operands; i++) | 2350 for (int i = 0; i < n_operands; i++) |
2346 { | 2351 { |
2347 int j; | 2352 int j; |
2348 struct operand_alternative *op_alt; | 2353 struct operand_alternative *op_alt; |
2425 case CT_SPECIAL_MEMORY: | 2430 case CT_SPECIAL_MEMORY: |
2426 op_alt[i].memory_ok = 1; | 2431 op_alt[i].memory_ok = 1; |
2427 break; | 2432 break; |
2428 | 2433 |
2429 case CT_ADDRESS: | 2434 case CT_ADDRESS: |
2435 if (oploc && !address_operand (*oploc[i], VOIDmode)) | |
2436 break; | |
2437 | |
2430 op_alt[i].is_address = 1; | 2438 op_alt[i].is_address = 1; |
2431 op_alt[i].cl | 2439 op_alt[i].cl |
2432 = (reg_class_subunion | 2440 = (reg_class_subunion |
2433 [(int) op_alt[i].cl] | 2441 [(int) op_alt[i].cl] |
2434 [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, | 2442 [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, |
2469 operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries); | 2477 operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries); |
2470 const char **constraints = XALLOCAVEC (const char *, n_operands); | 2478 const char **constraints = XALLOCAVEC (const char *, n_operands); |
2471 | 2479 |
2472 for (int i = 0; i < n_operands; ++i) | 2480 for (int i = 0; i < n_operands; ++i) |
2473 constraints[i] = insn_data[icode].operand[i].constraint; | 2481 constraints[i] = insn_data[icode].operand[i].constraint; |
2474 preprocess_constraints (n_operands, n_alternatives, constraints, op_alt); | 2482 preprocess_constraints (n_operands, n_alternatives, constraints, op_alt, |
2483 NULL); | |
2475 | 2484 |
2476 this_target_recog->x_op_alt[icode] = op_alt; | 2485 this_target_recog->x_op_alt[icode] = op_alt; |
2477 return op_alt; | 2486 return op_alt; |
2478 } | 2487 } |
2479 | 2488 |
2492 int n_operands = recog_data.n_operands; | 2501 int n_operands = recog_data.n_operands; |
2493 int n_alternatives = recog_data.n_alternatives; | 2502 int n_alternatives = recog_data.n_alternatives; |
2494 int n_entries = n_operands * n_alternatives; | 2503 int n_entries = n_operands * n_alternatives; |
2495 memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative)); | 2504 memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative)); |
2496 preprocess_constraints (n_operands, n_alternatives, | 2505 preprocess_constraints (n_operands, n_alternatives, |
2497 recog_data.constraints, asm_op_alt); | 2506 recog_data.constraints, asm_op_alt, |
2507 NULL); | |
2498 recog_op_alt = asm_op_alt; | 2508 recog_op_alt = asm_op_alt; |
2499 } | 2509 } |
2500 } | 2510 } |
2501 | 2511 |
2502 /* Check the operands of an insn against the insn's operand constraints | 2512 /* Check the operands of an insn against the insn's operand constraints |
2930 | 2940 |
2931 void | 2941 void |
2932 split_all_insns (void) | 2942 split_all_insns (void) |
2933 { | 2943 { |
2934 bool changed; | 2944 bool changed; |
2945 bool need_cfg_cleanup = false; | |
2935 basic_block bb; | 2946 basic_block bb; |
2936 | 2947 |
2937 auto_sbitmap blocks (last_basic_block_for_fn (cfun)); | 2948 auto_sbitmap blocks (last_basic_block_for_fn (cfun)); |
2938 bitmap_clear (blocks); | 2949 bitmap_clear (blocks); |
2939 changed = false; | 2950 changed = false; |
2948 { | 2959 { |
2949 /* Can't use `next_real_insn' because that might go across | 2960 /* Can't use `next_real_insn' because that might go across |
2950 CODE_LABELS and short-out basic blocks. */ | 2961 CODE_LABELS and short-out basic blocks. */ |
2951 next = NEXT_INSN (insn); | 2962 next = NEXT_INSN (insn); |
2952 finish = (insn == BB_END (bb)); | 2963 finish = (insn == BB_END (bb)); |
2964 | |
2965 /* If INSN has a REG_EH_REGION note and we split INSN, the | |
2966 resulting split may not have/need REG_EH_REGION notes. | |
2967 | |
2968 If that happens and INSN was the last reference to the | |
2969 given EH region, then the EH region will become unreachable. | |
2970 We can not leave the unreachable blocks in the CFG as that | |
2971 will trigger a checking failure. | |
2972 | |
2973 So track if INSN has a REG_EH_REGION note. If so and we | |
2974 split INSN, then trigger a CFG cleanup. */ | |
2975 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); | |
2953 if (INSN_P (insn)) | 2976 if (INSN_P (insn)) |
2954 { | 2977 { |
2955 rtx set = single_set (insn); | 2978 rtx set = single_set (insn); |
2956 | 2979 |
2957 /* Don't split no-op move insns. These should silently | 2980 /* Don't split no-op move insns. These should silently |
2964 is too risky to try to do this before register | 2987 is too risky to try to do this before register |
2965 allocation, and there are unlikely to be very many | 2988 allocation, and there are unlikely to be very many |
2966 nops then anyways. */ | 2989 nops then anyways. */ |
2967 if (reload_completed) | 2990 if (reload_completed) |
2968 delete_insn_and_edges (insn); | 2991 delete_insn_and_edges (insn); |
2992 if (note) | |
2993 need_cfg_cleanup = true; | |
2969 } | 2994 } |
2970 else | 2995 else |
2971 { | 2996 { |
2972 if (split_insn (insn)) | 2997 if (split_insn (insn)) |
2973 { | 2998 { |
2974 bitmap_set_bit (blocks, bb->index); | 2999 bitmap_set_bit (blocks, bb->index); |
2975 changed = true; | 3000 changed = true; |
3001 if (note) | |
3002 need_cfg_cleanup = true; | |
2976 } | 3003 } |
2977 } | 3004 } |
2978 } | 3005 } |
2979 } | 3006 } |
2980 } | 3007 } |
2981 | 3008 |
2982 default_rtl_profile (); | 3009 default_rtl_profile (); |
2983 if (changed) | 3010 if (changed) |
2984 find_many_sub_basic_blocks (blocks); | 3011 { |
3012 find_many_sub_basic_blocks (blocks); | |
3013 | |
3014 /* Splitting could drop an REG_EH_REGION if it potentially | |
3015 trapped in its original form, but does not in its split | |
3016 form. Consider a FLOAT_TRUNCATE which splits into a memory | |
3017 store/load pair and -fnon-call-exceptions. */ | |
3018 if (need_cfg_cleanup) | |
3019 cleanup_cfg (0); | |
3020 } | |
2985 | 3021 |
2986 checking_verify_flow_info (); | 3022 checking_verify_flow_info (); |
2987 } | 3023 } |
2988 | 3024 |
2989 /* Same as split_all_insns, but do not expect CFG to be available. | 3025 /* Same as split_all_insns, but do not expect CFG to be available. |
3419 /* Replace the old sequence with the new. */ | 3455 /* Replace the old sequence with the new. */ |
3420 rtx_insn *peepinsn = peep2_insn_data[i].insn; | 3456 rtx_insn *peepinsn = peep2_insn_data[i].insn; |
3421 last = emit_insn_after_setloc (attempt, | 3457 last = emit_insn_after_setloc (attempt, |
3422 peep2_insn_data[i].insn, | 3458 peep2_insn_data[i].insn, |
3423 INSN_LOCATION (peepinsn)); | 3459 INSN_LOCATION (peepinsn)); |
3460 if (JUMP_P (peepinsn) && JUMP_P (last)) | |
3461 CROSSING_JUMP_P (last) = CROSSING_JUMP_P (peepinsn); | |
3424 before_try = PREV_INSN (insn); | 3462 before_try = PREV_INSN (insn); |
3425 delete_insn_chain (insn, peep2_insn_data[i].insn, false); | 3463 delete_insn_chain (insn, peep2_insn_data[i].insn, false); |
3426 | 3464 |
3427 /* Re-insert the EH_REGION notes. */ | 3465 /* Re-insert the EH_REGION notes. */ |
3428 if (eh_note || (was_call && nonlocal_goto_handler_labels)) | 3466 if (eh_note || (was_call && nonlocal_goto_handler_labels)) |
3467 peep2_do_cleanup_cfg |= purge_dead_edges (bb); | 3505 peep2_do_cleanup_cfg |= purge_dead_edges (bb); |
3468 } | 3506 } |
3469 | 3507 |
3470 /* Re-insert the ARGS_SIZE notes. */ | 3508 /* Re-insert the ARGS_SIZE notes. */ |
3471 if (as_note) | 3509 if (as_note) |
3472 fixup_args_size_notes (before_try, last, INTVAL (XEXP (as_note, 0))); | 3510 fixup_args_size_notes (before_try, last, get_args_size (as_note)); |
3473 | 3511 |
3474 /* If we generated a jump instruction, it won't have | 3512 /* If we generated a jump instruction, it won't have |
3475 JUMP_LABEL set. Recompute after we're done. */ | 3513 JUMP_LABEL set. Recompute after we're done. */ |
3476 for (x = last; x != before_try; x = PREV_INSN (x)) | 3514 for (x = last; x != before_try; x = PREV_INSN (x)) |
3477 if (JUMP_P (x)) | 3515 if (JUMP_P (x)) |
3655 cleanup_cfg (CLEANUP_CFG_CHANGED); | 3693 cleanup_cfg (CLEANUP_CFG_CHANGED); |
3656 } | 3694 } |
3657 | 3695 |
3658 /* Common predicates for use with define_bypass. */ | 3696 /* Common predicates for use with define_bypass. */ |
3659 | 3697 |
3698 /* Helper function for store_data_bypass_p, handle just a single SET | |
3699 IN_SET. */ | |
3700 | |
3701 static bool | |
3702 store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set) | |
3703 { | |
3704 if (!MEM_P (SET_DEST (in_set))) | |
3705 return false; | |
3706 | |
3707 rtx out_set = single_set (out_insn); | |
3708 if (out_set) | |
3709 return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set)); | |
3710 | |
3711 rtx out_pat = PATTERN (out_insn); | |
3712 if (GET_CODE (out_pat) != PARALLEL) | |
3713 return false; | |
3714 | |
3715 for (int i = 0; i < XVECLEN (out_pat, 0); i++) | |
3716 { | |
3717 rtx out_exp = XVECEXP (out_pat, 0, i); | |
3718 | |
3719 if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE | |
3720 || GET_CODE (out_exp) == CLOBBER_HIGH) | |
3721 continue; | |
3722 | |
3723 gcc_assert (GET_CODE (out_exp) == SET); | |
3724 | |
3725 if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set))) | |
3726 return false; | |
3727 } | |
3728 | |
3729 return true; | |
3730 } | |
3731 | |
3660 /* True if the dependency between OUT_INSN and IN_INSN is on the store | 3732 /* True if the dependency between OUT_INSN and IN_INSN is on the store |
3661 data not the address operand(s) of the store. IN_INSN and OUT_INSN | 3733 data not the address operand(s) of the store. IN_INSN and OUT_INSN |
3662 must be either a single_set or a PARALLEL with SETs inside. */ | 3734 must be either a single_set or a PARALLEL with SETs inside. */ |
3663 | 3735 |
3664 int | 3736 int |
3665 store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn) | 3737 store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn) |
3666 { | 3738 { |
3667 rtx out_set, in_set; | 3739 rtx in_set = single_set (in_insn); |
3668 rtx out_pat, in_pat; | |
3669 rtx out_exp, in_exp; | |
3670 int i, j; | |
3671 | |
3672 in_set = single_set (in_insn); | |
3673 if (in_set) | 3740 if (in_set) |
3674 { | 3741 return store_data_bypass_p_1 (out_insn, in_set); |
3675 if (!MEM_P (SET_DEST (in_set))) | 3742 |
3743 rtx in_pat = PATTERN (in_insn); | |
3744 if (GET_CODE (in_pat) != PARALLEL) | |
3745 return false; | |
3746 | |
3747 for (int i = 0; i < XVECLEN (in_pat, 0); i++) | |
3748 { | |
3749 rtx in_exp = XVECEXP (in_pat, 0, i); | |
3750 | |
3751 if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE | |
3752 || GET_CODE (in_exp) == CLOBBER_HIGH) | |
3753 continue; | |
3754 | |
3755 gcc_assert (GET_CODE (in_exp) == SET); | |
3756 | |
3757 if (!store_data_bypass_p_1 (out_insn, in_exp)) | |
3676 return false; | 3758 return false; |
3677 | |
3678 out_set = single_set (out_insn); | |
3679 if (out_set) | |
3680 { | |
3681 if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set))) | |
3682 return false; | |
3683 } | |
3684 else | |
3685 { | |
3686 out_pat = PATTERN (out_insn); | |
3687 | |
3688 if (GET_CODE (out_pat) != PARALLEL) | |
3689 return false; | |
3690 | |
3691 for (i = 0; i < XVECLEN (out_pat, 0); i++) | |
3692 { | |
3693 out_exp = XVECEXP (out_pat, 0, i); | |
3694 | |
3695 if (GET_CODE (out_exp) == CLOBBER) | |
3696 continue; | |
3697 | |
3698 gcc_assert (GET_CODE (out_exp) == SET); | |
3699 | |
3700 if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set))) | |
3701 return false; | |
3702 } | |
3703 } | |
3704 } | |
3705 else | |
3706 { | |
3707 in_pat = PATTERN (in_insn); | |
3708 gcc_assert (GET_CODE (in_pat) == PARALLEL); | |
3709 | |
3710 for (i = 0; i < XVECLEN (in_pat, 0); i++) | |
3711 { | |
3712 in_exp = XVECEXP (in_pat, 0, i); | |
3713 | |
3714 if (GET_CODE (in_exp) == CLOBBER) | |
3715 continue; | |
3716 | |
3717 gcc_assert (GET_CODE (in_exp) == SET); | |
3718 | |
3719 if (!MEM_P (SET_DEST (in_exp))) | |
3720 return false; | |
3721 | |
3722 out_set = single_set (out_insn); | |
3723 if (out_set) | |
3724 { | |
3725 if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_exp))) | |
3726 return false; | |
3727 } | |
3728 else | |
3729 { | |
3730 out_pat = PATTERN (out_insn); | |
3731 gcc_assert (GET_CODE (out_pat) == PARALLEL); | |
3732 | |
3733 for (j = 0; j < XVECLEN (out_pat, 0); j++) | |
3734 { | |
3735 out_exp = XVECEXP (out_pat, 0, j); | |
3736 | |
3737 if (GET_CODE (out_exp) == CLOBBER) | |
3738 continue; | |
3739 | |
3740 gcc_assert (GET_CODE (out_exp) == SET); | |
3741 | |
3742 if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_exp))) | |
3743 return false; | |
3744 } | |
3745 } | |
3746 } | |
3747 } | 3759 } |
3748 | 3760 |
3749 return true; | 3761 return true; |
3750 } | 3762 } |
3751 | 3763 |
3787 | 3799 |
3788 for (i = 0; i < XVECLEN (out_pat, 0); i++) | 3800 for (i = 0; i < XVECLEN (out_pat, 0); i++) |
3789 { | 3801 { |
3790 rtx exp = XVECEXP (out_pat, 0, i); | 3802 rtx exp = XVECEXP (out_pat, 0, i); |
3791 | 3803 |
3792 if (GET_CODE (exp) == CLOBBER) | 3804 if (GET_CODE (exp) == CLOBBER || GET_CODE (exp) == CLOBBER_HIGH) |
3793 continue; | 3805 continue; |
3794 | 3806 |
3795 gcc_assert (GET_CODE (exp) == SET); | 3807 gcc_assert (GET_CODE (exp) == SET); |
3796 | 3808 |
3797 if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1)) | 3809 if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1)) |