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 }