Mercurial > hg > CbC > CbC_gcc
comparison gcc/gimple.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* Gimple IR support functions. | 1 /* Gimple IR support functions. |
2 | 2 |
3 Copyright 2007, 2008, 2009 Free Software Foundation, Inc. | 3 Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
4 Contributed by Aldy Hernandez <aldyh@redhat.com> | 4 Contributed by Aldy Hernandez <aldyh@redhat.com> |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
196 if (retval) | 196 if (retval) |
197 gimple_return_set_retval (s, retval); | 197 gimple_return_set_retval (s, retval); |
198 return s; | 198 return s; |
199 } | 199 } |
200 | 200 |
201 /* Reset alias information on call S. */ | |
202 | |
203 void | |
204 gimple_call_reset_alias_info (gimple s) | |
205 { | |
206 if (gimple_call_flags (s) & ECF_CONST) | |
207 memset (gimple_call_use_set (s), 0, sizeof (struct pt_solution)); | |
208 else | |
209 pt_solution_reset (gimple_call_use_set (s)); | |
210 if (gimple_call_flags (s) & (ECF_CONST|ECF_PURE|ECF_NOVOPS)) | |
211 memset (gimple_call_clobber_set (s), 0, sizeof (struct pt_solution)); | |
212 else | |
213 pt_solution_reset (gimple_call_clobber_set (s)); | |
214 } | |
215 | |
201 /* Helper for gimple_build_call, gimple_build_call_vec and | 216 /* Helper for gimple_build_call, gimple_build_call_vec and |
202 gimple_build_call_from_tree. Build the basic components of a | 217 gimple_build_call_from_tree. Build the basic components of a |
203 GIMPLE_CALL statement to function FN with NARGS arguments. */ | 218 GIMPLE_CALL statement to function FN with NARGS arguments. */ |
204 | 219 |
205 static inline gimple | 220 static inline gimple |
207 { | 222 { |
208 gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3); | 223 gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3); |
209 if (TREE_CODE (fn) == FUNCTION_DECL) | 224 if (TREE_CODE (fn) == FUNCTION_DECL) |
210 fn = build_fold_addr_expr (fn); | 225 fn = build_fold_addr_expr (fn); |
211 gimple_set_op (s, 1, fn); | 226 gimple_set_op (s, 1, fn); |
227 gimple_call_reset_alias_info (s); | |
212 return s; | 228 return s; |
213 } | 229 } |
214 | 230 |
215 | 231 |
216 /* Build a GIMPLE_CALL statement to function FN with the arguments | 232 /* Build a GIMPLE_CALL statement to function FN with the arguments |
279 gimple_call_set_tail (call, CALL_EXPR_TAILCALL (t)); | 295 gimple_call_set_tail (call, CALL_EXPR_TAILCALL (t)); |
280 gimple_call_set_cannot_inline (call, CALL_CANNOT_INLINE_P (t)); | 296 gimple_call_set_cannot_inline (call, CALL_CANNOT_INLINE_P (t)); |
281 gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t)); | 297 gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t)); |
282 gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t)); | 298 gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t)); |
283 gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); | 299 gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); |
300 gimple_call_set_nothrow (call, TREE_NOTHROW (t)); | |
284 gimple_set_no_warning (call, TREE_NO_WARNING (t)); | 301 gimple_set_no_warning (call, TREE_NO_WARNING (t)); |
285 | 302 |
286 return call; | 303 return call; |
287 } | 304 } |
288 | 305 |
618 /* Build a GIMPLE_EH_MUST_NOT_THROW statement. */ | 635 /* Build a GIMPLE_EH_MUST_NOT_THROW statement. */ |
619 | 636 |
620 gimple | 637 gimple |
621 gimple_build_eh_must_not_throw (tree decl) | 638 gimple_build_eh_must_not_throw (tree decl) |
622 { | 639 { |
623 gimple p = gimple_alloc (GIMPLE_EH_MUST_NOT_THROW, 1); | 640 gimple p = gimple_alloc (GIMPLE_EH_MUST_NOT_THROW, 0); |
624 | 641 |
625 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); | 642 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); |
626 gcc_assert (flags_from_decl_or_type (decl) & ECF_NORETURN); | 643 gcc_assert (flags_from_decl_or_type (decl) & ECF_NORETURN); |
627 gimple_eh_must_not_throw_set_fndecl (p, decl); | 644 gimple_eh_must_not_throw_set_fndecl (p, decl); |
628 | 645 |
1295 operands are not scanned. | 1312 operands are not scanned. |
1296 | 1313 |
1297 The return value is that returned by the last call to walk_tree, or | 1314 The return value is that returned by the last call to walk_tree, or |
1298 NULL_TREE if no CALLBACK_OP is specified. */ | 1315 NULL_TREE if no CALLBACK_OP is specified. */ |
1299 | 1316 |
1300 inline tree | 1317 tree |
1301 walk_gimple_op (gimple stmt, walk_tree_fn callback_op, | 1318 walk_gimple_op (gimple stmt, walk_tree_fn callback_op, |
1302 struct walk_stmt_info *wi) | 1319 struct walk_stmt_info *wi) |
1303 { | 1320 { |
1304 struct pointer_set_t *pset = (wi) ? wi->pset : NULL; | 1321 struct pointer_set_t *pset = (wi) ? wi->pset : NULL; |
1305 unsigned i; | 1322 unsigned i; |
1306 tree ret = NULL_TREE; | 1323 tree ret = NULL_TREE; |
1307 | 1324 |
1308 switch (gimple_code (stmt)) | 1325 switch (gimple_code (stmt)) |
1309 { | 1326 { |
1310 case GIMPLE_ASSIGN: | 1327 case GIMPLE_ASSIGN: |
1311 /* Walk the RHS operands. A formal temporary LHS may use a | 1328 /* Walk the RHS operands. If the LHS is of a non-renamable type or |
1312 COMPONENT_REF RHS. */ | 1329 is a register variable, we may use a COMPONENT_REF on the RHS. */ |
1313 if (wi) | 1330 if (wi) |
1314 wi->val_only = !is_gimple_reg (gimple_assign_lhs (stmt)) | 1331 { |
1315 || !gimple_assign_single_p (stmt); | 1332 tree lhs = gimple_assign_lhs (stmt); |
1333 wi->val_only | |
1334 = (is_gimple_reg_type (TREE_TYPE (lhs)) && !is_gimple_reg (lhs)) | |
1335 || !gimple_assign_single_p (stmt); | |
1336 } | |
1316 | 1337 |
1317 for (i = 1; i < gimple_num_ops (stmt); i++) | 1338 for (i = 1; i < gimple_num_ops (stmt); i++) |
1318 { | 1339 { |
1319 ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, | 1340 ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, |
1320 pset); | 1341 pset); |
1731 flags = flags_from_decl_or_type (TREE_TYPE (t)); | 1752 flags = flags_from_decl_or_type (TREE_TYPE (t)); |
1732 else | 1753 else |
1733 flags = 0; | 1754 flags = 0; |
1734 } | 1755 } |
1735 | 1756 |
1757 if (stmt->gsbase.subcode & GF_CALL_NOTHROW) | |
1758 flags |= ECF_NOTHROW; | |
1759 | |
1736 return flags; | 1760 return flags; |
1737 } | 1761 } |
1738 | 1762 |
1763 /* Detects argument flags for argument number ARG on call STMT. */ | |
1764 | |
1765 int | |
1766 gimple_call_arg_flags (const_gimple stmt, unsigned arg) | |
1767 { | |
1768 tree type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt))); | |
1769 tree attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); | |
1770 if (!attr) | |
1771 return 0; | |
1772 | |
1773 attr = TREE_VALUE (TREE_VALUE (attr)); | |
1774 if (1 + arg >= (unsigned) TREE_STRING_LENGTH (attr)) | |
1775 return 0; | |
1776 | |
1777 switch (TREE_STRING_POINTER (attr)[1 + arg]) | |
1778 { | |
1779 case 'x': | |
1780 case 'X': | |
1781 return EAF_UNUSED; | |
1782 | |
1783 case 'R': | |
1784 return EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE; | |
1785 | |
1786 case 'r': | |
1787 return EAF_NOCLOBBER | EAF_NOESCAPE; | |
1788 | |
1789 case 'W': | |
1790 return EAF_DIRECT | EAF_NOESCAPE; | |
1791 | |
1792 case 'w': | |
1793 return EAF_NOESCAPE; | |
1794 | |
1795 case '.': | |
1796 default: | |
1797 return 0; | |
1798 } | |
1799 } | |
1800 | |
1801 /* Detects return flags for the call STMT. */ | |
1802 | |
1803 int | |
1804 gimple_call_return_flags (const_gimple stmt) | |
1805 { | |
1806 tree type; | |
1807 tree attr = NULL_TREE; | |
1808 | |
1809 if (gimple_call_flags (stmt) & ECF_MALLOC) | |
1810 return ERF_NOALIAS; | |
1811 | |
1812 type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt))); | |
1813 attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); | |
1814 if (!attr) | |
1815 return 0; | |
1816 | |
1817 attr = TREE_VALUE (TREE_VALUE (attr)); | |
1818 if (TREE_STRING_LENGTH (attr) < 1) | |
1819 return 0; | |
1820 | |
1821 switch (TREE_STRING_POINTER (attr)[0]) | |
1822 { | |
1823 case '1': | |
1824 case '2': | |
1825 case '3': | |
1826 case '4': | |
1827 return ERF_RETURNS_ARG | (TREE_STRING_POINTER (attr)[0] - '1'); | |
1828 | |
1829 case 'm': | |
1830 return ERF_NOALIAS; | |
1831 | |
1832 case '.': | |
1833 default: | |
1834 return 0; | |
1835 } | |
1836 } | |
1739 | 1837 |
1740 /* Return true if GS is a copy assignment. */ | 1838 /* Return true if GS is a copy assignment. */ |
1741 | 1839 |
1742 bool | 1840 bool |
1743 gimple_assign_copy_p (gimple gs) | 1841 gimple_assign_copy_p (gimple gs) |
1830 } | 1928 } |
1831 } | 1929 } |
1832 | 1930 |
1833 VEC_replace (basic_block, label_to_block_map, uid, bb); | 1931 VEC_replace (basic_block, label_to_block_map, uid, bb); |
1834 } | 1932 } |
1835 } | |
1836 | |
1837 | |
1838 /* Fold the expression computed by STMT. If the expression can be | |
1839 folded, return the folded result, otherwise return NULL. STMT is | |
1840 not modified. */ | |
1841 | |
1842 tree | |
1843 gimple_fold (const_gimple stmt) | |
1844 { | |
1845 location_t loc = gimple_location (stmt); | |
1846 switch (gimple_code (stmt)) | |
1847 { | |
1848 case GIMPLE_COND: | |
1849 return fold_binary_loc (loc, gimple_cond_code (stmt), | |
1850 boolean_type_node, | |
1851 gimple_cond_lhs (stmt), | |
1852 gimple_cond_rhs (stmt)); | |
1853 | |
1854 case GIMPLE_ASSIGN: | |
1855 switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))) | |
1856 { | |
1857 case GIMPLE_UNARY_RHS: | |
1858 return fold_unary_loc (loc, gimple_assign_rhs_code (stmt), | |
1859 TREE_TYPE (gimple_assign_lhs (stmt)), | |
1860 gimple_assign_rhs1 (stmt)); | |
1861 case GIMPLE_BINARY_RHS: | |
1862 return fold_binary_loc (loc, gimple_assign_rhs_code (stmt), | |
1863 TREE_TYPE (gimple_assign_lhs (stmt)), | |
1864 gimple_assign_rhs1 (stmt), | |
1865 gimple_assign_rhs2 (stmt)); | |
1866 case GIMPLE_SINGLE_RHS: | |
1867 return fold (gimple_assign_rhs1 (stmt)); | |
1868 default:; | |
1869 } | |
1870 break; | |
1871 | |
1872 case GIMPLE_SWITCH: | |
1873 return gimple_switch_index (stmt); | |
1874 | |
1875 case GIMPLE_CALL: | |
1876 return NULL_TREE; | |
1877 | |
1878 default: | |
1879 break; | |
1880 } | |
1881 | |
1882 gcc_unreachable (); | |
1883 } | 1933 } |
1884 | 1934 |
1885 | 1935 |
1886 /* Modify the RHS of the assignment pointed-to by GSI using the | 1936 /* Modify the RHS of the assignment pointed-to by GSI using the |
1887 operands in the expression tree EXPR. | 1937 operands in the expression tree EXPR. |
3167 return true; | 3217 return true; |
3168 | 3218 |
3169 return false; | 3219 return false; |
3170 } | 3220 } |
3171 | 3221 |
3172 /* Return true if the field decls F1 and F2 are at the same offset. */ | 3222 /* Return true if the field decls F1 and F2 are at the same offset. |
3223 | |
3224 This is intended to be used on GIMPLE types only. In order to | |
3225 compare GENERIC types, use fields_compatible_p instead. */ | |
3173 | 3226 |
3174 bool | 3227 bool |
3175 compare_field_offset (tree f1, tree f2) | 3228 gimple_compare_field_offset (tree f1, tree f2) |
3176 { | 3229 { |
3177 if (DECL_OFFSET_ALIGN (f1) == DECL_OFFSET_ALIGN (f2)) | 3230 if (DECL_OFFSET_ALIGN (f1) == DECL_OFFSET_ALIGN (f2)) |
3178 return (operand_equal_p (DECL_FIELD_OFFSET (f1), | 3231 { |
3179 DECL_FIELD_OFFSET (f2), 0) | 3232 tree offset1 = DECL_FIELD_OFFSET (f1); |
3180 && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (f1), | 3233 tree offset2 = DECL_FIELD_OFFSET (f2); |
3181 DECL_FIELD_BIT_OFFSET (f2))); | 3234 return ((offset1 == offset2 |
3235 /* Once gimplification is done, self-referential offsets are | |
3236 instantiated as operand #2 of the COMPONENT_REF built for | |
3237 each access and reset. Therefore, they are not relevant | |
3238 anymore and fields are interchangeable provided that they | |
3239 represent the same access. */ | |
3240 || (TREE_CODE (offset1) == PLACEHOLDER_EXPR | |
3241 && TREE_CODE (offset2) == PLACEHOLDER_EXPR | |
3242 && (DECL_SIZE (f1) == DECL_SIZE (f2) | |
3243 || (TREE_CODE (DECL_SIZE (f1)) == PLACEHOLDER_EXPR | |
3244 && TREE_CODE (DECL_SIZE (f2)) == PLACEHOLDER_EXPR) | |
3245 || operand_equal_p (DECL_SIZE (f1), DECL_SIZE (f2), 0)) | |
3246 && DECL_ALIGN (f1) == DECL_ALIGN (f2)) | |
3247 || operand_equal_p (offset1, offset2, 0)) | |
3248 && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (f1), | |
3249 DECL_FIELD_BIT_OFFSET (f2))); | |
3250 } | |
3182 | 3251 |
3183 /* Fortran and C do not always agree on what DECL_OFFSET_ALIGN | 3252 /* Fortran and C do not always agree on what DECL_OFFSET_ALIGN |
3184 should be, so handle differing ones specially by decomposing | 3253 should be, so handle differing ones specially by decomposing |
3185 the offset into a byte and bit offset manually. */ | 3254 the offset into a byte and bit offset manually. */ |
3186 if (host_integerp (DECL_FIELD_OFFSET (f1), 0) | 3255 if (host_integerp (DECL_FIELD_OFFSET (f1), 0) |
3331 tree max1 = TYPE_MAX_VALUE (i1); | 3400 tree max1 = TYPE_MAX_VALUE (i1); |
3332 tree max2 = TYPE_MAX_VALUE (i2); | 3401 tree max2 = TYPE_MAX_VALUE (i2); |
3333 | 3402 |
3334 /* The minimum/maximum values have to be the same. */ | 3403 /* The minimum/maximum values have to be the same. */ |
3335 if ((min1 == min2 | 3404 if ((min1 == min2 |
3336 || (min1 && min2 && operand_equal_p (min1, min2, 0))) | 3405 || (min1 && min2 |
3406 && ((TREE_CODE (min1) == PLACEHOLDER_EXPR | |
3407 && TREE_CODE (min2) == PLACEHOLDER_EXPR) | |
3408 || operand_equal_p (min1, min2, 0)))) | |
3337 && (max1 == max2 | 3409 && (max1 == max2 |
3338 || (max1 && max2 && operand_equal_p (max1, max2, 0)))) | 3410 || (max1 && max2 |
3411 && ((TREE_CODE (max1) == PLACEHOLDER_EXPR | |
3412 && TREE_CODE (max2) == PLACEHOLDER_EXPR) | |
3413 || operand_equal_p (max1, max2, 0))))) | |
3339 goto same_types; | 3414 goto same_types; |
3340 else | 3415 else |
3341 goto different_types; | 3416 goto different_types; |
3342 } | 3417 } |
3343 } | 3418 } |
3404 the other pointed-to type they are the same. */ | 3479 the other pointed-to type they are the same. */ |
3405 if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)) | 3480 if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)) |
3406 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t1)) | 3481 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t1)) |
3407 && (!COMPLETE_TYPE_P (TREE_TYPE (t1)) | 3482 && (!COMPLETE_TYPE_P (TREE_TYPE (t1)) |
3408 || !COMPLETE_TYPE_P (TREE_TYPE (t2))) | 3483 || !COMPLETE_TYPE_P (TREE_TYPE (t2))) |
3484 && TYPE_QUALS (TREE_TYPE (t1)) == TYPE_QUALS (TREE_TYPE (t2)) | |
3409 && compare_type_names_p (TYPE_MAIN_VARIANT (TREE_TYPE (t1)), | 3485 && compare_type_names_p (TYPE_MAIN_VARIANT (TREE_TYPE (t1)), |
3410 TYPE_MAIN_VARIANT (TREE_TYPE (t2)), true)) | 3486 TYPE_MAIN_VARIANT (TREE_TYPE (t2)), true)) |
3411 { | 3487 { |
3412 /* Replace the pointed-to incomplete type with the | 3488 /* Replace the pointed-to incomplete type with the |
3413 complete one. */ | 3489 complete one. |
3490 ??? This simple name-based merging causes at least some | |
3491 of the ICEs in canonicalizing FIELD_DECLs during stmt | |
3492 read. For example in GCC we have two different struct deps | |
3493 and we mismatch the use in struct cpp_reader in sched-int.h | |
3494 vs. mkdeps.c. Of course the whole exercise is for TBAA | |
3495 with structs which contain pointers to incomplete types | |
3496 in one unit and to complete ones in another. So we | |
3497 probably should merge these types only with more context. */ | |
3414 if (COMPLETE_TYPE_P (TREE_TYPE (t2))) | 3498 if (COMPLETE_TYPE_P (TREE_TYPE (t2))) |
3415 TREE_TYPE (t1) = TREE_TYPE (t2); | 3499 TREE_TYPE (t1) = TREE_TYPE (t2); |
3416 else | 3500 else |
3417 TREE_TYPE (t2) = TREE_TYPE (t1); | 3501 TREE_TYPE (t2) = TREE_TYPE (t1); |
3418 goto same_types; | 3502 goto same_types; |
3518 f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) | 3602 f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) |
3519 { | 3603 { |
3520 /* The fields must have the same name, offset and type. */ | 3604 /* The fields must have the same name, offset and type. */ |
3521 if (DECL_NAME (f1) != DECL_NAME (f2) | 3605 if (DECL_NAME (f1) != DECL_NAME (f2) |
3522 || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) | 3606 || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) |
3523 || !compare_field_offset (f1, f2) | 3607 || !gimple_compare_field_offset (f1, f2) |
3524 || !gimple_types_compatible_p (TREE_TYPE (f1), | 3608 || !gimple_types_compatible_p (TREE_TYPE (f1), |
3525 TREE_TYPE (f2))) | 3609 TREE_TYPE (f2))) |
3526 goto different_types; | 3610 goto different_types; |
3527 } | 3611 } |
3528 | 3612 |
3705 } | 3789 } |
3706 | 3790 |
3707 /* For integer types hash the types min/max values and the string flag. */ | 3791 /* For integer types hash the types min/max values and the string flag. */ |
3708 if (TREE_CODE (type) == INTEGER_TYPE) | 3792 if (TREE_CODE (type) == INTEGER_TYPE) |
3709 { | 3793 { |
3710 v = iterative_hash_expr (TYPE_MIN_VALUE (type), v); | 3794 /* OMP lowering can introduce error_mark_node in place of |
3711 v = iterative_hash_expr (TYPE_MAX_VALUE (type), v); | 3795 random local decls in types. */ |
3796 if (TYPE_MIN_VALUE (type) != error_mark_node) | |
3797 v = iterative_hash_expr (TYPE_MIN_VALUE (type), v); | |
3798 if (TYPE_MAX_VALUE (type) != error_mark_node) | |
3799 v = iterative_hash_expr (TYPE_MAX_VALUE (type), v); | |
3712 v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v); | 3800 v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v); |
3713 } | 3801 } |
3714 | 3802 |
3715 /* For array types hash their domain and the string flag. */ | 3803 /* For array types hash their domain and the string flag. */ |
3716 if (TREE_CODE (type) == ARRAY_TYPE | 3804 if (TREE_CODE (type) == ARRAY_TYPE |
4574 static bool | 4662 static bool |
4575 gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED, | 4663 gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED, |
4576 tree addr, void *data) | 4664 tree addr, void *data) |
4577 { | 4665 { |
4578 bitmap addresses_taken = (bitmap)data; | 4666 bitmap addresses_taken = (bitmap)data; |
4579 while (handled_component_p (addr)) | 4667 addr = get_base_address (addr); |
4580 addr = TREE_OPERAND (addr, 0); | 4668 if (addr |
4581 if (DECL_P (addr)) | 4669 && DECL_P (addr)) |
4582 { | 4670 { |
4583 bitmap_set_bit (addresses_taken, DECL_UID (addr)); | 4671 bitmap_set_bit (addresses_taken, DECL_UID (addr)); |
4584 return true; | 4672 return true; |
4585 } | 4673 } |
4586 return false; | 4674 return false; |
4601 /* Return a printable name for symbol DECL. */ | 4689 /* Return a printable name for symbol DECL. */ |
4602 | 4690 |
4603 const char * | 4691 const char * |
4604 gimple_decl_printable_name (tree decl, int verbosity) | 4692 gimple_decl_printable_name (tree decl, int verbosity) |
4605 { | 4693 { |
4606 gcc_assert (decl && DECL_NAME (decl)); | 4694 if (!DECL_NAME (decl)) |
4695 return NULL; | |
4607 | 4696 |
4608 if (DECL_ASSEMBLER_NAME_SET_P (decl)) | 4697 if (DECL_ASSEMBLER_NAME_SET_P (decl)) |
4609 { | 4698 { |
4610 const char *str, *mangled_str; | 4699 const char *str, *mangled_str; |
4611 int dmgl_opts = DMGL_NO_OPTS; | 4700 int dmgl_opts = DMGL_NO_OPTS; |
4626 } | 4715 } |
4627 | 4716 |
4628 return IDENTIFIER_POINTER (DECL_NAME (decl)); | 4717 return IDENTIFIER_POINTER (DECL_NAME (decl)); |
4629 } | 4718 } |
4630 | 4719 |
4631 | |
4632 /* Fold a OBJ_TYPE_REF expression to the address of a function. | |
4633 KNOWN_TYPE carries the true type of OBJ_TYPE_REF_OBJECT(REF). Adapted | |
4634 from cp_fold_obj_type_ref, but it tolerates types with no binfo | |
4635 data. */ | |
4636 | |
4637 tree | |
4638 gimple_fold_obj_type_ref (tree ref, tree known_type) | |
4639 { | |
4640 HOST_WIDE_INT index; | |
4641 HOST_WIDE_INT i; | |
4642 tree v; | |
4643 tree fndecl; | |
4644 | |
4645 if (TYPE_BINFO (known_type) == NULL_TREE) | |
4646 return NULL_TREE; | |
4647 | |
4648 v = BINFO_VIRTUALS (TYPE_BINFO (known_type)); | |
4649 index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); | |
4650 i = 0; | |
4651 while (i != index) | |
4652 { | |
4653 i += (TARGET_VTABLE_USES_DESCRIPTORS | |
4654 ? TARGET_VTABLE_USES_DESCRIPTORS : 1); | |
4655 v = TREE_CHAIN (v); | |
4656 } | |
4657 | |
4658 fndecl = TREE_VALUE (v); | |
4659 | |
4660 #ifdef ENABLE_CHECKING | |
4661 gcc_assert (tree_int_cst_equal (OBJ_TYPE_REF_TOKEN (ref), | |
4662 DECL_VINDEX (fndecl))); | |
4663 #endif | |
4664 | |
4665 cgraph_node (fndecl)->local.vtable_method = true; | |
4666 | |
4667 return build_fold_addr_expr (fndecl); | |
4668 } | |
4669 | |
4670 #include "gt-gimple.h" | 4720 #include "gt-gimple.h" |