Mercurial > hg > CbC > CbC_gcc
comparison gcc/var-tracking.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Variable tracking routines for the GNU compiler. | 1 /* Variable tracking routines for the GNU compiler. |
2 Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 | 2 Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it | 7 GCC is free software; you can redistribute it and/or modify it |
90 #include "system.h" | 90 #include "system.h" |
91 #include "coretypes.h" | 91 #include "coretypes.h" |
92 #include "tm.h" | 92 #include "tm.h" |
93 #include "rtl.h" | 93 #include "rtl.h" |
94 #include "tree.h" | 94 #include "tree.h" |
95 #include "tm_p.h" | |
95 #include "hard-reg-set.h" | 96 #include "hard-reg-set.h" |
96 #include "basic-block.h" | 97 #include "basic-block.h" |
97 #include "flags.h" | 98 #include "flags.h" |
98 #include "output.h" | 99 #include "output.h" |
99 #include "insn-config.h" | 100 #include "insn-config.h" |
107 #include "timevar.h" | 108 #include "timevar.h" |
108 #include "tree-pass.h" | 109 #include "tree-pass.h" |
109 #include "tree-flow.h" | 110 #include "tree-flow.h" |
110 #include "cselib.h" | 111 #include "cselib.h" |
111 #include "target.h" | 112 #include "target.h" |
112 #include "toplev.h" | |
113 #include "params.h" | 113 #include "params.h" |
114 #include "diagnostic.h" | 114 #include "diagnostic.h" |
115 #include "tree-pretty-print.h" | 115 #include "tree-pretty-print.h" |
116 #include "pointer-set.h" | 116 #include "pointer-set.h" |
117 #include "recog.h" | 117 #include "recog.h" |
406 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *, | 406 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *, |
407 HOST_WIDE_INT *); | 407 HOST_WIDE_INT *); |
408 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *, | 408 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *, |
409 HOST_WIDE_INT *); | 409 HOST_WIDE_INT *); |
410 static bool vt_stack_adjustments (void); | 410 static bool vt_stack_adjustments (void); |
411 static rtx compute_cfa_pointer (HOST_WIDE_INT); | |
412 static hashval_t variable_htab_hash (const void *); | 411 static hashval_t variable_htab_hash (const void *); |
413 static int variable_htab_eq (const void *, const void *); | 412 static int variable_htab_eq (const void *, const void *); |
414 static void variable_htab_free (void *); | 413 static void variable_htab_free (void *); |
415 | 414 |
416 static void init_attrs_list_set (attrs *); | 415 static void init_attrs_list_set (attrs *); |
693 | 692 |
694 free (stack); | 693 free (stack); |
695 return true; | 694 return true; |
696 } | 695 } |
697 | 696 |
697 /* arg_pointer_rtx resp. frame_pointer_rtx if stack_pointer_rtx or | |
698 hard_frame_pointer_rtx is being mapped to it and offset for it. */ | |
699 static rtx cfa_base_rtx; | |
700 static HOST_WIDE_INT cfa_base_offset; | |
701 | |
698 /* Compute a CFA-based value for the stack pointer. */ | 702 /* Compute a CFA-based value for the stack pointer. */ |
699 | 703 |
700 static rtx | 704 static inline rtx |
701 compute_cfa_pointer (HOST_WIDE_INT adjustment) | 705 compute_cfa_pointer (HOST_WIDE_INT adjustment) |
702 { | 706 { |
703 rtx cfa; | 707 return plus_constant (cfa_base_rtx, adjustment + cfa_base_offset); |
704 | |
705 #ifdef FRAME_POINTER_CFA_OFFSET | |
706 adjustment -= FRAME_POINTER_CFA_OFFSET (current_function_decl); | |
707 cfa = plus_constant (frame_pointer_rtx, adjustment); | |
708 #else | |
709 adjustment -= ARG_POINTER_CFA_OFFSET (current_function_decl); | |
710 cfa = plus_constant (arg_pointer_rtx, adjustment); | |
711 #endif | |
712 | |
713 return cfa; | |
714 } | 708 } |
715 | 709 |
716 /* Adjustment for hard_frame_pointer_rtx to cfa base reg, | 710 /* Adjustment for hard_frame_pointer_rtx to cfa base reg, |
717 or -1 if the replacement shouldn't be done. */ | 711 or -1 if the replacement shouldn't be done. */ |
718 static HOST_WIDE_INT hard_frame_pointer_adjustment = -1; | 712 static HOST_WIDE_INT hard_frame_pointer_adjustment = -1; |
741 if (CONSTANT_P (*loc)) | 735 if (CONSTANT_P (*loc)) |
742 return -1; | 736 return -1; |
743 switch (GET_CODE (*loc)) | 737 switch (GET_CODE (*loc)) |
744 { | 738 { |
745 case REG: | 739 case REG: |
746 if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0)) | 740 if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0, VOIDmode)) |
747 return 1; | 741 return 1; |
748 return -1; | 742 return -1; |
749 case PLUS: | 743 case PLUS: |
750 case MINUS: | 744 case MINUS: |
751 case MULT: | 745 case MULT: |
796 enum machine_mode mem_mode_save; | 790 enum machine_mode mem_mode_save; |
797 bool store_save; | 791 bool store_save; |
798 switch (GET_CODE (loc)) | 792 switch (GET_CODE (loc)) |
799 { | 793 { |
800 case REG: | 794 case REG: |
801 /* Don't do any sp or fp replacements outside of MEM addresses. */ | 795 /* Don't do any sp or fp replacements outside of MEM addresses |
802 if (amd->mem_mode == VOIDmode) | 796 on the LHS. */ |
797 if (amd->mem_mode == VOIDmode && amd->store) | |
803 return loc; | 798 return loc; |
804 if (loc == stack_pointer_rtx | 799 if (loc == stack_pointer_rtx |
805 && !frame_pointer_needed) | 800 && !frame_pointer_needed |
801 && cfa_base_rtx) | |
806 return compute_cfa_pointer (amd->stack_adjust); | 802 return compute_cfa_pointer (amd->stack_adjust); |
807 else if (loc == hard_frame_pointer_rtx | 803 else if (loc == hard_frame_pointer_rtx |
808 && frame_pointer_needed | 804 && frame_pointer_needed |
809 && hard_frame_pointer_adjustment != -1) | 805 && hard_frame_pointer_adjustment != -1 |
806 && cfa_base_rtx) | |
810 return compute_cfa_pointer (hard_frame_pointer_adjustment); | 807 return compute_cfa_pointer (hard_frame_pointer_adjustment); |
808 gcc_checking_assert (loc != virtual_incoming_args_rtx); | |
811 return loc; | 809 return loc; |
812 case MEM: | 810 case MEM: |
813 mem = loc; | 811 mem = loc; |
814 if (!amd->store) | 812 if (!amd->store) |
815 { | 813 { |
907 && subreg_lowpart_p (tem) | 905 && subreg_lowpart_p (tem) |
908 && !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_test, tem)) | 906 && !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_test, tem)) |
909 return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem), | 907 return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem), |
910 GET_MODE (SUBREG_REG (tem))); | 908 GET_MODE (SUBREG_REG (tem))); |
911 return tem; | 909 return tem; |
910 case ASM_OPERANDS: | |
911 /* Don't do any replacements in second and following | |
912 ASM_OPERANDS of inline-asm with multiple sets. | |
913 ASM_OPERANDS_INPUT_VEC, ASM_OPERANDS_INPUT_CONSTRAINT_VEC | |
914 and ASM_OPERANDS_LABEL_VEC need to be equal between | |
915 all the ASM_OPERANDs in the insn and adjust_insn will | |
916 fix this up. */ | |
917 if (ASM_OPERANDS_OUTPUT_IDX (loc) != 0) | |
918 return loc; | |
919 break; | |
912 default: | 920 default: |
913 break; | 921 break; |
914 } | 922 } |
915 return NULL_RTX; | 923 return NULL_RTX; |
916 } | 924 } |
957 | 965 |
958 amd.store = true; | 966 amd.store = true; |
959 note_stores (PATTERN (insn), adjust_mem_stores, &amd); | 967 note_stores (PATTERN (insn), adjust_mem_stores, &amd); |
960 | 968 |
961 amd.store = false; | 969 amd.store = false; |
962 note_uses (&PATTERN (insn), adjust_mem_uses, &amd); | 970 if (GET_CODE (PATTERN (insn)) == PARALLEL |
971 && asm_noperands (PATTERN (insn)) > 0 | |
972 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET) | |
973 { | |
974 rtx body, set0; | |
975 int i; | |
976 | |
977 /* inline-asm with multiple sets is tiny bit more complicated, | |
978 because the 3 vectors in ASM_OPERANDS need to be shared between | |
979 all ASM_OPERANDS in the instruction. adjust_mems will | |
980 not touch ASM_OPERANDS other than the first one, asm_noperands | |
981 test above needs to be called before that (otherwise it would fail) | |
982 and afterwards this code fixes it up. */ | |
983 note_uses (&PATTERN (insn), adjust_mem_uses, &amd); | |
984 body = PATTERN (insn); | |
985 set0 = XVECEXP (body, 0, 0); | |
986 gcc_checking_assert (GET_CODE (set0) == SET | |
987 && GET_CODE (SET_SRC (set0)) == ASM_OPERANDS | |
988 && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set0)) == 0); | |
989 for (i = 1; i < XVECLEN (body, 0); i++) | |
990 if (GET_CODE (XVECEXP (body, 0, i)) != SET) | |
991 break; | |
992 else | |
993 { | |
994 set = XVECEXP (body, 0, i); | |
995 gcc_checking_assert (GET_CODE (SET_SRC (set)) == ASM_OPERANDS | |
996 && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set)) | |
997 == i); | |
998 if (ASM_OPERANDS_INPUT_VEC (SET_SRC (set)) | |
999 != ASM_OPERANDS_INPUT_VEC (SET_SRC (set0)) | |
1000 || ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set)) | |
1001 != ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0)) | |
1002 || ASM_OPERANDS_LABEL_VEC (SET_SRC (set)) | |
1003 != ASM_OPERANDS_LABEL_VEC (SET_SRC (set0))) | |
1004 { | |
1005 rtx newsrc = shallow_copy_rtx (SET_SRC (set)); | |
1006 ASM_OPERANDS_INPUT_VEC (newsrc) | |
1007 = ASM_OPERANDS_INPUT_VEC (SET_SRC (set0)); | |
1008 ASM_OPERANDS_INPUT_CONSTRAINT_VEC (newsrc) | |
1009 = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0)); | |
1010 ASM_OPERANDS_LABEL_VEC (newsrc) | |
1011 = ASM_OPERANDS_LABEL_VEC (SET_SRC (set0)); | |
1012 validate_change (NULL_RTX, &SET_SRC (set), newsrc, true); | |
1013 } | |
1014 } | |
1015 } | |
1016 else | |
1017 note_uses (&PATTERN (insn), adjust_mem_uses, &amd); | |
963 | 1018 |
964 /* For read-only MEMs containing some constant, prefer those | 1019 /* For read-only MEMs containing some constant, prefer those |
965 constants. */ | 1020 constants. */ |
966 set = single_set (insn); | 1021 set = single_set (insn); |
967 if (set && MEM_P (SET_SRC (set)) && MEM_READONLY_P (SET_SRC (set))) | 1022 if (set && MEM_P (SET_SRC (set)) && MEM_READONLY_P (SET_SRC (set))) |
1015 | 1070 |
1016 /* Return the decl in the decl_or_value. */ | 1071 /* Return the decl in the decl_or_value. */ |
1017 static inline tree | 1072 static inline tree |
1018 dv_as_decl (decl_or_value dv) | 1073 dv_as_decl (decl_or_value dv) |
1019 { | 1074 { |
1020 #ifdef ENABLE_CHECKING | 1075 gcc_checking_assert (dv_is_decl_p (dv)); |
1021 gcc_assert (dv_is_decl_p (dv)); | |
1022 #endif | |
1023 return (tree) dv; | 1076 return (tree) dv; |
1024 } | 1077 } |
1025 | 1078 |
1026 /* Return the value in the decl_or_value. */ | 1079 /* Return the value in the decl_or_value. */ |
1027 static inline rtx | 1080 static inline rtx |
1028 dv_as_value (decl_or_value dv) | 1081 dv_as_value (decl_or_value dv) |
1029 { | 1082 { |
1030 #ifdef ENABLE_CHECKING | 1083 gcc_checking_assert (dv_is_value_p (dv)); |
1031 gcc_assert (dv_is_value_p (dv)); | |
1032 #endif | |
1033 return (rtx)dv; | 1084 return (rtx)dv; |
1034 } | 1085 } |
1035 | 1086 |
1036 /* Return the opaque pointer in the decl_or_value. */ | 1087 /* Return the opaque pointer in the decl_or_value. */ |
1037 static inline void * | 1088 static inline void * |
1076 static inline decl_or_value | 1127 static inline decl_or_value |
1077 dv_from_decl (tree decl) | 1128 dv_from_decl (tree decl) |
1078 { | 1129 { |
1079 decl_or_value dv; | 1130 decl_or_value dv; |
1080 dv = decl; | 1131 dv = decl; |
1081 #ifdef ENABLE_CHECKING | 1132 gcc_checking_assert (dv_is_decl_p (dv)); |
1082 gcc_assert (dv_is_decl_p (dv)); | |
1083 #endif | |
1084 return dv; | 1133 return dv; |
1085 } | 1134 } |
1086 | 1135 |
1087 /* Build a decl_or_value out of a value. */ | 1136 /* Build a decl_or_value out of a value. */ |
1088 static inline decl_or_value | 1137 static inline decl_or_value |
1089 dv_from_value (rtx value) | 1138 dv_from_value (rtx value) |
1090 { | 1139 { |
1091 decl_or_value dv; | 1140 decl_or_value dv; |
1092 dv = value; | 1141 dv = value; |
1093 #ifdef ENABLE_CHECKING | 1142 gcc_checking_assert (dv_is_value_p (dv)); |
1094 gcc_assert (dv_is_value_p (dv)); | |
1095 #endif | |
1096 return dv; | 1143 return dv; |
1097 } | 1144 } |
1098 | 1145 |
1099 extern void debug_dv (decl_or_value dv); | 1146 extern void debug_dv (decl_or_value dv); |
1100 | 1147 |
1101 void | 1148 DEBUG_FUNCTION void |
1102 debug_dv (decl_or_value dv) | 1149 debug_dv (decl_or_value dv) |
1103 { | 1150 { |
1104 if (dv_is_value_p (dv)) | 1151 if (dv_is_value_p (dv)) |
1105 debug_rtx (dv_as_value (dv)); | 1152 debug_rtx (dv_as_value (dv)); |
1106 else | 1153 else |
1165 { | 1212 { |
1166 int i; | 1213 int i; |
1167 variable var = (variable) elem; | 1214 variable var = (variable) elem; |
1168 location_chain node, next; | 1215 location_chain node, next; |
1169 | 1216 |
1170 gcc_assert (var->refcount > 0); | 1217 gcc_checking_assert (var->refcount > 0); |
1171 | 1218 |
1172 var->refcount--; | 1219 var->refcount--; |
1173 if (var->refcount > 0) | 1220 if (var->refcount > 0) |
1174 return; | 1221 return; |
1175 | 1222 |
1368 anymore. */ | 1415 anymore. */ |
1369 | 1416 |
1370 static void | 1417 static void |
1371 shared_hash_destroy (shared_hash vars) | 1418 shared_hash_destroy (shared_hash vars) |
1372 { | 1419 { |
1373 gcc_assert (vars->refcount > 0); | 1420 gcc_checking_assert (vars->refcount > 0); |
1374 if (--vars->refcount == 0) | 1421 if (--vars->refcount == 0) |
1375 { | 1422 { |
1376 htab_delete (vars->htab); | 1423 htab_delete (vars->htab); |
1377 pool_free (shared_hash_pool, vars); | 1424 pool_free (shared_hash_pool, vars); |
1378 } | 1425 } |
2122 else | 2169 else |
2123 nnode->set_src = snode->set_src; | 2170 nnode->set_src = snode->set_src; |
2124 nnode->next = dnode; | 2171 nnode->next = dnode; |
2125 dnode = nnode; | 2172 dnode = nnode; |
2126 } | 2173 } |
2127 #ifdef ENABLE_CHECKING | |
2128 else if (r == 0) | 2174 else if (r == 0) |
2129 gcc_assert (rtx_equal_p (dnode->loc, snode->loc)); | 2175 gcc_checking_assert (rtx_equal_p (dnode->loc, snode->loc)); |
2130 #endif | |
2131 | 2176 |
2132 if (r >= 0) | 2177 if (r >= 0) |
2133 snode = snode->next; | 2178 snode = snode->next; |
2134 | 2179 |
2135 nodep = &dnode->next; | 2180 nodep = &dnode->next; |
2477 : DECL_CHANGED (dv_as_decl (dv))); | 2522 : DECL_CHANGED (dv_as_decl (dv))); |
2478 } | 2523 } |
2479 | 2524 |
2480 /* Return a location list node whose loc is rtx_equal to LOC, in the | 2525 /* Return a location list node whose loc is rtx_equal to LOC, in the |
2481 location list of a one-part variable or value VAR, or in that of | 2526 location list of a one-part variable or value VAR, or in that of |
2482 any values recursively mentioned in the location lists. */ | 2527 any values recursively mentioned in the location lists. VARS must |
2528 be in star-canonical form. */ | |
2483 | 2529 |
2484 static location_chain | 2530 static location_chain |
2485 find_loc_in_1pdv (rtx loc, variable var, htab_t vars) | 2531 find_loc_in_1pdv (rtx loc, variable var, htab_t vars) |
2486 { | 2532 { |
2487 location_chain node; | 2533 location_chain node; |
2488 enum rtx_code loc_code; | 2534 enum rtx_code loc_code; |
2489 | 2535 |
2490 if (!var) | 2536 if (!var) |
2491 return NULL; | 2537 return NULL; |
2492 | 2538 |
2493 gcc_assert (dv_onepart_p (var->dv)); | 2539 gcc_checking_assert (dv_onepart_p (var->dv)); |
2494 | 2540 |
2495 if (!var->n_var_parts) | 2541 if (!var->n_var_parts) |
2496 return NULL; | 2542 return NULL; |
2497 | 2543 |
2498 gcc_assert (var->var_part[0].offset == 0); | 2544 gcc_checking_assert (var->var_part[0].offset == 0); |
2545 gcc_checking_assert (loc != dv_as_opaque (var->dv)); | |
2499 | 2546 |
2500 loc_code = GET_CODE (loc); | 2547 loc_code = GET_CODE (loc); |
2501 for (node = var->var_part[0].loc_chain; node; node = node->next) | 2548 for (node = var->var_part[0].loc_chain; node; node = node->next) |
2502 { | 2549 { |
2550 decl_or_value dv; | |
2551 variable rvar; | |
2552 | |
2503 if (GET_CODE (node->loc) != loc_code) | 2553 if (GET_CODE (node->loc) != loc_code) |
2504 { | 2554 { |
2505 if (GET_CODE (node->loc) != VALUE) | 2555 if (GET_CODE (node->loc) != VALUE) |
2506 continue; | 2556 continue; |
2507 } | 2557 } |
2511 { | 2561 { |
2512 if (rtx_equal_p (loc, node->loc)) | 2562 if (rtx_equal_p (loc, node->loc)) |
2513 return node; | 2563 return node; |
2514 continue; | 2564 continue; |
2515 } | 2565 } |
2516 if (!VALUE_RECURSED_INTO (node->loc)) | 2566 |
2517 { | 2567 /* Since we're in star-canonical form, we don't need to visit |
2518 decl_or_value dv = dv_from_value (node->loc); | 2568 non-canonical nodes: one-part variables and non-canonical |
2519 variable var = (variable) | 2569 values would only point back to the canonical node. */ |
2520 htab_find_with_hash (vars, dv, dv_htab_hash (dv)); | 2570 if (dv_is_value_p (var->dv) |
2521 | 2571 && !canon_value_cmp (node->loc, dv_as_value (var->dv))) |
2522 if (var) | 2572 { |
2573 /* Skip all subsequent VALUEs. */ | |
2574 while (node->next && GET_CODE (node->next->loc) == VALUE) | |
2523 { | 2575 { |
2524 location_chain where; | 2576 node = node->next; |
2525 VALUE_RECURSED_INTO (node->loc) = true; | 2577 gcc_checking_assert (!canon_value_cmp (node->loc, |
2526 if ((where = find_loc_in_1pdv (loc, var, vars))) | 2578 dv_as_value (var->dv))); |
2527 { | 2579 if (loc == node->loc) |
2528 VALUE_RECURSED_INTO (node->loc) = false; | 2580 return node; |
2529 return where; | |
2530 } | |
2531 VALUE_RECURSED_INTO (node->loc) = false; | |
2532 } | 2581 } |
2533 } | 2582 continue; |
2583 } | |
2584 | |
2585 gcc_checking_assert (node == var->var_part[0].loc_chain); | |
2586 gcc_checking_assert (!node->next); | |
2587 | |
2588 dv = dv_from_value (node->loc); | |
2589 rvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv)); | |
2590 return find_loc_in_1pdv (loc, rvar, vars); | |
2534 } | 2591 } |
2535 | 2592 |
2536 return NULL; | 2593 return NULL; |
2537 } | 2594 } |
2538 | 2595 |
2587 location_chain s1node, variable s2var) | 2644 location_chain s1node, variable s2var) |
2588 { | 2645 { |
2589 dataflow_set *s1set = dsm->cur; | 2646 dataflow_set *s1set = dsm->cur; |
2590 dataflow_set *s2set = dsm->src; | 2647 dataflow_set *s2set = dsm->src; |
2591 location_chain found; | 2648 location_chain found; |
2649 | |
2650 if (s2var) | |
2651 { | |
2652 location_chain s2node; | |
2653 | |
2654 gcc_checking_assert (dv_onepart_p (s2var->dv)); | |
2655 | |
2656 if (s2var->n_var_parts) | |
2657 { | |
2658 gcc_checking_assert (s2var->var_part[0].offset == 0); | |
2659 s2node = s2var->var_part[0].loc_chain; | |
2660 | |
2661 for (; s1node && s2node; | |
2662 s1node = s1node->next, s2node = s2node->next) | |
2663 if (s1node->loc != s2node->loc) | |
2664 break; | |
2665 else if (s1node->loc == val) | |
2666 continue; | |
2667 else | |
2668 insert_into_intersection (dest, s1node->loc, | |
2669 MIN (s1node->init, s2node->init)); | |
2670 } | |
2671 } | |
2592 | 2672 |
2593 for (; s1node; s1node = s1node->next) | 2673 for (; s1node; s1node = s1node->next) |
2594 { | 2674 { |
2595 if (s1node->loc == val) | 2675 if (s1node->loc == val) |
2596 continue; | 2676 continue; |
2722 if (GET_CODE (x) == DEBUG_EXPR) | 2802 if (GET_CODE (x) == DEBUG_EXPR) |
2723 { | 2803 { |
2724 if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)) | 2804 if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)) |
2725 < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y))) | 2805 < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y))) |
2726 return -1; | 2806 return -1; |
2727 #ifdef ENABLE_CHECKING | 2807 gcc_checking_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)) |
2728 gcc_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)) | 2808 > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y))); |
2729 > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y))); | |
2730 #endif | |
2731 return 1; | 2809 return 1; |
2732 } | 2810 } |
2733 | 2811 |
2734 fmt = GET_RTX_FORMAT (code); | 2812 fmt = GET_RTX_FORMAT (code); |
2735 for (i = 0; i < GET_RTX_LENGTH (code); i++) | 2813 for (i = 0; i < GET_RTX_LENGTH (code); i++) |
3017 location_chain node; | 3095 location_chain node; |
3018 | 3096 |
3019 if (!dv_is_value_p (dv)) | 3097 if (!dv_is_value_p (dv)) |
3020 return 1; | 3098 return 1; |
3021 | 3099 |
3022 gcc_assert (var->n_var_parts == 1); | 3100 gcc_checking_assert (var->n_var_parts == 1); |
3023 | 3101 |
3024 val = dv_as_value (dv); | 3102 val = dv_as_value (dv); |
3025 | 3103 |
3026 for (node = var->var_part[0].loc_chain; node; node = node->next) | 3104 for (node = var->var_part[0].loc_chain; node; node = node->next) |
3027 if (GET_CODE (node->loc) == VALUE) | 3105 if (GET_CODE (node->loc) == VALUE) |
3060 bool has_marks; | 3138 bool has_marks; |
3061 | 3139 |
3062 if (!dv_onepart_p (dv)) | 3140 if (!dv_onepart_p (dv)) |
3063 return 1; | 3141 return 1; |
3064 | 3142 |
3065 gcc_assert (var->n_var_parts == 1); | 3143 gcc_checking_assert (var->n_var_parts == 1); |
3066 | 3144 |
3067 if (dv_is_value_p (dv)) | 3145 if (dv_is_value_p (dv)) |
3068 { | 3146 { |
3069 cval = dv_as_value (dv); | 3147 cval = dv_as_value (dv); |
3070 if (!VALUE_RECURSED_INTO (cval)) | 3148 if (!VALUE_RECURSED_INTO (cval)) |
3250 | 3328 |
3251 slot = clobber_slot_part (set, cval, slot, 0, NULL); | 3329 slot = clobber_slot_part (set, cval, slot, 0, NULL); |
3252 | 3330 |
3253 /* Variable may have been unshared. */ | 3331 /* Variable may have been unshared. */ |
3254 var = (variable)*slot; | 3332 var = (variable)*slot; |
3255 gcc_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval | 3333 gcc_checking_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval |
3256 && var->var_part[0].loc_chain->next == NULL); | 3334 && var->var_part[0].loc_chain->next == NULL); |
3257 | 3335 |
3258 if (VALUE_RECURSED_INTO (cval)) | 3336 if (VALUE_RECURSED_INTO (cval)) |
3259 goto restart_with_cval; | 3337 goto restart_with_cval; |
3260 | 3338 |
3261 return 1; | 3339 return 1; |
3340 location_chain node, *nodep; | 3418 location_chain node, *nodep; |
3341 | 3419 |
3342 /* If the incoming onepart variable has an empty location list, then | 3420 /* If the incoming onepart variable has an empty location list, then |
3343 the intersection will be just as empty. For other variables, | 3421 the intersection will be just as empty. For other variables, |
3344 it's always union. */ | 3422 it's always union. */ |
3345 gcc_assert (s1var->n_var_parts | 3423 gcc_checking_assert (s1var->n_var_parts |
3346 && s1var->var_part[0].loc_chain); | 3424 && s1var->var_part[0].loc_chain); |
3347 | 3425 |
3348 if (!onepart) | 3426 if (!onepart) |
3349 return variable_union (s1var, dst); | 3427 return variable_union (s1var, dst); |
3350 | 3428 |
3351 gcc_assert (s1var->n_var_parts == 1 | 3429 gcc_checking_assert (s1var->n_var_parts == 1 |
3352 && s1var->var_part[0].offset == 0); | 3430 && s1var->var_part[0].offset == 0); |
3353 | 3431 |
3354 dvhash = dv_htab_hash (dv); | 3432 dvhash = dv_htab_hash (dv); |
3355 if (dv_is_value_p (dv)) | 3433 if (dv_is_value_p (dv)) |
3356 val = dv_as_value (dv); | 3434 val = dv_as_value (dv); |
3357 else | 3435 else |
3485 } | 3563 } |
3486 | 3564 |
3487 dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash); | 3565 dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash); |
3488 gcc_assert (*dstslot == dvar); | 3566 gcc_assert (*dstslot == dvar); |
3489 canonicalize_values_star (dstslot, dst); | 3567 canonicalize_values_star (dstslot, dst); |
3490 #ifdef ENABLE_CHECKING | 3568 gcc_checking_assert (dstslot |
3491 gcc_assert (dstslot | 3569 == shared_hash_find_slot_noinsert_1 (dst->vars, |
3492 == shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash)); | 3570 dv, dvhash)); |
3493 #endif | |
3494 dvar = (variable)*dstslot; | 3571 dvar = (variable)*dstslot; |
3495 } | 3572 } |
3496 else | 3573 else |
3497 { | 3574 { |
3498 bool has_value = false, has_other = false; | 3575 bool has_value = false, has_other = false; |
3553 } | 3630 } |
3554 | 3631 |
3555 dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash); | 3632 dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash); |
3556 gcc_assert (*dstslot == dvar); | 3633 gcc_assert (*dstslot == dvar); |
3557 canonicalize_values_star (dstslot, dst); | 3634 canonicalize_values_star (dstslot, dst); |
3558 #ifdef ENABLE_CHECKING | 3635 gcc_checking_assert (dstslot |
3559 gcc_assert (dstslot | 3636 == shared_hash_find_slot_noinsert_1 (dst->vars, |
3560 == shared_hash_find_slot_noinsert_1 (dst->vars, | 3637 dv, dvhash)); |
3561 dv, dvhash)); | |
3562 #endif | |
3563 dvar = (variable)*dstslot; | 3638 dvar = (variable)*dstslot; |
3564 } | 3639 } |
3565 } | 3640 } |
3566 | 3641 |
3567 if (!onepart_variable_different_p (dvar, s2var)) | 3642 if (!onepart_variable_different_p (dvar, s2var)) |
3660 attrs list, *listp; | 3735 attrs list, *listp; |
3661 | 3736 |
3662 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | 3737 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
3663 { | 3738 { |
3664 rtx canon[NUM_MACHINE_MODES]; | 3739 rtx canon[NUM_MACHINE_MODES]; |
3740 | |
3741 /* If the list is empty or one entry, no need to canonicalize | |
3742 anything. */ | |
3743 if (set->regs[i] == NULL || set->regs[i]->next == NULL) | |
3744 continue; | |
3665 | 3745 |
3666 memset (canon, 0, sizeof (canon)); | 3746 memset (canon, 0, sizeof (canon)); |
3667 | 3747 |
3668 for (list = set->regs[i]; list; list = list->next) | 3748 for (list = set->regs[i]; list; list = list->next) |
3669 if (list->offset == 0 && dv_is_value_p (list->dv)) | 3749 if (list->offset == 0 && dv_is_value_p (list->dv)) |
3872 /* Create a unique value to hold this register, | 3952 /* Create a unique value to hold this register, |
3873 that ought to be found and reused in | 3953 that ought to be found and reused in |
3874 subsequent rounds. */ | 3954 subsequent rounds. */ |
3875 cselib_val *v; | 3955 cselib_val *v; |
3876 gcc_assert (!cselib_lookup (node->loc, | 3956 gcc_assert (!cselib_lookup (node->loc, |
3877 GET_MODE (node->loc), 0)); | 3957 GET_MODE (node->loc), 0, |
3878 v = cselib_lookup (node->loc, GET_MODE (node->loc), 1); | 3958 VOIDmode)); |
3959 v = cselib_lookup (node->loc, GET_MODE (node->loc), 1, | |
3960 VOIDmode); | |
3879 cselib_preserve_value (v); | 3961 cselib_preserve_value (v); |
3880 cselib_invalidate_rtx (node->loc); | 3962 cselib_invalidate_rtx (node->loc); |
3881 cval = v->val_rtx; | 3963 cval = v->val_rtx; |
3882 cdv = dv_from_value (cval); | 3964 cdv = dv_from_value (cval); |
3883 if (dump_file) | 3965 if (dump_file) |
3933 dv = pvar->dv; | 4015 dv = pvar->dv; |
3934 | 4016 |
3935 var = shared_hash_find (set->vars, dv); | 4017 var = shared_hash_find (set->vars, dv); |
3936 if (var) | 4018 if (var) |
3937 { | 4019 { |
4020 /* Although variable_post_merge_new_vals may have made decls | |
4021 non-star-canonical, values that pre-existed in canonical form | |
4022 remain canonical, and newly-created values reference a single | |
4023 REG, so they are canonical as well. Since VAR has the | |
4024 location list for a VALUE, using find_loc_in_1pdv for it is | |
4025 fine, since VALUEs don't map back to DECLs. */ | |
3938 if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars))) | 4026 if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars))) |
3939 return 1; | 4027 return 1; |
3940 val_reset (set, dv); | 4028 val_reset (set, dv); |
3941 } | 4029 } |
3942 | 4030 |
4666 regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc), | 4754 regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc), |
4667 reg_offset, mode); | 4755 reg_offset, mode); |
4668 return gen_rtx_REG_offset (loc, mode, regno, offset); | 4756 return gen_rtx_REG_offset (loc, mode, regno, offset); |
4669 } | 4757 } |
4670 | 4758 |
4671 /* arg_pointer_rtx resp. frame_pointer_rtx if stack_pointer_rtx or | |
4672 hard_frame_pointer_rtx is being mapped to it. */ | |
4673 static rtx cfa_base_rtx; | |
4674 | |
4675 /* Carry information about uses and stores while walking rtx. */ | 4759 /* Carry information about uses and stores while walking rtx. */ |
4676 | 4760 |
4677 struct count_use_info | 4761 struct count_use_info |
4678 { | 4762 { |
4679 /* The insn where the RTX is. */ | 4763 /* The insn where the RTX is. */ |
4698 int i; | 4782 int i; |
4699 | 4783 |
4700 if (cui->sets) | 4784 if (cui->sets) |
4701 { | 4785 { |
4702 /* This is called after uses are set up and before stores are | 4786 /* This is called after uses are set up and before stores are |
4703 processed bycselib, so it's safe to look up srcs, but not | 4787 processed by cselib, so it's safe to look up srcs, but not |
4704 dsts. So we look up expressions that appear in srcs or in | 4788 dsts. So we look up expressions that appear in srcs or in |
4705 dest expressions, but we search the sets array for dests of | 4789 dest expressions, but we search the sets array for dests of |
4706 stores. */ | 4790 stores. */ |
4707 if (cui->store_p) | 4791 if (cui->store_p) |
4708 { | 4792 { |
4793 /* Some targets represent memset and memcpy patterns | |
4794 by (set (mem:BLK ...) (reg:[QHSD]I ...)) or | |
4795 (set (mem:BLK ...) (const_int ...)) or | |
4796 (set (mem:BLK ...) (mem:BLK ...)). Don't return anything | |
4797 in that case, otherwise we end up with mode mismatches. */ | |
4798 if (mode == BLKmode && MEM_P (x)) | |
4799 return NULL; | |
4709 for (i = 0; i < cui->n_sets; i++) | 4800 for (i = 0; i < cui->n_sets; i++) |
4710 if (cui->sets[i].dest == x) | 4801 if (cui->sets[i].dest == x) |
4711 return cui->sets[i].src_elt; | 4802 return cui->sets[i].src_elt; |
4712 } | 4803 } |
4713 else | 4804 else |
4714 return cselib_lookup (x, mode, 0); | 4805 return cselib_lookup (x, mode, 0, VOIDmode); |
4715 } | 4806 } |
4716 | 4807 |
4717 return NULL; | 4808 return NULL; |
4718 } | 4809 } |
4719 | 4810 |
4738 if (REG_P (loc)) | 4829 if (REG_P (loc)) |
4739 return NULL; | 4830 return NULL; |
4740 else if (MEM_P (loc)) | 4831 else if (MEM_P (loc)) |
4741 { | 4832 { |
4742 cselib_val *addr = cselib_lookup (XEXP (loc, 0), | 4833 cselib_val *addr = cselib_lookup (XEXP (loc, 0), |
4743 get_address_mode (loc), 0); | 4834 get_address_mode (loc), 0, |
4835 GET_MODE (loc)); | |
4744 if (addr) | 4836 if (addr) |
4745 return replace_equiv_address_nv (loc, addr->val_rtx); | 4837 return replace_equiv_address_nv (loc, addr->val_rtx); |
4746 else | 4838 else |
4747 return NULL; | 4839 return NULL; |
4748 } | 4840 } |
4749 else | 4841 else |
4750 return cselib_subst_to_values (loc); | 4842 return cselib_subst_to_values (loc, VOIDmode); |
4751 } | 4843 } |
4752 | 4844 |
4753 /* Determine what kind of micro operation to choose for a USE. Return | 4845 /* Determine what kind of micro operation to choose for a USE. Return |
4754 MO_CLOBBER if no micro operation is to be generated. */ | 4846 MO_CLOBBER if no micro operation is to be generated. */ |
4755 | 4847 |
4765 if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false)) | 4857 if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false)) |
4766 { | 4858 { |
4767 rtx ploc = PAT_VAR_LOCATION_LOC (loc); | 4859 rtx ploc = PAT_VAR_LOCATION_LOC (loc); |
4768 if (! VAR_LOC_UNKNOWN_P (ploc)) | 4860 if (! VAR_LOC_UNKNOWN_P (ploc)) |
4769 { | 4861 { |
4770 cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1); | 4862 cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1, |
4863 VOIDmode); | |
4771 | 4864 |
4772 /* ??? flag_float_store and volatile mems are never | 4865 /* ??? flag_float_store and volatile mems are never |
4773 given values, but we could in theory use them for | 4866 given values, but we could in theory use them for |
4774 locations. */ | 4867 locations. */ |
4775 gcc_assert (val || 1); | 4868 gcc_assert (val || 1); |
4787 if (cui->store_p) | 4880 if (cui->store_p) |
4788 { | 4881 { |
4789 if (REG_P (loc) | 4882 if (REG_P (loc) |
4790 || (find_use_val (loc, GET_MODE (loc), cui) | 4883 || (find_use_val (loc, GET_MODE (loc), cui) |
4791 && cselib_lookup (XEXP (loc, 0), | 4884 && cselib_lookup (XEXP (loc, 0), |
4792 get_address_mode (loc), 0))) | 4885 get_address_mode (loc), 0, |
4886 GET_MODE (loc)))) | |
4793 return MO_VAL_SET; | 4887 return MO_VAL_SET; |
4794 } | 4888 } |
4795 else | 4889 else |
4796 { | 4890 { |
4797 cselib_val *val = find_use_val (loc, GET_MODE (loc), cui); | 4891 cselib_val *val = find_use_val (loc, GET_MODE (loc), cui); |
4949 || !CONST_INT_P (XEXP (XEXP (vloc, 0), 1)))) | 5043 || !CONST_INT_P (XEXP (XEXP (vloc, 0), 1)))) |
4950 { | 5044 { |
4951 rtx mloc = vloc; | 5045 rtx mloc = vloc; |
4952 enum machine_mode address_mode = get_address_mode (mloc); | 5046 enum machine_mode address_mode = get_address_mode (mloc); |
4953 cselib_val *val | 5047 cselib_val *val |
4954 = cselib_lookup (XEXP (mloc, 0), address_mode, 0); | 5048 = cselib_lookup (XEXP (mloc, 0), address_mode, 0, |
5049 GET_MODE (mloc)); | |
4955 | 5050 |
4956 if (val && !cselib_preserved_value_p (val)) | 5051 if (val && !cselib_preserved_value_p (val)) |
4957 { | 5052 { |
4958 micro_operation moa; | 5053 micro_operation moa; |
4959 preserve_value (val); | 5054 preserve_value (val); |
4960 mloc = cselib_subst_to_values (XEXP (mloc, 0)); | 5055 mloc = cselib_subst_to_values (XEXP (mloc, 0), |
5056 GET_MODE (mloc)); | |
4961 moa.type = MO_VAL_USE; | 5057 moa.type = MO_VAL_USE; |
4962 moa.insn = cui->insn; | 5058 moa.insn = cui->insn; |
4963 moa.u.loc = gen_rtx_CONCAT (address_mode, | 5059 moa.u.loc = gen_rtx_CONCAT (address_mode, |
4964 val->val_rtx, mloc); | 5060 val->val_rtx, mloc); |
4965 if (dump_file && (dump_flags & TDF_DETAILS)) | 5061 if (dump_file && (dump_flags & TDF_DETAILS)) |
5025 || !CONST_INT_P (XEXP (XEXP (oloc, 0), 1)))) | 5121 || !CONST_INT_P (XEXP (XEXP (oloc, 0), 1)))) |
5026 { | 5122 { |
5027 rtx mloc = oloc; | 5123 rtx mloc = oloc; |
5028 enum machine_mode address_mode = get_address_mode (mloc); | 5124 enum machine_mode address_mode = get_address_mode (mloc); |
5029 cselib_val *val | 5125 cselib_val *val |
5030 = cselib_lookup (XEXP (mloc, 0), address_mode, 0); | 5126 = cselib_lookup (XEXP (mloc, 0), address_mode, 0, |
5127 GET_MODE (mloc)); | |
5031 | 5128 |
5032 if (val && !cselib_preserved_value_p (val)) | 5129 if (val && !cselib_preserved_value_p (val)) |
5033 { | 5130 { |
5034 micro_operation moa; | 5131 micro_operation moa; |
5035 preserve_value (val); | 5132 preserve_value (val); |
5036 mloc = cselib_subst_to_values (XEXP (mloc, 0)); | 5133 mloc = cselib_subst_to_values (XEXP (mloc, 0), |
5134 GET_MODE (mloc)); | |
5037 moa.type = MO_VAL_USE; | 5135 moa.type = MO_VAL_USE; |
5038 moa.insn = cui->insn; | 5136 moa.insn = cui->insn; |
5039 moa.u.loc = gen_rtx_CONCAT (address_mode, | 5137 moa.u.loc = gen_rtx_CONCAT (address_mode, |
5040 val->val_rtx, mloc); | 5138 val->val_rtx, mloc); |
5041 if (dump_file && (dump_flags & TDF_DETAILS)) | 5139 if (dump_file && (dump_flags & TDF_DETAILS)) |
5126 case PLUS: | 5224 case PLUS: |
5127 case MINUS: | 5225 case MINUS: |
5128 case XOR: | 5226 case XOR: |
5129 case NOT: | 5227 case NOT: |
5130 case NEG: | 5228 case NEG: |
5229 if (!REG_P (XEXP (src, 0))) | |
5230 return NULL_RTX; | |
5231 break; | |
5131 case SIGN_EXTEND: | 5232 case SIGN_EXTEND: |
5132 case ZERO_EXTEND: | 5233 case ZERO_EXTEND: |
5234 if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0))) | |
5235 return NULL_RTX; | |
5133 break; | 5236 break; |
5134 default: | 5237 default: |
5135 return NULL_RTX; | 5238 return NULL_RTX; |
5136 } | 5239 } |
5137 | 5240 |
5138 if (!REG_P (XEXP (src, 0)) || !SCALAR_INT_MODE_P (GET_MODE (src))) | 5241 if (!SCALAR_INT_MODE_P (GET_MODE (src)) || XEXP (src, 0) == cfa_base_rtx) |
5139 return NULL_RTX; | 5242 return NULL_RTX; |
5140 | 5243 |
5141 v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0); | 5244 v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0, VOIDmode); |
5142 if (!v || !cselib_preserved_value_p (v)) | 5245 if (!v || !cselib_preserved_value_p (v)) |
5143 return NULL_RTX; | 5246 return NULL_RTX; |
5144 | 5247 |
5145 switch (GET_CODE (src)) | 5248 switch (GET_CODE (src)) |
5146 { | 5249 { |
5257 || !CONST_INT_P (XEXP (XEXP (loc, 0), 1)))) | 5360 || !CONST_INT_P (XEXP (XEXP (loc, 0), 1)))) |
5258 { | 5361 { |
5259 rtx mloc = loc; | 5362 rtx mloc = loc; |
5260 enum machine_mode address_mode = get_address_mode (mloc); | 5363 enum machine_mode address_mode = get_address_mode (mloc); |
5261 cselib_val *val = cselib_lookup (XEXP (mloc, 0), | 5364 cselib_val *val = cselib_lookup (XEXP (mloc, 0), |
5262 address_mode, 0); | 5365 address_mode, 0, |
5366 GET_MODE (mloc)); | |
5263 | 5367 |
5264 if (val && !cselib_preserved_value_p (val)) | 5368 if (val && !cselib_preserved_value_p (val)) |
5265 { | 5369 { |
5266 preserve_value (val); | 5370 preserve_value (val); |
5267 mo.type = MO_VAL_USE; | 5371 mo.type = MO_VAL_USE; |
5268 mloc = cselib_subst_to_values (XEXP (mloc, 0)); | 5372 mloc = cselib_subst_to_values (XEXP (mloc, 0), |
5373 GET_MODE (mloc)); | |
5269 mo.u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc); | 5374 mo.u.loc = gen_rtx_CONCAT (address_mode, val->val_rtx, mloc); |
5270 mo.insn = cui->insn; | 5375 mo.insn = cui->insn; |
5271 if (dump_file && (dump_flags & TDF_DETAILS)) | 5376 if (dump_file && (dump_flags & TDF_DETAILS)) |
5272 log_op_type (mo.u.loc, cui->bb, cui->insn, | 5377 log_op_type (mo.u.loc, cui->bb, cui->insn, |
5273 mo.type, dump_file); | 5378 mo.type, dump_file); |
5322 if (nloc) | 5427 if (nloc) |
5323 oloc = nloc; | 5428 oloc = nloc; |
5324 | 5429 |
5325 if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC) | 5430 if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC) |
5326 { | 5431 { |
5327 cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0); | 5432 cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0, VOIDmode); |
5328 | 5433 |
5329 gcc_assert (oval != v); | 5434 gcc_assert (oval != v); |
5330 gcc_assert (REG_P (oloc) || MEM_P (oloc)); | 5435 gcc_assert (REG_P (oloc) || MEM_P (oloc)); |
5331 | 5436 |
5332 if (!cselib_preserved_value_p (oval)) | 5437 if (!cselib_preserved_value_p (oval)) |
5635 | 5740 |
5636 dataflow_set_init (&old_out); | 5741 dataflow_set_init (&old_out); |
5637 dataflow_set_copy (&old_out, out); | 5742 dataflow_set_copy (&old_out, out); |
5638 dataflow_set_copy (out, in); | 5743 dataflow_set_copy (out, in); |
5639 | 5744 |
5640 for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++) | 5745 FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo) |
5641 { | 5746 { |
5642 rtx insn = mo->insn; | 5747 rtx insn = mo->insn; |
5643 | 5748 |
5644 switch (mo->type) | 5749 switch (mo->type) |
5645 { | 5750 { |
5929 int i; | 6034 int i; |
5930 int htabsz = 0; | 6035 int htabsz = 0; |
5931 int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE); | 6036 int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE); |
5932 bool success = true; | 6037 bool success = true; |
5933 | 6038 |
6039 timevar_push (TV_VAR_TRACKING_DATAFLOW); | |
5934 /* Compute reverse completion order of depth first search of the CFG | 6040 /* Compute reverse completion order of depth first search of the CFG |
5935 so that the data-flow runs faster. */ | 6041 so that the data-flow runs faster. */ |
5936 rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS); | 6042 rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS); |
5937 bb_order = XNEWVEC (int, last_basic_block); | 6043 bb_order = XNEWVEC (int, last_basic_block); |
5938 pre_and_rev_post_order_compute (NULL, rc_order, false); | 6044 pre_and_rev_post_order_compute (NULL, rc_order, false); |
5964 | 6070 |
5965 while (!fibheap_empty (worklist)) | 6071 while (!fibheap_empty (worklist)) |
5966 { | 6072 { |
5967 bb = (basic_block) fibheap_extract_min (worklist); | 6073 bb = (basic_block) fibheap_extract_min (worklist); |
5968 RESET_BIT (in_worklist, bb->index); | 6074 RESET_BIT (in_worklist, bb->index); |
6075 gcc_assert (!TEST_BIT (visited, bb->index)); | |
5969 if (!TEST_BIT (visited, bb->index)) | 6076 if (!TEST_BIT (visited, bb->index)) |
5970 { | 6077 { |
5971 bool changed; | 6078 bool changed; |
5972 edge_iterator ei; | 6079 edge_iterator ei; |
5973 int oldinsz, oldoutsz; | 6080 int oldinsz, oldoutsz; |
6116 fibheap_delete (pending); | 6223 fibheap_delete (pending); |
6117 sbitmap_free (visited); | 6224 sbitmap_free (visited); |
6118 sbitmap_free (in_worklist); | 6225 sbitmap_free (in_worklist); |
6119 sbitmap_free (in_pending); | 6226 sbitmap_free (in_pending); |
6120 | 6227 |
6228 timevar_pop (TV_VAR_TRACKING_DATAFLOW); | |
6121 return success; | 6229 return success; |
6122 } | 6230 } |
6123 | 6231 |
6124 /* Print the content of the LIST to dump file. */ | 6232 /* Print the content of the LIST to dump file. */ |
6125 | 6233 |
6977 return loc; | 7085 return loc; |
6978 | 7086 |
6979 data.vars = vars; | 7087 data.vars = vars; |
6980 data.dummy = false; | 7088 data.dummy = false; |
6981 data.cur_loc_changed = false; | 7089 data.cur_loc_changed = false; |
6982 loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5, | 7090 loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 8, |
6983 vt_expand_loc_callback, &data); | 7091 vt_expand_loc_callback, &data); |
6984 | 7092 |
6985 if (loc && MEM_P (loc)) | 7093 if (loc && MEM_P (loc)) |
6986 loc = targetm.delegitimize_address (loc); | 7094 loc = targetm.delegitimize_address (loc); |
6987 return loc; | 7095 return loc; |
6998 | 7106 |
6999 gcc_assert (MAY_HAVE_DEBUG_INSNS); | 7107 gcc_assert (MAY_HAVE_DEBUG_INSNS); |
7000 data.vars = vars; | 7108 data.vars = vars; |
7001 data.dummy = true; | 7109 data.dummy = true; |
7002 data.cur_loc_changed = false; | 7110 data.cur_loc_changed = false; |
7003 ret = cselib_dummy_expand_value_rtx_cb (loc, scratch_regs, 5, | 7111 ret = cselib_dummy_expand_value_rtx_cb (loc, scratch_regs, 8, |
7004 vt_expand_loc_callback, &data); | 7112 vt_expand_loc_callback, &data); |
7005 *pcur_loc_changed = data.cur_loc_changed; | 7113 *pcur_loc_changed = data.cur_loc_changed; |
7006 return ret; | 7114 return ret; |
7007 } | 7115 } |
7008 | |
7009 #ifdef ENABLE_RTL_CHECKING | |
7010 /* Used to verify that cur_loc_changed updating is safe. */ | |
7011 static struct pointer_map_t *emitted_notes; | |
7012 #endif | |
7013 | 7116 |
7014 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP. DATA contains | 7117 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP. DATA contains |
7015 additional parameters: WHERE specifies whether the note shall be emitted | 7118 additional parameters: WHERE specifies whether the note shall be emitted |
7016 before or after instruction INSN. */ | 7119 before or after instruction INSN. */ |
7017 | 7120 |
7053 var->cur_loc_changed = true; | 7156 var->cur_loc_changed = true; |
7054 } | 7157 } |
7055 if (var->n_var_parts == 0) | 7158 if (var->n_var_parts == 0) |
7056 var->cur_loc_changed = true; | 7159 var->cur_loc_changed = true; |
7057 } | 7160 } |
7058 #ifndef ENABLE_RTL_CHECKING | |
7059 if (!var->cur_loc_changed) | 7161 if (!var->cur_loc_changed) |
7060 goto clear; | 7162 goto clear; |
7061 #endif | |
7062 for (i = 0; i < var->n_var_parts; i++) | 7163 for (i = 0; i < var->n_var_parts; i++) |
7063 { | 7164 { |
7064 enum machine_mode mode, wider_mode; | 7165 enum machine_mode mode, wider_mode; |
7065 rtx loc2; | 7166 rtx loc2; |
7066 | 7167 |
7198 gen_rtvec_v (n_var_parts, loc)); | 7299 gen_rtvec_v (n_var_parts, loc)); |
7199 note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, | 7300 note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, |
7200 parallel, (int) initialized); | 7301 parallel, (int) initialized); |
7201 } | 7302 } |
7202 | 7303 |
7203 #ifdef ENABLE_RTL_CHECKING | |
7204 if (note_vl) | |
7205 { | |
7206 void **note_slot = pointer_map_insert (emitted_notes, decl); | |
7207 rtx pnote = (rtx) *note_slot; | |
7208 if (!var->cur_loc_changed && (pnote || PAT_VAR_LOCATION_LOC (note_vl))) | |
7209 { | |
7210 gcc_assert (pnote); | |
7211 gcc_assert (rtx_equal_p (PAT_VAR_LOCATION_LOC (pnote), | |
7212 PAT_VAR_LOCATION_LOC (note_vl))); | |
7213 } | |
7214 *note_slot = (void *) note_vl; | |
7215 } | |
7216 if (!var->cur_loc_changed) | |
7217 goto clear; | |
7218 #endif | |
7219 | |
7220 if (where != EMIT_NOTE_BEFORE_INSN) | 7304 if (where != EMIT_NOTE_BEFORE_INSN) |
7221 { | 7305 { |
7222 note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn); | 7306 note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn); |
7223 if (where == EMIT_NOTE_AFTER_CALL_INSN) | 7307 if (where == EMIT_NOTE_AFTER_CALL_INSN) |
7224 NOTE_DURING_CALL_P (note) = true; | 7308 NOTE_DURING_CALL_P (note) = true; |
7225 } | 7309 } |
7226 else | 7310 else |
7227 note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn); | 7311 { |
7312 /* Make sure that the call related notes come first. */ | |
7313 while (NEXT_INSN (insn) | |
7314 && NOTE_P (insn) | |
7315 && NOTE_DURING_CALL_P (insn)) | |
7316 insn = NEXT_INSN (insn); | |
7317 if (NOTE_P (insn) && NOTE_DURING_CALL_P (insn)) | |
7318 note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn); | |
7319 else | |
7320 note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn); | |
7321 } | |
7228 NOTE_VAR_LOCATION (note) = note_vl; | 7322 NOTE_VAR_LOCATION (note) = note_vl; |
7229 | 7323 |
7230 clear: | 7324 clear: |
7231 set_dv_changed (var->dv, false); | 7325 set_dv_changed (var->dv, false); |
7232 var->cur_loc_changed = false; | 7326 var->cur_loc_changed = false; |
7557 micro_operation *mo; | 7651 micro_operation *mo; |
7558 | 7652 |
7559 dataflow_set_clear (set); | 7653 dataflow_set_clear (set); |
7560 dataflow_set_copy (set, &VTI (bb)->in); | 7654 dataflow_set_copy (set, &VTI (bb)->in); |
7561 | 7655 |
7562 for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++) | 7656 FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo) |
7563 { | 7657 { |
7564 rtx insn = mo->insn; | 7658 rtx insn = mo->insn; |
7565 | 7659 |
7566 switch (mo->type) | 7660 switch (mo->type) |
7567 { | 7661 { |
7833 vt_emit_notes (void) | 7927 vt_emit_notes (void) |
7834 { | 7928 { |
7835 basic_block bb; | 7929 basic_block bb; |
7836 dataflow_set cur; | 7930 dataflow_set cur; |
7837 | 7931 |
7838 #ifdef ENABLE_RTL_CHECKING | |
7839 emitted_notes = pointer_map_create (); | |
7840 #endif | |
7841 gcc_assert (!htab_elements (changed_variables)); | 7932 gcc_assert (!htab_elements (changed_variables)); |
7842 | 7933 |
7843 /* Free memory occupied by the out hash tables, as they aren't used | 7934 /* Free memory occupied by the out hash tables, as they aren't used |
7844 anymore. */ | 7935 anymore. */ |
7845 FOR_EACH_BB (bb) | 7936 FOR_EACH_BB (bb) |
7852 if (MAY_HAVE_DEBUG_INSNS) | 7943 if (MAY_HAVE_DEBUG_INSNS) |
7853 { | 7944 { |
7854 unsigned int i; | 7945 unsigned int i; |
7855 rtx val; | 7946 rtx val; |
7856 | 7947 |
7857 for (i = 0; VEC_iterate (rtx, preserved_values, i, val); i++) | 7948 FOR_EACH_VEC_ELT (rtx, preserved_values, i, val) |
7858 add_cselib_value_chains (dv_from_value (val)); | 7949 add_cselib_value_chains (dv_from_value (val)); |
7859 changed_variables_stack = VEC_alloc (variable, heap, 40); | 7950 changed_variables_stack = VEC_alloc (variable, heap, 40); |
7860 changed_values_stack = VEC_alloc (rtx, heap, 40); | 7951 changed_values_stack = VEC_alloc (rtx, heap, 40); |
7861 } | 7952 } |
7862 | 7953 |
7882 if (MAY_HAVE_DEBUG_INSNS) | 7973 if (MAY_HAVE_DEBUG_INSNS) |
7883 { | 7974 { |
7884 unsigned int i; | 7975 unsigned int i; |
7885 rtx val; | 7976 rtx val; |
7886 | 7977 |
7887 for (i = 0; VEC_iterate (rtx, preserved_values, i, val); i++) | 7978 FOR_EACH_VEC_ELT (rtx, preserved_values, i, val) |
7888 remove_cselib_value_chains (dv_from_value (val)); | 7979 remove_cselib_value_chains (dv_from_value (val)); |
7889 gcc_assert (htab_elements (value_chains) == 0); | 7980 gcc_assert (htab_elements (value_chains) == 0); |
7890 } | 7981 } |
7891 #endif | 7982 #endif |
7892 dataflow_set_destroy (&cur); | 7983 dataflow_set_destroy (&cur); |
7895 { | 7986 { |
7896 VEC_free (variable, heap, changed_variables_stack); | 7987 VEC_free (variable, heap, changed_variables_stack); |
7897 VEC_free (rtx, heap, changed_values_stack); | 7988 VEC_free (rtx, heap, changed_values_stack); |
7898 } | 7989 } |
7899 | 7990 |
7900 #ifdef ENABLE_RTL_CHECKING | |
7901 pointer_map_destroy (emitted_notes); | |
7902 #endif | |
7903 emit_notes = false; | 7991 emit_notes = false; |
7904 } | 7992 } |
7905 | 7993 |
7906 /* If there is a declaration and offset associated with register/memory RTL | 7994 /* If there is a declaration and offset associated with register/memory RTL |
7907 assign declaration to *DECLP and offset to *OFFSETP, and return true. */ | 7995 assign declaration to *DECLP and offset to *OFFSETP, and return true. */ |
7928 } | 8016 } |
7929 } | 8017 } |
7930 return false; | 8018 return false; |
7931 } | 8019 } |
7932 | 8020 |
8021 /* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK. */ | |
8022 | |
8023 static void | |
8024 vt_add_function_parameter (tree parm) | |
8025 { | |
8026 rtx decl_rtl = DECL_RTL_IF_SET (parm); | |
8027 rtx incoming = DECL_INCOMING_RTL (parm); | |
8028 tree decl; | |
8029 enum machine_mode mode; | |
8030 HOST_WIDE_INT offset; | |
8031 dataflow_set *out; | |
8032 decl_or_value dv; | |
8033 | |
8034 if (TREE_CODE (parm) != PARM_DECL) | |
8035 return; | |
8036 | |
8037 if (!decl_rtl || !incoming) | |
8038 return; | |
8039 | |
8040 if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode) | |
8041 return; | |
8042 | |
8043 if (!vt_get_decl_and_offset (incoming, &decl, &offset)) | |
8044 { | |
8045 if (REG_P (incoming) || MEM_P (incoming)) | |
8046 { | |
8047 /* This means argument is passed by invisible reference. */ | |
8048 offset = 0; | |
8049 decl = parm; | |
8050 incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming); | |
8051 } | |
8052 else | |
8053 { | |
8054 if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset)) | |
8055 return; | |
8056 offset += byte_lowpart_offset (GET_MODE (incoming), | |
8057 GET_MODE (decl_rtl)); | |
8058 } | |
8059 } | |
8060 | |
8061 if (!decl) | |
8062 return; | |
8063 | |
8064 if (parm != decl) | |
8065 { | |
8066 /* Assume that DECL_RTL was a pseudo that got spilled to | |
8067 memory. The spill slot sharing code will force the | |
8068 memory to reference spill_slot_decl (%sfp), so we don't | |
8069 match above. That's ok, the pseudo must have referenced | |
8070 the entire parameter, so just reset OFFSET. */ | |
8071 gcc_assert (decl == get_spill_slot_decl (false)); | |
8072 offset = 0; | |
8073 } | |
8074 | |
8075 if (!track_loc_p (incoming, parm, offset, false, &mode, &offset)) | |
8076 return; | |
8077 | |
8078 out = &VTI (ENTRY_BLOCK_PTR)->out; | |
8079 | |
8080 dv = dv_from_decl (parm); | |
8081 | |
8082 if (target_for_debug_bind (parm) | |
8083 /* We can't deal with these right now, because this kind of | |
8084 variable is single-part. ??? We could handle parallels | |
8085 that describe multiple locations for the same single | |
8086 value, but ATM we don't. */ | |
8087 && GET_CODE (incoming) != PARALLEL) | |
8088 { | |
8089 cselib_val *val; | |
8090 | |
8091 /* ??? We shouldn't ever hit this, but it may happen because | |
8092 arguments passed by invisible reference aren't dealt with | |
8093 above: incoming-rtl will have Pmode rather than the | |
8094 expected mode for the type. */ | |
8095 if (offset) | |
8096 return; | |
8097 | |
8098 val = cselib_lookup (var_lowpart (mode, incoming), mode, true, | |
8099 VOIDmode); | |
8100 | |
8101 /* ??? Float-typed values in memory are not handled by | |
8102 cselib. */ | |
8103 if (val) | |
8104 { | |
8105 preserve_value (val); | |
8106 set_variable_part (out, val->val_rtx, dv, offset, | |
8107 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); | |
8108 dv = dv_from_value (val->val_rtx); | |
8109 } | |
8110 } | |
8111 | |
8112 if (REG_P (incoming)) | |
8113 { | |
8114 incoming = var_lowpart (mode, incoming); | |
8115 gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER); | |
8116 attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset, | |
8117 incoming); | |
8118 set_variable_part (out, incoming, dv, offset, | |
8119 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); | |
8120 } | |
8121 else if (MEM_P (incoming)) | |
8122 { | |
8123 incoming = var_lowpart (mode, incoming); | |
8124 set_variable_part (out, incoming, dv, offset, | |
8125 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); | |
8126 } | |
8127 } | |
8128 | |
7933 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */ | 8129 /* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */ |
7934 | 8130 |
7935 static void | 8131 static void |
7936 vt_add_function_parameters (void) | 8132 vt_add_function_parameters (void) |
7937 { | 8133 { |
7938 tree parm; | 8134 tree parm; |
7939 | 8135 |
7940 for (parm = DECL_ARGUMENTS (current_function_decl); | 8136 for (parm = DECL_ARGUMENTS (current_function_decl); |
7941 parm; parm = TREE_CHAIN (parm)) | 8137 parm; parm = DECL_CHAIN (parm)) |
7942 { | 8138 vt_add_function_parameter (parm); |
7943 rtx decl_rtl = DECL_RTL_IF_SET (parm); | 8139 |
7944 rtx incoming = DECL_INCOMING_RTL (parm); | 8140 if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl))) |
7945 tree decl; | 8141 { |
7946 enum machine_mode mode; | 8142 tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl)); |
7947 HOST_WIDE_INT offset; | 8143 |
7948 dataflow_set *out; | 8144 if (TREE_CODE (vexpr) == INDIRECT_REF) |
7949 decl_or_value dv; | 8145 vexpr = TREE_OPERAND (vexpr, 0); |
7950 | 8146 |
7951 if (TREE_CODE (parm) != PARM_DECL) | 8147 if (TREE_CODE (vexpr) == PARM_DECL |
7952 continue; | 8148 && DECL_ARTIFICIAL (vexpr) |
7953 | 8149 && !DECL_IGNORED_P (vexpr) |
7954 if (!DECL_NAME (parm)) | 8150 && DECL_NAMELESS (vexpr)) |
7955 continue; | 8151 vt_add_function_parameter (vexpr); |
7956 | |
7957 if (!decl_rtl || !incoming) | |
7958 continue; | |
7959 | |
7960 if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode) | |
7961 continue; | |
7962 | |
7963 if (!vt_get_decl_and_offset (incoming, &decl, &offset)) | |
7964 { | |
7965 if (REG_P (incoming) || MEM_P (incoming)) | |
7966 { | |
7967 /* This means argument is passed by invisible reference. */ | |
7968 offset = 0; | |
7969 decl = parm; | |
7970 incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming); | |
7971 } | |
7972 else | |
7973 { | |
7974 if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset)) | |
7975 continue; | |
7976 offset += byte_lowpart_offset (GET_MODE (incoming), | |
7977 GET_MODE (decl_rtl)); | |
7978 } | |
7979 } | |
7980 | |
7981 if (!decl) | |
7982 continue; | |
7983 | |
7984 if (parm != decl) | |
7985 { | |
7986 /* Assume that DECL_RTL was a pseudo that got spilled to | |
7987 memory. The spill slot sharing code will force the | |
7988 memory to reference spill_slot_decl (%sfp), so we don't | |
7989 match above. That's ok, the pseudo must have referenced | |
7990 the entire parameter, so just reset OFFSET. */ | |
7991 gcc_assert (decl == get_spill_slot_decl (false)); | |
7992 offset = 0; | |
7993 } | |
7994 | |
7995 if (!track_loc_p (incoming, parm, offset, false, &mode, &offset)) | |
7996 continue; | |
7997 | |
7998 out = &VTI (ENTRY_BLOCK_PTR)->out; | |
7999 | |
8000 dv = dv_from_decl (parm); | |
8001 | |
8002 if (target_for_debug_bind (parm) | |
8003 /* We can't deal with these right now, because this kind of | |
8004 variable is single-part. ??? We could handle parallels | |
8005 that describe multiple locations for the same single | |
8006 value, but ATM we don't. */ | |
8007 && GET_CODE (incoming) != PARALLEL) | |
8008 { | |
8009 cselib_val *val; | |
8010 | |
8011 /* ??? We shouldn't ever hit this, but it may happen because | |
8012 arguments passed by invisible reference aren't dealt with | |
8013 above: incoming-rtl will have Pmode rather than the | |
8014 expected mode for the type. */ | |
8015 if (offset) | |
8016 continue; | |
8017 | |
8018 val = cselib_lookup (var_lowpart (mode, incoming), mode, true); | |
8019 | |
8020 /* ??? Float-typed values in memory are not handled by | |
8021 cselib. */ | |
8022 if (val) | |
8023 { | |
8024 preserve_value (val); | |
8025 set_variable_part (out, val->val_rtx, dv, offset, | |
8026 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); | |
8027 dv = dv_from_value (val->val_rtx); | |
8028 } | |
8029 } | |
8030 | |
8031 if (REG_P (incoming)) | |
8032 { | |
8033 incoming = var_lowpart (mode, incoming); | |
8034 gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER); | |
8035 attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset, | |
8036 incoming); | |
8037 set_variable_part (out, incoming, dv, offset, | |
8038 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); | |
8039 } | |
8040 else if (MEM_P (incoming)) | |
8041 { | |
8042 incoming = var_lowpart (mode, incoming); | |
8043 set_variable_part (out, incoming, dv, offset, | |
8044 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); | |
8045 } | |
8046 } | 8152 } |
8047 | 8153 |
8048 if (MAY_HAVE_DEBUG_INSNS) | 8154 if (MAY_HAVE_DEBUG_INSNS) |
8049 { | 8155 { |
8050 cselib_preserve_only_values (); | 8156 cselib_preserve_only_values (); |
8088 { | 8194 { |
8089 cselib_val *val; | 8195 cselib_val *val; |
8090 | 8196 |
8091 #ifdef FRAME_POINTER_CFA_OFFSET | 8197 #ifdef FRAME_POINTER_CFA_OFFSET |
8092 cfa_base_rtx = frame_pointer_rtx; | 8198 cfa_base_rtx = frame_pointer_rtx; |
8199 cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl); | |
8093 #else | 8200 #else |
8094 cfa_base_rtx = arg_pointer_rtx; | 8201 cfa_base_rtx = arg_pointer_rtx; |
8202 cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl); | |
8095 #endif | 8203 #endif |
8096 if (cfa_base_rtx == hard_frame_pointer_rtx | 8204 if (cfa_base_rtx == hard_frame_pointer_rtx |
8097 || !fixed_regs[REGNO (cfa_base_rtx)]) | 8205 || !fixed_regs[REGNO (cfa_base_rtx)]) |
8098 { | 8206 { |
8099 cfa_base_rtx = NULL_RTX; | 8207 cfa_base_rtx = NULL_RTX; |
8100 return; | 8208 return; |
8101 } | 8209 } |
8102 if (!MAY_HAVE_DEBUG_INSNS) | 8210 if (!MAY_HAVE_DEBUG_INSNS) |
8103 return; | 8211 return; |
8104 | 8212 |
8213 /* Tell alias analysis that cfa_base_rtx should share | |
8214 find_base_term value with stack pointer or hard frame pointer. */ | |
8215 vt_equate_reg_base_value (cfa_base_rtx, | |
8216 frame_pointer_needed | |
8217 ? hard_frame_pointer_rtx : stack_pointer_rtx); | |
8105 val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1, | 8218 val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1, |
8106 get_insns ()); | 8219 VOIDmode, get_insns ()); |
8107 preserve_value (val); | 8220 preserve_value (val); |
8108 cselib_preserve_cfa_base_value (val); | 8221 cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx)); |
8109 var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out, cfa_base_rtx, | 8222 var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out, cfa_base_rtx, |
8110 VAR_INIT_STATUS_INITIALIZED, dv_from_value (val->val_rtx), | 8223 VAR_INIT_STATUS_INITIALIZED, dv_from_value (val->val_rtx), |
8111 0, NULL_RTX, INSERT); | 8224 0, NULL_RTX, INSERT); |
8112 } | 8225 } |
8113 | 8226 |
8471 { | 8584 { |
8472 dump_dataflow_sets (); | 8585 dump_dataflow_sets (); |
8473 dump_flow_info (dump_file, dump_flags); | 8586 dump_flow_info (dump_file, dump_flags); |
8474 } | 8587 } |
8475 | 8588 |
8589 timevar_push (TV_VAR_TRACKING_EMIT); | |
8476 vt_emit_notes (); | 8590 vt_emit_notes (); |
8591 timevar_pop (TV_VAR_TRACKING_EMIT); | |
8477 | 8592 |
8478 vt_finalize (); | 8593 vt_finalize (); |
8479 vt_debug_insns_local (false); | 8594 vt_debug_insns_local (false); |
8480 return 0; | 8595 return 0; |
8481 } | 8596 } |