Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-polymorphic-call.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
1 /* Analysis of polymorphic call context. | 1 /* Analysis of polymorphic call context. |
2 Copyright (C) 2013-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2013-2018 Free Software Foundation, Inc. |
3 Contributed by Jan Hubicka | 3 Contributed by Jan Hubicka |
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 under | 7 GCC is free software; you can redistribute it and/or modify it under |
757 bool | 757 bool |
758 ipa_polymorphic_call_context::set_by_invariant (tree cst, | 758 ipa_polymorphic_call_context::set_by_invariant (tree cst, |
759 tree otr_type, | 759 tree otr_type, |
760 HOST_WIDE_INT off) | 760 HOST_WIDE_INT off) |
761 { | 761 { |
762 HOST_WIDE_INT offset2, size, max_size; | 762 poly_int64 offset2, size, max_size; |
763 bool reverse; | 763 bool reverse; |
764 tree base; | 764 tree base; |
765 | 765 |
766 invalid = false; | 766 invalid = false; |
767 off = 0; | 767 off = 0; |
770 if (TREE_CODE (cst) != ADDR_EXPR) | 770 if (TREE_CODE (cst) != ADDR_EXPR) |
771 return false; | 771 return false; |
772 | 772 |
773 cst = TREE_OPERAND (cst, 0); | 773 cst = TREE_OPERAND (cst, 0); |
774 base = get_ref_base_and_extent (cst, &offset2, &size, &max_size, &reverse); | 774 base = get_ref_base_and_extent (cst, &offset2, &size, &max_size, &reverse); |
775 if (!DECL_P (base) || max_size == -1 || max_size != size) | 775 if (!DECL_P (base) || !known_size_p (max_size) || maybe_ne (max_size, size)) |
776 return false; | 776 return false; |
777 | 777 |
778 /* Only type inconsistent programs can have otr_type that is | 778 /* Only type inconsistent programs can have otr_type that is |
779 not part of outer type. */ | 779 not part of outer type. */ |
780 if (otr_type && !contains_type_p (TREE_TYPE (base), off, otr_type)) | 780 if (otr_type && !contains_type_p (TREE_TYPE (base), off, otr_type)) |
897 while (true) | 897 while (true) |
898 { | 898 { |
899 base_pointer = walk_ssa_copies (base_pointer, &visited); | 899 base_pointer = walk_ssa_copies (base_pointer, &visited); |
900 if (TREE_CODE (base_pointer) == ADDR_EXPR) | 900 if (TREE_CODE (base_pointer) == ADDR_EXPR) |
901 { | 901 { |
902 HOST_WIDE_INT size, max_size; | 902 HOST_WIDE_INT offset2, size; |
903 HOST_WIDE_INT offset2; | |
904 bool reverse; | 903 bool reverse; |
905 tree base | 904 tree base |
906 = get_ref_base_and_extent (TREE_OPERAND (base_pointer, 0), | 905 = get_ref_base_and_extent_hwi (TREE_OPERAND (base_pointer, 0), |
907 &offset2, &size, &max_size, &reverse); | 906 &offset2, &size, &reverse); |
908 | 907 if (!base) |
909 if (max_size != -1 && max_size == size) | 908 break; |
910 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)), | 909 |
911 offset + offset2, | 910 combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base)), |
912 true, | 911 offset + offset2, |
913 NULL /* Do not change outer type. */); | 912 true, |
913 NULL /* Do not change outer type. */); | |
914 | 914 |
915 /* If this is a varying address, punt. */ | 915 /* If this is a varying address, punt. */ |
916 if ((TREE_CODE (base) == MEM_REF || DECL_P (base)) | 916 if (TREE_CODE (base) == MEM_REF || DECL_P (base)) |
917 && max_size != -1 | |
918 && max_size == size) | |
919 { | 917 { |
920 /* We found dereference of a pointer. Type of the pointer | 918 /* We found dereference of a pointer. Type of the pointer |
921 and MEM_REF is meaningless, but we can look futher. */ | 919 and MEM_REF is meaningless, but we can look futher. */ |
922 if (TREE_CODE (base) == MEM_REF) | 920 offset_int mem_offset; |
921 if (TREE_CODE (base) == MEM_REF | |
922 && mem_ref_offset (base).is_constant (&mem_offset)) | |
923 { | 923 { |
924 offset_int o = mem_ref_offset (base) * BITS_PER_UNIT; | 924 offset_int o = mem_offset * BITS_PER_UNIT; |
925 o += offset; | 925 o += offset; |
926 o += offset2; | 926 o += offset2; |
927 if (!wi::fits_shwi_p (o)) | 927 if (!wi::fits_shwi_p (o)) |
928 break; | 928 break; |
929 base_pointer = TREE_OPERAND (base, 0); | 929 base_pointer = TREE_OPERAND (base, 0); |
1147 return false; | 1147 return false; |
1148 | 1148 |
1149 if (TREE_CODE (lhs) == COMPONENT_REF | 1149 if (TREE_CODE (lhs) == COMPONENT_REF |
1150 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1))) | 1150 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1))) |
1151 return false; | 1151 return false; |
1152 /* In the future we might want to use get_base_ref_and_offset to find | 1152 /* In the future we might want to use get_ref_base_and_extent to find |
1153 if there is a field corresponding to the offset and if so, proceed | 1153 if there is a field corresponding to the offset and if so, proceed |
1154 almost like if it was a component ref. */ | 1154 almost like if it was a component ref. */ |
1155 } | 1155 } |
1156 } | 1156 } |
1157 | 1157 |
1179 | 1179 |
1180 static tree | 1180 static tree |
1181 extr_type_from_vtbl_ptr_store (gimple *stmt, struct type_change_info *tci, | 1181 extr_type_from_vtbl_ptr_store (gimple *stmt, struct type_change_info *tci, |
1182 HOST_WIDE_INT *type_offset) | 1182 HOST_WIDE_INT *type_offset) |
1183 { | 1183 { |
1184 HOST_WIDE_INT offset, size, max_size; | 1184 poly_int64 offset, size, max_size; |
1185 tree lhs, rhs, base; | 1185 tree lhs, rhs, base; |
1186 bool reverse; | 1186 bool reverse; |
1187 | 1187 |
1188 if (!gimple_assign_single_p (stmt)) | 1188 if (!gimple_assign_single_p (stmt)) |
1189 return NULL_TREE; | 1189 return NULL_TREE; |
1261 print_generic_expr (dump_file, tci->instance, TDF_SLIM); | 1261 print_generic_expr (dump_file, tci->instance, TDF_SLIM); |
1262 fprintf (dump_file, " with offset %i\n", (int)tci->offset); | 1262 fprintf (dump_file, " with offset %i\n", (int)tci->offset); |
1263 } | 1263 } |
1264 return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE; | 1264 return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE; |
1265 } | 1265 } |
1266 if (offset != tci->offset | 1266 if (maybe_ne (offset, tci->offset) |
1267 || size != POINTER_SIZE | 1267 || maybe_ne (size, POINTER_SIZE) |
1268 || max_size != POINTER_SIZE) | 1268 || maybe_ne (max_size, POINTER_SIZE)) |
1269 { | 1269 { |
1270 if (dump_file) | 1270 if (dump_file) |
1271 fprintf (dump_file, " wrong offset %i!=%i or size %i\n", | 1271 { |
1272 (int)offset, (int)tci->offset, (int)size); | 1272 fprintf (dump_file, " wrong offset "); |
1273 return offset + POINTER_SIZE <= tci->offset | 1273 print_dec (offset, dump_file); |
1274 || (max_size != -1 | 1274 fprintf (dump_file, "!=%i or size ", (int) tci->offset); |
1275 && tci->offset + POINTER_SIZE > offset + max_size) | 1275 print_dec (size, dump_file); |
1276 ? error_mark_node : NULL; | 1276 fprintf (dump_file, "\n"); |
1277 } | |
1278 return (known_le (offset + POINTER_SIZE, tci->offset) | |
1279 || (known_size_p (max_size) | |
1280 && known_gt (tci->offset + POINTER_SIZE, | |
1281 offset + max_size)) | |
1282 ? error_mark_node : NULL); | |
1277 } | 1283 } |
1278 } | 1284 } |
1279 | 1285 |
1280 tree vtable; | 1286 tree vtable; |
1281 unsigned HOST_WIDE_INT offset2; | 1287 unsigned HOST_WIDE_INT offset2; |
1401 && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE | 1407 && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE |
1402 && gimple_call_num_args (stmt)) | 1408 && gimple_call_num_args (stmt)) |
1403 { | 1409 { |
1404 tree op = walk_ssa_copies (gimple_call_arg (stmt, 0)); | 1410 tree op = walk_ssa_copies (gimple_call_arg (stmt, 0)); |
1405 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); | 1411 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); |
1406 HOST_WIDE_INT offset = 0, size, max_size; | 1412 HOST_WIDE_INT offset = 0; |
1407 bool reverse; | 1413 bool reverse; |
1408 | 1414 |
1409 if (dump_file) | 1415 if (dump_file) |
1410 { | 1416 { |
1411 fprintf (dump_file, " Checking constructor call: "); | 1417 fprintf (dump_file, " Checking constructor call: "); |
1413 } | 1419 } |
1414 | 1420 |
1415 /* See if THIS parameter seems like instance pointer. */ | 1421 /* See if THIS parameter seems like instance pointer. */ |
1416 if (TREE_CODE (op) == ADDR_EXPR) | 1422 if (TREE_CODE (op) == ADDR_EXPR) |
1417 { | 1423 { |
1418 op = get_ref_base_and_extent (TREE_OPERAND (op, 0), &offset, | 1424 HOST_WIDE_INT size; |
1419 &size, &max_size, &reverse); | 1425 op = get_ref_base_and_extent_hwi (TREE_OPERAND (op, 0), |
1420 if (size != max_size || max_size == -1) | 1426 &offset, &size, &reverse); |
1427 if (!op) | |
1421 { | 1428 { |
1422 tci->speculative++; | 1429 tci->speculative++; |
1423 return csftc_abort_walking_p (tci->speculative); | 1430 return csftc_abort_walking_p (tci->speculative); |
1424 } | 1431 } |
1425 if (op && TREE_CODE (op) == MEM_REF) | 1432 if (TREE_CODE (op) == MEM_REF) |
1426 { | 1433 { |
1427 if (!tree_fits_shwi_p (TREE_OPERAND (op, 1))) | 1434 if (!tree_fits_shwi_p (TREE_OPERAND (op, 1))) |
1428 { | 1435 { |
1429 tci->speculative++; | 1436 tci->speculative++; |
1430 return csftc_abort_walking_p (tci->speculative); | 1437 return csftc_abort_walking_p (tci->speculative); |
1576 load around. */ | 1583 load around. */ |
1577 | 1584 |
1578 if (gimple_code (call) == GIMPLE_CALL) | 1585 if (gimple_code (call) == GIMPLE_CALL) |
1579 { | 1586 { |
1580 tree ref = gimple_call_fn (call); | 1587 tree ref = gimple_call_fn (call); |
1581 HOST_WIDE_INT offset2, size, max_size; | |
1582 bool reverse; | 1588 bool reverse; |
1583 | 1589 |
1584 if (TREE_CODE (ref) == OBJ_TYPE_REF) | 1590 if (TREE_CODE (ref) == OBJ_TYPE_REF) |
1585 { | 1591 { |
1586 ref = OBJ_TYPE_REF_EXPR (ref); | 1592 ref = OBJ_TYPE_REF_EXPR (ref); |
1606 vptr load. */ | 1612 vptr load. */ |
1607 if (TREE_CODE (ref) == SSA_NAME | 1613 if (TREE_CODE (ref) == SSA_NAME |
1608 && !SSA_NAME_IS_DEFAULT_DEF (ref) | 1614 && !SSA_NAME_IS_DEFAULT_DEF (ref) |
1609 && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref))) | 1615 && gimple_assign_load_p (SSA_NAME_DEF_STMT (ref))) |
1610 { | 1616 { |
1617 HOST_WIDE_INT offset2, size; | |
1611 tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref)); | 1618 tree ref_exp = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (ref)); |
1612 tree base_ref | 1619 tree base_ref |
1613 = get_ref_base_and_extent (ref_exp, &offset2, &size, | 1620 = get_ref_base_and_extent_hwi (ref_exp, &offset2, |
1614 &max_size, &reverse); | 1621 &size, &reverse); |
1615 | 1622 |
1616 /* Finally verify that what we found looks like read from | 1623 /* Finally verify that what we found looks like read from |
1617 OTR_OBJECT or from INSTANCE with offset OFFSET. */ | 1624 OTR_OBJECT or from INSTANCE with offset OFFSET. */ |
1618 if (base_ref | 1625 if (base_ref |
1619 && ((TREE_CODE (base_ref) == MEM_REF | 1626 && ((TREE_CODE (base_ref) == MEM_REF |