comparison gcc/ipa-polymorphic-call.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
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