Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-nested.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 |
---|---|
29 #include "tree-inline.h" | 29 #include "tree-inline.h" |
30 #include "gimple.h" | 30 #include "gimple.h" |
31 #include "tree-iterator.h" | 31 #include "tree-iterator.h" |
32 #include "tree-flow.h" | 32 #include "tree-flow.h" |
33 #include "cgraph.h" | 33 #include "cgraph.h" |
34 #include "expr.h" | 34 #include "expr.h" /* FIXME: For STACK_SAVEAREA_MODE and SAVE_NONLOCAL. */ |
35 #include "langhooks.h" | 35 #include "langhooks.h" |
36 #include "pointer-set.h" | 36 #include "pointer-set.h" |
37 | 37 |
38 | 38 |
39 /* The object of this pass is to lower the representation of a set of nested | 39 /* The object of this pass is to lower the representation of a set of nested |
82 struct nesting_info *inner; | 82 struct nesting_info *inner; |
83 struct nesting_info *next; | 83 struct nesting_info *next; |
84 | 84 |
85 struct pointer_map_t *field_map; | 85 struct pointer_map_t *field_map; |
86 struct pointer_map_t *var_map; | 86 struct pointer_map_t *var_map; |
87 struct pointer_set_t *mem_refs; | |
87 bitmap suppress_expansion; | 88 bitmap suppress_expansion; |
88 | 89 |
89 tree context; | 90 tree context; |
90 tree new_local_var_chain; | 91 tree new_local_var_chain; |
91 tree debug_var_chain; | 92 tree debug_var_chain; |
145 gcc_assert (!TYPE_SIZE_UNIT (type) | 146 gcc_assert (!TYPE_SIZE_UNIT (type) |
146 || TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST); | 147 || TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST); |
147 | 148 |
148 tmp_var = create_tmp_var_raw (type, prefix); | 149 tmp_var = create_tmp_var_raw (type, prefix); |
149 DECL_CONTEXT (tmp_var) = info->context; | 150 DECL_CONTEXT (tmp_var) = info->context; |
150 TREE_CHAIN (tmp_var) = info->new_local_var_chain; | 151 DECL_CHAIN (tmp_var) = info->new_local_var_chain; |
151 DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1; | 152 DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1; |
152 if (TREE_CODE (type) == COMPLEX_TYPE | 153 if (TREE_CODE (type) == COMPLEX_TYPE |
153 || TREE_CODE (type) == VECTOR_TYPE) | 154 || TREE_CODE (type) == VECTOR_TYPE) |
154 DECL_GIMPLE_REG_P (tmp_var) = 1; | 155 DECL_GIMPLE_REG_P (tmp_var) = 1; |
155 | 156 |
181 Temporarily set CURRENT_FUNCTION_DECL to the desired context, | 182 Temporarily set CURRENT_FUNCTION_DECL to the desired context, |
182 build the ADDR_EXPR, then restore CURRENT_FUNCTION_DECL. That | 183 build the ADDR_EXPR, then restore CURRENT_FUNCTION_DECL. That |
183 way the properties are for the ADDR_EXPR are computed properly. */ | 184 way the properties are for the ADDR_EXPR are computed properly. */ |
184 save_context = current_function_decl; | 185 save_context = current_function_decl; |
185 current_function_decl = context; | 186 current_function_decl = context; |
186 retval = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp); | 187 retval = build_fold_addr_expr (exp); |
187 current_function_decl = save_context; | 188 current_function_decl = save_context; |
188 return retval; | 189 return retval; |
189 } | 190 } |
190 | 191 |
191 /* Insert FIELD into TYPE, sorted by alignment requirements. */ | 192 /* Insert FIELD into TYPE, sorted by alignment requirements. */ |
195 { | 196 { |
196 tree *p; | 197 tree *p; |
197 | 198 |
198 DECL_CONTEXT (field) = type; | 199 DECL_CONTEXT (field) = type; |
199 | 200 |
200 for (p = &TYPE_FIELDS (type); *p ; p = &TREE_CHAIN (*p)) | 201 for (p = &TYPE_FIELDS (type); *p ; p = &DECL_CHAIN (*p)) |
201 if (DECL_ALIGN (field) >= DECL_ALIGN (*p)) | 202 if (DECL_ALIGN (field) >= DECL_ALIGN (*p)) |
202 break; | 203 break; |
203 | 204 |
204 TREE_CHAIN (field) = *p; | 205 DECL_CHAIN (field) = *p; |
205 *p = field; | 206 *p = field; |
206 | 207 |
207 /* Set correct alignment for frame struct type. */ | 208 /* Set correct alignment for frame struct type. */ |
208 if (TYPE_ALIGN (type) < DECL_ALIGN (field)) | 209 if (TYPE_ALIGN (type) < DECL_ALIGN (field)) |
209 TYPE_ALIGN (type) = DECL_ALIGN (field); | 210 TYPE_ALIGN (type) = DECL_ALIGN (field); |
695 struct cgraph_node *cgn = cgraph_node (fndecl); | 696 struct cgraph_node *cgn = cgraph_node (fndecl); |
696 tree arg; | 697 tree arg; |
697 | 698 |
698 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) | 699 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) |
699 { | 700 { |
700 for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = TREE_CHAIN (arg)) | 701 for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = DECL_CHAIN (arg)) |
701 if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl)) | 702 if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl)) |
702 return true; | 703 return true; |
703 | 704 |
704 if (check_for_nested_with_variably_modified (cgn->decl, orig_fndecl)) | 705 if (check_for_nested_with_variably_modified (cgn->decl, orig_fndecl)) |
705 return true; | 706 return true; |
715 create_nesting_tree (struct cgraph_node *cgn) | 716 create_nesting_tree (struct cgraph_node *cgn) |
716 { | 717 { |
717 struct nesting_info *info = XCNEW (struct nesting_info); | 718 struct nesting_info *info = XCNEW (struct nesting_info); |
718 info->field_map = pointer_map_create (); | 719 info->field_map = pointer_map_create (); |
719 info->var_map = pointer_map_create (); | 720 info->var_map = pointer_map_create (); |
721 info->mem_refs = pointer_set_create (); | |
720 info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack); | 722 info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack); |
721 info->context = cgn->decl; | 723 info->context = cgn->decl; |
722 | 724 |
723 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) | 725 for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) |
724 { | 726 { |
756 | 758 |
757 for (i = info->outer; i->context != target_context; i = i->outer) | 759 for (i = info->outer; i->context != target_context; i = i->outer) |
758 { | 760 { |
759 tree field = get_chain_field (i); | 761 tree field = get_chain_field (i); |
760 | 762 |
761 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 763 x = build_simple_mem_ref (x); |
762 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 764 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
763 x = init_tmp_var (info, x, gsi); | 765 x = init_tmp_var (info, x, gsi); |
764 } | 766 } |
765 } | 767 } |
766 | 768 |
791 | 793 |
792 for (i = info->outer; i->context != target_context; i = i->outer) | 794 for (i = info->outer; i->context != target_context; i = i->outer) |
793 { | 795 { |
794 tree field = get_chain_field (i); | 796 tree field = get_chain_field (i); |
795 | 797 |
796 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 798 x = build_simple_mem_ref (x); |
797 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 799 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
798 x = init_tmp_var (info, x, gsi); | 800 x = init_tmp_var (info, x, gsi); |
799 } | 801 } |
800 | 802 |
801 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 803 x = build_simple_mem_ref (x); |
802 } | 804 } |
803 | 805 |
804 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 806 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
805 return x; | 807 return x; |
806 } | 808 } |
839 { | 841 { |
840 x = get_chain_decl (info); | 842 x = get_chain_decl (info); |
841 for (i = info->outer; i->context != target_context; i = i->outer) | 843 for (i = info->outer; i->context != target_context; i = i->outer) |
842 { | 844 { |
843 field = get_chain_field (i); | 845 field = get_chain_field (i); |
844 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 846 x = build_simple_mem_ref (x); |
845 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 847 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
846 } | 848 } |
847 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 849 x = build_simple_mem_ref (x); |
848 } | 850 } |
849 | 851 |
850 field = lookup_field_for_decl (i, decl, INSERT); | 852 field = lookup_field_for_decl (i, decl, INSERT); |
851 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); | 853 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE); |
852 if (use_pointer_in_frame (decl)) | 854 if (use_pointer_in_frame (decl)) |
853 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 855 x = build_simple_mem_ref (x); |
854 | 856 |
855 /* ??? We should be remapping types as well, surely. */ | 857 /* ??? We should be remapping types as well, surely. */ |
856 new_decl = build_decl (DECL_SOURCE_LOCATION (decl), | 858 new_decl = build_decl (DECL_SOURCE_LOCATION (decl), |
857 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); | 859 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); |
858 DECL_CONTEXT (new_decl) = info->context; | 860 DECL_CONTEXT (new_decl) = info->context; |
871 | 873 |
872 SET_DECL_VALUE_EXPR (new_decl, x); | 874 SET_DECL_VALUE_EXPR (new_decl, x); |
873 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; | 875 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; |
874 | 876 |
875 *slot = new_decl; | 877 *slot = new_decl; |
876 TREE_CHAIN (new_decl) = info->debug_var_chain; | 878 DECL_CHAIN (new_decl) = info->debug_var_chain; |
877 info->debug_var_chain = new_decl; | 879 info->debug_var_chain = new_decl; |
878 | 880 |
879 if (!optimize | 881 if (!optimize |
880 && info->context != target_context | 882 && info->context != target_context |
881 && variably_modified_type_p (TREE_TYPE (decl), NULL)) | 883 && variably_modified_type_p (TREE_TYPE (decl), NULL)) |
925 x = lookup_field_for_decl (i, t, INSERT); | 927 x = lookup_field_for_decl (i, t, INSERT); |
926 x = get_frame_field (info, target_context, x, &wi->gsi); | 928 x = get_frame_field (info, target_context, x, &wi->gsi); |
927 if (use_pointer_in_frame (t)) | 929 if (use_pointer_in_frame (t)) |
928 { | 930 { |
929 x = init_tmp_var (info, x, &wi->gsi); | 931 x = init_tmp_var (info, x, &wi->gsi); |
930 x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x); | 932 x = build_simple_mem_ref (x); |
931 } | 933 } |
932 } | 934 } |
933 | 935 |
934 if (wi->val_only) | 936 if (wi->val_only) |
935 { | 937 { |
1198 static void | 1200 static void |
1199 note_nonlocal_block_vlas (struct nesting_info *info, tree block) | 1201 note_nonlocal_block_vlas (struct nesting_info *info, tree block) |
1200 { | 1202 { |
1201 tree var; | 1203 tree var; |
1202 | 1204 |
1203 for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) | 1205 for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) |
1204 if (TREE_CODE (var) == VAR_DECL | 1206 if (TREE_CODE (var) == VAR_DECL |
1205 && variably_modified_type_p (TREE_TYPE (var), NULL) | 1207 && variably_modified_type_p (TREE_TYPE (var), NULL) |
1206 && DECL_HAS_VALUE_EXPR_P (var) | 1208 && DECL_HAS_VALUE_EXPR_P (var) |
1207 && decl_function_context (var) != info->context) | 1209 && decl_function_context (var) != info->context) |
1208 note_nonlocal_vla_type (info, TREE_TYPE (var)); | 1210 note_nonlocal_vla_type (info, TREE_TYPE (var)); |
1363 | 1365 |
1364 SET_DECL_VALUE_EXPR (new_decl, x); | 1366 SET_DECL_VALUE_EXPR (new_decl, x); |
1365 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; | 1367 DECL_HAS_VALUE_EXPR_P (new_decl) = 1; |
1366 *slot = new_decl; | 1368 *slot = new_decl; |
1367 | 1369 |
1368 TREE_CHAIN (new_decl) = info->debug_var_chain; | 1370 DECL_CHAIN (new_decl) = info->debug_var_chain; |
1369 info->debug_var_chain = new_decl; | 1371 info->debug_var_chain = new_decl; |
1370 | 1372 |
1371 /* Do not emit debug info twice. */ | 1373 /* Do not emit debug info twice. */ |
1372 DECL_IGNORED_P (decl) = 1; | 1374 DECL_IGNORED_P (decl) = 1; |
1373 | 1375 |
1496 wi->val_only = false; | 1498 wi->val_only = false; |
1497 walk_tree (tp, convert_local_reference_op, wi, NULL); | 1499 walk_tree (tp, convert_local_reference_op, wi, NULL); |
1498 wi->val_only = save_val_only; | 1500 wi->val_only = save_val_only; |
1499 break; | 1501 break; |
1500 | 1502 |
1503 case MEM_REF: | |
1504 save_val_only = wi->val_only; | |
1505 wi->val_only = true; | |
1506 wi->is_lhs = false; | |
1507 walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op, | |
1508 wi, NULL); | |
1509 /* We need to re-fold the MEM_REF as component references as | |
1510 part of a ADDR_EXPR address are not allowed. But we cannot | |
1511 fold here, as the chain record type is not yet finalized. */ | |
1512 if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR | |
1513 && !DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0))) | |
1514 pointer_set_insert (info->mem_refs, tp); | |
1515 wi->val_only = save_val_only; | |
1516 break; | |
1517 | |
1501 case VIEW_CONVERT_EXPR: | 1518 case VIEW_CONVERT_EXPR: |
1502 /* Just request to look at the subtrees, leaving val_only and lhs | 1519 /* Just request to look at the subtrees, leaving val_only and lhs |
1503 untouched. This might actually be for !val_only + lhs, in which | 1520 untouched. This might actually be for !val_only + lhs, in which |
1504 case we don't want to force a replacement by a temporary. */ | 1521 case we don't want to force a replacement by a temporary. */ |
1505 *walk_subtrees = 1; | 1522 *walk_subtrees = 1; |
2051 actually uses its static chain; if not, remember that. */ | 2068 actually uses its static chain; if not, remember that. */ |
2052 | 2069 |
2053 static void | 2070 static void |
2054 convert_all_function_calls (struct nesting_info *root) | 2071 convert_all_function_calls (struct nesting_info *root) |
2055 { | 2072 { |
2073 unsigned int chain_count = 0, old_chain_count, iter_count; | |
2056 struct nesting_info *n; | 2074 struct nesting_info *n; |
2057 int iter_count; | |
2058 bool any_changed; | |
2059 | 2075 |
2060 /* First, optimistically clear static_chain for all decls that haven't | 2076 /* First, optimistically clear static_chain for all decls that haven't |
2061 used the static chain already for variable access. */ | 2077 used the static chain already for variable access. */ |
2062 FOR_EACH_NEST_INFO (n, root) | 2078 FOR_EACH_NEST_INFO (n, root) |
2063 { | 2079 { |
2069 fprintf (dump_file, "Guessing no static-chain for %s\n", | 2085 fprintf (dump_file, "Guessing no static-chain for %s\n", |
2070 lang_hooks.decl_printable_name (decl, 2)); | 2086 lang_hooks.decl_printable_name (decl, 2)); |
2071 } | 2087 } |
2072 else | 2088 else |
2073 DECL_STATIC_CHAIN (decl) = 1; | 2089 DECL_STATIC_CHAIN (decl) = 1; |
2090 chain_count += DECL_STATIC_CHAIN (decl); | |
2074 } | 2091 } |
2075 | 2092 |
2076 /* Walk the functions and perform transformations. Note that these | 2093 /* Walk the functions and perform transformations. Note that these |
2077 transformations can induce new uses of the static chain, which in turn | 2094 transformations can induce new uses of the static chain, which in turn |
2078 require re-examining all users of the decl. */ | 2095 require re-examining all users of the decl. */ |
2081 would still need to iterate in this loop since address-of references | 2098 would still need to iterate in this loop since address-of references |
2082 wouldn't show up in the callgraph anyway. */ | 2099 wouldn't show up in the callgraph anyway. */ |
2083 iter_count = 0; | 2100 iter_count = 0; |
2084 do | 2101 do |
2085 { | 2102 { |
2086 any_changed = false; | 2103 old_chain_count = chain_count; |
2104 chain_count = 0; | |
2087 iter_count++; | 2105 iter_count++; |
2088 | 2106 |
2089 if (dump_file && (dump_flags & TDF_DETAILS)) | 2107 if (dump_file && (dump_flags & TDF_DETAILS)) |
2090 fputc ('\n', dump_file); | 2108 fputc ('\n', dump_file); |
2091 | 2109 |
2092 FOR_EACH_NEST_INFO (n, root) | 2110 FOR_EACH_NEST_INFO (n, root) |
2093 { | 2111 { |
2094 tree decl = n->context; | 2112 tree decl = n->context; |
2095 bool old_static_chain = DECL_STATIC_CHAIN (decl); | |
2096 | |
2097 walk_function (convert_tramp_reference_stmt, | 2113 walk_function (convert_tramp_reference_stmt, |
2098 convert_tramp_reference_op, n); | 2114 convert_tramp_reference_op, n); |
2099 walk_function (convert_gimple_call, NULL, n); | 2115 walk_function (convert_gimple_call, NULL, n); |
2100 | 2116 chain_count += DECL_STATIC_CHAIN (decl); |
2101 /* If a call to another function created the use of a chain | |
2102 within this function, we'll have to continue iteration. */ | |
2103 if (!old_static_chain && DECL_STATIC_CHAIN (decl)) | |
2104 any_changed = true; | |
2105 } | 2117 } |
2106 } | 2118 } |
2107 while (any_changed); | 2119 while (chain_count != old_chain_count); |
2108 | 2120 |
2109 if (dump_file && (dump_flags & TDF_DETAILS)) | 2121 if (dump_file && (dump_flags & TDF_DETAILS)) |
2110 fprintf (dump_file, "convert_all_function_calls iterations: %d\n\n", | 2122 fprintf (dump_file, "convert_all_function_calls iterations: %u\n\n", |
2111 iter_count); | 2123 iter_count); |
2112 } | 2124 } |
2113 | 2125 |
2114 struct nesting_copy_body_data | 2126 struct nesting_copy_body_data |
2115 { | 2127 { |
2177 for (subblock = BLOCK_SUBBLOCKS (block); | 2189 for (subblock = BLOCK_SUBBLOCKS (block); |
2178 subblock; | 2190 subblock; |
2179 subblock = BLOCK_CHAIN (subblock)) | 2191 subblock = BLOCK_CHAIN (subblock)) |
2180 remap_vla_decls (subblock, root); | 2192 remap_vla_decls (subblock, root); |
2181 | 2193 |
2182 for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) | 2194 for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) |
2183 { | 2195 if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) |
2184 if (TREE_CODE (var) == VAR_DECL | 2196 { |
2185 && variably_modified_type_p (TREE_TYPE (var), NULL) | 2197 val = DECL_VALUE_EXPR (var); |
2186 && DECL_HAS_VALUE_EXPR_P (var)) | 2198 type = TREE_TYPE (var); |
2187 { | 2199 |
2188 type = TREE_TYPE (var); | 2200 if (!(TREE_CODE (val) == INDIRECT_REF |
2189 val = DECL_VALUE_EXPR (var); | 2201 && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL |
2190 if (walk_tree (&type, contains_remapped_vars, root, NULL) != NULL | 2202 && variably_modified_type_p (type, NULL))) |
2191 || walk_tree (&val, contains_remapped_vars, root, NULL) != NULL) | 2203 continue; |
2192 break; | 2204 |
2193 } | 2205 if (pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)) |
2194 } | 2206 || walk_tree (&type, contains_remapped_vars, root, NULL)) |
2207 break; | |
2208 } | |
2209 | |
2195 if (var == NULL_TREE) | 2210 if (var == NULL_TREE) |
2196 return; | 2211 return; |
2197 | 2212 |
2198 memset (&id, 0, sizeof (id)); | 2213 memset (&id, 0, sizeof (id)); |
2199 id.cb.copy_decl = nesting_copy_decl; | 2214 id.cb.copy_decl = nesting_copy_decl; |
2200 id.cb.decl_map = pointer_map_create (); | 2215 id.cb.decl_map = pointer_map_create (); |
2201 id.root = root; | 2216 id.root = root; |
2202 | 2217 |
2203 for (; var; var = TREE_CHAIN (var)) | 2218 for (; var; var = DECL_CHAIN (var)) |
2204 if (TREE_CODE (var) == VAR_DECL | 2219 if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) |
2205 && variably_modified_type_p (TREE_TYPE (var), NULL) | |
2206 && DECL_HAS_VALUE_EXPR_P (var)) | |
2207 { | 2220 { |
2208 struct nesting_info *i; | 2221 struct nesting_info *i; |
2209 tree newt, t, context; | 2222 tree newt, context; |
2210 | 2223 void **slot; |
2211 t = type = TREE_TYPE (var); | 2224 |
2212 val = DECL_VALUE_EXPR (var); | 2225 val = DECL_VALUE_EXPR (var); |
2213 if (walk_tree (&type, contains_remapped_vars, root, NULL) == NULL | 2226 type = TREE_TYPE (var); |
2214 && walk_tree (&val, contains_remapped_vars, root, NULL) == NULL) | 2227 |
2228 if (!(TREE_CODE (val) == INDIRECT_REF | |
2229 && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL | |
2230 && variably_modified_type_p (type, NULL))) | |
2231 continue; | |
2232 | |
2233 slot = pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)); | |
2234 if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL)) | |
2215 continue; | 2235 continue; |
2216 | 2236 |
2217 context = decl_function_context (var); | 2237 context = decl_function_context (var); |
2218 for (i = root; i; i = i->outer) | 2238 for (i = root; i; i = i->outer) |
2219 if (i->context == context) | 2239 if (i->context == context) |
2220 break; | 2240 break; |
2221 | 2241 |
2222 if (i == NULL) | 2242 if (i == NULL) |
2223 continue; | 2243 continue; |
2224 | 2244 |
2245 /* Fully expand value expressions. This avoids having debug variables | |
2246 only referenced from them and that can be swept during GC. */ | |
2247 if (slot) | |
2248 { | |
2249 tree t = (tree) *slot; | |
2250 gcc_assert (DECL_P (t) && DECL_HAS_VALUE_EXPR_P (t)); | |
2251 val = build1 (INDIRECT_REF, TREE_TYPE (val), DECL_VALUE_EXPR (t)); | |
2252 } | |
2253 | |
2225 id.cb.src_fn = i->context; | 2254 id.cb.src_fn = i->context; |
2226 id.cb.dst_fn = i->context; | 2255 id.cb.dst_fn = i->context; |
2227 id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); | 2256 id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); |
2228 | 2257 |
2229 TREE_TYPE (var) = newt = remap_type (type, &id.cb); | 2258 TREE_TYPE (var) = newt = remap_type (type, &id.cb); |
2230 while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) | 2259 while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) |
2231 { | 2260 { |
2232 newt = TREE_TYPE (newt); | 2261 newt = TREE_TYPE (newt); |
2233 t = TREE_TYPE (t); | 2262 type = TREE_TYPE (type); |
2234 } | 2263 } |
2235 if (TYPE_NAME (newt) | 2264 if (TYPE_NAME (newt) |
2236 && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL | 2265 && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL |
2237 && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) | 2266 && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) |
2238 && newt != t | 2267 && newt != type |
2239 && TYPE_NAME (newt) == TYPE_NAME (t)) | 2268 && TYPE_NAME (newt) == TYPE_NAME (type)) |
2240 TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); | 2269 TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); |
2241 | 2270 |
2242 walk_tree (&val, copy_tree_body_r, &id.cb, NULL); | 2271 walk_tree (&val, copy_tree_body_r, &id.cb, NULL); |
2243 if (val != DECL_VALUE_EXPR (var)) | 2272 if (val != DECL_VALUE_EXPR (var)) |
2244 SET_DECL_VALUE_EXPR (var, val); | 2273 SET_DECL_VALUE_EXPR (var, val); |
2245 } | 2274 } |
2246 | 2275 |
2247 pointer_map_destroy (id.cb.decl_map); | 2276 pointer_map_destroy (id.cb.decl_map); |
2277 } | |
2278 | |
2279 /* Fold the MEM_REF *E. */ | |
2280 static bool | |
2281 fold_mem_refs (const void *e, void *data ATTRIBUTE_UNUSED) | |
2282 { | |
2283 tree *ref_p = CONST_CAST2(tree *, const tree *, (const tree *)e); | |
2284 *ref_p = fold (*ref_p); | |
2285 return true; | |
2248 } | 2286 } |
2249 | 2287 |
2250 /* Do "everything else" to clean up or complete state collected by the | 2288 /* Do "everything else" to clean up or complete state collected by the |
2251 various walking passes -- lay out the types and decls, generate code | 2289 various walking passes -- lay out the types and decls, generate code |
2252 to initialize the frame decl, store critical expressions in the | 2290 to initialize the frame decl, store critical expressions in the |
2280 that we can declare it also in the lexical blocks, which | 2318 that we can declare it also in the lexical blocks, which |
2281 helps ensure virtual regs that end up appearing in its RTL | 2319 helps ensure virtual regs that end up appearing in its RTL |
2282 expression get substituted in instantiate_virtual_regs(). */ | 2320 expression get substituted in instantiate_virtual_regs(). */ |
2283 for (adjust = &root->new_local_var_chain; | 2321 for (adjust = &root->new_local_var_chain; |
2284 *adjust != root->frame_decl; | 2322 *adjust != root->frame_decl; |
2285 adjust = &TREE_CHAIN (*adjust)) | 2323 adjust = &DECL_CHAIN (*adjust)) |
2286 gcc_assert (TREE_CHAIN (*adjust)); | 2324 gcc_assert (DECL_CHAIN (*adjust)); |
2287 *adjust = TREE_CHAIN (*adjust); | 2325 *adjust = DECL_CHAIN (*adjust); |
2288 | 2326 |
2289 TREE_CHAIN (root->frame_decl) = NULL_TREE; | 2327 DECL_CHAIN (root->frame_decl) = NULL_TREE; |
2290 declare_vars (root->frame_decl, | 2328 declare_vars (root->frame_decl, |
2291 gimple_seq_first_stmt (gimple_body (context)), true); | 2329 gimple_seq_first_stmt (gimple_body (context)), true); |
2292 } | 2330 } |
2293 | 2331 |
2294 /* If any parameters were referenced non-locally, then we need to | 2332 /* If any parameters were referenced non-locally, then we need to |
2295 insert a copy. Likewise, if any variables were referenced by | 2333 insert a copy. Likewise, if any variables were referenced by |
2296 pointer, we need to initialize the address. */ | 2334 pointer, we need to initialize the address. */ |
2297 if (root->any_parm_remapped) | 2335 if (root->any_parm_remapped) |
2298 { | 2336 { |
2299 tree p; | 2337 tree p; |
2300 for (p = DECL_ARGUMENTS (context); p ; p = TREE_CHAIN (p)) | 2338 for (p = DECL_ARGUMENTS (context); p ; p = DECL_CHAIN (p)) |
2301 { | 2339 { |
2302 tree field, x, y; | 2340 tree field, x, y; |
2303 | 2341 |
2304 field = lookup_field_for_decl (root, p, NO_INSERT); | 2342 field = lookup_field_for_decl (root, p, NO_INSERT); |
2305 if (!field) | 2343 if (!field) |
2400 gimple scope; | 2438 gimple scope; |
2401 | 2439 |
2402 remap_vla_decls (DECL_INITIAL (root->context), root); | 2440 remap_vla_decls (DECL_INITIAL (root->context), root); |
2403 | 2441 |
2404 for (debug_var = root->debug_var_chain; debug_var; | 2442 for (debug_var = root->debug_var_chain; debug_var; |
2405 debug_var = TREE_CHAIN (debug_var)) | 2443 debug_var = DECL_CHAIN (debug_var)) |
2406 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) | 2444 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) |
2407 break; | 2445 break; |
2408 | 2446 |
2409 /* If there are any debug decls with variable length types, | 2447 /* If there are any debug decls with variable length types, |
2410 remap those types using other debug_var_chain variables. */ | 2448 remap those types using other debug_var_chain variables. */ |
2415 memset (&id, 0, sizeof (id)); | 2453 memset (&id, 0, sizeof (id)); |
2416 id.cb.copy_decl = nesting_copy_decl; | 2454 id.cb.copy_decl = nesting_copy_decl; |
2417 id.cb.decl_map = pointer_map_create (); | 2455 id.cb.decl_map = pointer_map_create (); |
2418 id.root = root; | 2456 id.root = root; |
2419 | 2457 |
2420 for (; debug_var; debug_var = TREE_CHAIN (debug_var)) | 2458 for (; debug_var; debug_var = DECL_CHAIN (debug_var)) |
2421 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) | 2459 if (variably_modified_type_p (TREE_TYPE (debug_var), NULL)) |
2422 { | 2460 { |
2423 tree type = TREE_TYPE (debug_var); | 2461 tree type = TREE_TYPE (debug_var); |
2424 tree newt, t = type; | 2462 tree newt, t = type; |
2425 struct nesting_info *i; | 2463 struct nesting_info *i; |
2459 BLOCK_VARS (DECL_INITIAL (root->context)) | 2497 BLOCK_VARS (DECL_INITIAL (root->context)) |
2460 = chainon (BLOCK_VARS (DECL_INITIAL (root->context)), | 2498 = chainon (BLOCK_VARS (DECL_INITIAL (root->context)), |
2461 root->debug_var_chain); | 2499 root->debug_var_chain); |
2462 } | 2500 } |
2463 | 2501 |
2502 /* Fold the rewritten MEM_REF trees. */ | |
2503 pointer_set_traverse (root->mem_refs, fold_mem_refs, NULL); | |
2504 | |
2464 /* Dump the translated tree function. */ | 2505 /* Dump the translated tree function. */ |
2465 if (dump_file) | 2506 if (dump_file) |
2466 { | 2507 { |
2467 fputs ("\n\n", dump_file); | 2508 fputs ("\n\n", dump_file); |
2468 dump_function_to_file (root->context, dump_file, dump_flags); | 2509 dump_function_to_file (root->context, dump_file, dump_flags); |
2512 do | 2553 do |
2513 { | 2554 { |
2514 next = iter_nestinfo_next (node); | 2555 next = iter_nestinfo_next (node); |
2515 pointer_map_destroy (node->var_map); | 2556 pointer_map_destroy (node->var_map); |
2516 pointer_map_destroy (node->field_map); | 2557 pointer_map_destroy (node->field_map); |
2558 pointer_set_destroy (node->mem_refs); | |
2517 free (node); | 2559 free (node); |
2518 node = next; | 2560 node = next; |
2519 } | 2561 } |
2520 while (node); | 2562 while (node); |
2521 } | 2563 } |