comparison gcc/tree-ssa-loop-ivopts.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 /* Induction variable optimizations. 1 /* Induction variable optimizations.
2 Copyright (C) 2003-2017 Free Software Foundation, Inc. 2 Copyright (C) 2003-2018 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it 6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 7 under the terms of the GNU General Public License as published by the
164 164
165 /* Types of uses. */ 165 /* Types of uses. */
166 enum use_type 166 enum use_type
167 { 167 {
168 USE_NONLINEAR_EXPR, /* Use in a nonlinear expression. */ 168 USE_NONLINEAR_EXPR, /* Use in a nonlinear expression. */
169 USE_ADDRESS, /* Use in an address. */ 169 USE_REF_ADDRESS, /* Use is an address for an explicit memory
170 reference. */
171 USE_PTR_ADDRESS, /* Use is a pointer argument to a function in
172 cases where the expansion of the function
173 will turn the argument into a normal address. */
170 USE_COMPARE /* Use is a compare. */ 174 USE_COMPARE /* Use is a compare. */
171 }; 175 };
172 176
173 /* Cost of a computation. */ 177 /* Cost of a computation. */
174 struct comp_cost 178 struct comp_cost
360 struct iv_use 364 struct iv_use
361 { 365 {
362 unsigned id; /* The id of the use. */ 366 unsigned id; /* The id of the use. */
363 unsigned group_id; /* The group id the use belongs to. */ 367 unsigned group_id; /* The group id the use belongs to. */
364 enum use_type type; /* Type of the use. */ 368 enum use_type type; /* Type of the use. */
369 tree mem_type; /* The memory type to use when testing whether an
370 address is legitimate, and what the address's
371 cost is. */
365 struct iv *iv; /* The induction variable it is based on. */ 372 struct iv *iv; /* The induction variable it is based on. */
366 gimple *stmt; /* Statement in that it occurs. */ 373 gimple *stmt; /* Statement in that it occurs. */
367 tree *op_p; /* The place where it occurs. */ 374 tree *op_p; /* The place where it occurs. */
368 375
369 tree addr_base; /* Base address with const offset stripped. */ 376 tree addr_base; /* Base address with const offset stripped. */
370 unsigned HOST_WIDE_INT addr_offset; 377 poly_uint64_pod addr_offset;
371 /* Const offset stripped from base address. */ 378 /* Const offset stripped from base address. */
372 }; 379 };
373 380
374 /* Group of uses. */ 381 /* Group of uses. */
375 struct iv_group 382 struct iv_group
504 { 511 {
505 static inline hashval_t hash (const iv_inv_expr_ent *); 512 static inline hashval_t hash (const iv_inv_expr_ent *);
506 static inline bool equal (const iv_inv_expr_ent *, const iv_inv_expr_ent *); 513 static inline bool equal (const iv_inv_expr_ent *, const iv_inv_expr_ent *);
507 }; 514 };
508 515
516 /* Return true if uses of type TYPE represent some form of address. */
517
518 inline bool
519 address_p (use_type type)
520 {
521 return type == USE_REF_ADDRESS || type == USE_PTR_ADDRESS;
522 }
523
509 /* Hash function for loop invariant expressions. */ 524 /* Hash function for loop invariant expressions. */
510 525
511 inline hashval_t 526 inline hashval_t
512 iv_inv_expr_hasher::hash (const iv_inv_expr_ent *expr) 527 iv_inv_expr_hasher::hash (const iv_inv_expr_ent *expr)
513 { 528 {
766 { 781 {
767 group = data->vgroups[i]; 782 group = data->vgroups[i];
768 fprintf (file, "Group %d:\n", group->id); 783 fprintf (file, "Group %d:\n", group->id);
769 if (group->type == USE_NONLINEAR_EXPR) 784 if (group->type == USE_NONLINEAR_EXPR)
770 fprintf (file, " Type:\tGENERIC\n"); 785 fprintf (file, " Type:\tGENERIC\n");
771 else if (group->type == USE_ADDRESS) 786 else if (group->type == USE_REF_ADDRESS)
772 fprintf (file, " Type:\tADDRESS\n"); 787 fprintf (file, " Type:\tREFERENCE ADDRESS\n");
788 else if (group->type == USE_PTR_ADDRESS)
789 fprintf (file, " Type:\tPOINTER ARGUMENT ADDRESS\n");
773 else 790 else
774 { 791 {
775 gcc_assert (group->type == USE_COMPARE); 792 gcc_assert (group->type == USE_COMPARE);
776 fprintf (file, " Type:\tCOMPARE\n"); 793 fprintf (file, " Type:\tCOMPARE\n");
777 } 794 }
965 if (!expr) 982 if (!expr)
966 return false; 983 return false;
967 984
968 code = TREE_CODE (expr); 985 code = TREE_CODE (expr);
969 codeclass = TREE_CODE_CLASS (code); 986 codeclass = TREE_CODE_CLASS (code);
987
988 if (code == CALL_EXPR)
989 {
990 tree arg;
991 call_expr_arg_iterator iter;
992 FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
993 if (contains_abnormal_ssa_name_p (arg))
994 return true;
995 return false;
996 }
970 997
971 if (code == SSA_NAME) 998 if (code == SSA_NAME)
972 return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr) != 0; 999 return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr) != 0;
973 1000
974 if (code == INTEGER_CST 1001 if (code == INTEGER_CST
1125 case MINUS_EXPR: 1152 case MINUS_EXPR:
1126 /* Pointer addition is done solely using POINTER_PLUS_EXPR. */ 1153 /* Pointer addition is done solely using POINTER_PLUS_EXPR. */
1127 gcc_unreachable (); 1154 gcc_unreachable ();
1128 1155
1129 default: 1156 default:
1157 if (POLY_INT_CST_P (expr))
1158 return NULL_TREE;
1130 return fold_convert (ptr_type_node, expr); 1159 return fold_convert (ptr_type_node, expr);
1131 } 1160 }
1132 } 1161 }
1133 1162
1134 /* Return true if address expression with non-DECL_P operand appears 1163 /* Return true if address expression with non-DECL_P operand appears
1409 return false; 1438 return false;
1410 1439
1411 /* If STMT could throw, then do not consider STMT as defining a GIV. 1440 /* If STMT could throw, then do not consider STMT as defining a GIV.
1412 While this will suppress optimizations, we can not safely delete this 1441 While this will suppress optimizations, we can not safely delete this
1413 GIV and associated statements, even if it appears it is not used. */ 1442 GIV and associated statements, even if it appears it is not used. */
1414 if (stmt_could_throw_p (stmt)) 1443 if (stmt_could_throw_p (cfun, stmt))
1415 return false; 1444 return false;
1416 1445
1417 return true; 1446 return true;
1418 } 1447 }
1419 1448
1498 return true; 1527 return true;
1499 } 1528 }
1500 1529
1501 /* Records a use of TYPE at *USE_P in STMT whose value is IV in GROUP. 1530 /* Records a use of TYPE at *USE_P in STMT whose value is IV in GROUP.
1502 For address type use, ADDR_BASE is the stripped IV base, ADDR_OFFSET 1531 For address type use, ADDR_BASE is the stripped IV base, ADDR_OFFSET
1503 is the const offset stripped from IV base; for other types use, both 1532 is the const offset stripped from IV base and MEM_TYPE is the type
1504 are zero by default. */ 1533 of the memory being addressed. For uses of other types, ADDR_BASE
1534 and ADDR_OFFSET are zero by default and MEM_TYPE is NULL_TREE. */
1505 1535
1506 static struct iv_use * 1536 static struct iv_use *
1507 record_use (struct iv_group *group, tree *use_p, struct iv *iv, 1537 record_use (struct iv_group *group, tree *use_p, struct iv *iv,
1508 gimple *stmt, enum use_type type, tree addr_base, 1538 gimple *stmt, enum use_type type, tree mem_type,
1509 unsigned HOST_WIDE_INT addr_offset) 1539 tree addr_base, poly_uint64 addr_offset)
1510 { 1540 {
1511 struct iv_use *use = XCNEW (struct iv_use); 1541 struct iv_use *use = XCNEW (struct iv_use);
1512 1542
1513 use->id = group->vuses.length (); 1543 use->id = group->vuses.length ();
1514 use->group_id = group->id; 1544 use->group_id = group->id;
1515 use->type = type; 1545 use->type = type;
1546 use->mem_type = mem_type;
1516 use->iv = iv; 1547 use->iv = iv;
1517 use->stmt = stmt; 1548 use->stmt = stmt;
1518 use->op_p = use_p; 1549 use->op_p = use_p;
1519 use->addr_base = addr_base; 1550 use->addr_base = addr_base;
1520 use->addr_offset = addr_offset; 1551 use->addr_offset = addr_offset;
1565 data->vgroups.safe_push (group); 1596 data->vgroups.safe_push (group);
1566 return group; 1597 return group;
1567 } 1598 }
1568 1599
1569 /* Record a use of TYPE at *USE_P in STMT whose value is IV in a group. 1600 /* Record a use of TYPE at *USE_P in STMT whose value is IV in a group.
1570 New group will be created if there is no existing group for the use. */ 1601 New group will be created if there is no existing group for the use.
1602 MEM_TYPE is the type of memory being addressed, or NULL if this
1603 isn't an address reference. */
1571 1604
1572 static struct iv_use * 1605 static struct iv_use *
1573 record_group_use (struct ivopts_data *data, tree *use_p, 1606 record_group_use (struct ivopts_data *data, tree *use_p,
1574 struct iv *iv, gimple *stmt, enum use_type type) 1607 struct iv *iv, gimple *stmt, enum use_type type,
1608 tree mem_type)
1575 { 1609 {
1576 tree addr_base = NULL; 1610 tree addr_base = NULL;
1577 struct iv_group *group = NULL; 1611 struct iv_group *group = NULL;
1578 unsigned HOST_WIDE_INT addr_offset = 0; 1612 poly_uint64 addr_offset = 0;
1579 1613
1580 /* Record non address type use in a new group. */ 1614 /* Record non address type use in a new group. */
1581 if (type == USE_ADDRESS && iv->base_object) 1615 if (address_p (type))
1582 { 1616 {
1583 unsigned int i; 1617 unsigned int i;
1584 1618
1585 addr_base = strip_offset (iv->base, &addr_offset); 1619 addr_base = strip_offset (iv->base, &addr_offset);
1586 for (i = 0; i < data->vgroups.length (); i++) 1620 for (i = 0; i < data->vgroups.length (); i++)
1587 { 1621 {
1588 struct iv_use *use; 1622 struct iv_use *use;
1589 1623
1590 group = data->vgroups[i]; 1624 group = data->vgroups[i];
1591 use = group->vuses[0]; 1625 use = group->vuses[0];
1592 if (use->type != USE_ADDRESS || !use->iv->base_object) 1626 if (!address_p (use->type))
1593 continue; 1627 continue;
1594 1628
1595 /* Check if it has the same stripped base and step. */ 1629 /* Check if it has the same stripped base and step. */
1596 if (operand_equal_p (iv->base_object, use->iv->base_object, 0) 1630 if (operand_equal_p (iv->base_object, use->iv->base_object, 0)
1597 && operand_equal_p (iv->step, use->iv->step, 0) 1631 && operand_equal_p (iv->step, use->iv->step, 0)
1603 } 1637 }
1604 1638
1605 if (!group) 1639 if (!group)
1606 group = record_group (data, type); 1640 group = record_group (data, type);
1607 1641
1608 return record_use (group, use_p, iv, stmt, type, addr_base, addr_offset); 1642 return record_use (group, use_p, iv, stmt, type, mem_type,
1643 addr_base, addr_offset);
1609 } 1644 }
1610 1645
1611 /* Checks whether the use OP is interesting and if so, records it. */ 1646 /* Checks whether the use OP is interesting and if so, records it. */
1612 1647
1613 static struct iv_use * 1648 static struct iv_use *
1637 } 1672 }
1638 1673
1639 stmt = SSA_NAME_DEF_STMT (op); 1674 stmt = SSA_NAME_DEF_STMT (op);
1640 gcc_assert (gimple_code (stmt) == GIMPLE_PHI || is_gimple_assign (stmt)); 1675 gcc_assert (gimple_code (stmt) == GIMPLE_PHI || is_gimple_assign (stmt));
1641 1676
1642 use = record_group_use (data, NULL, iv, stmt, USE_NONLINEAR_EXPR); 1677 use = record_group_use (data, NULL, iv, stmt, USE_NONLINEAR_EXPR, NULL_TREE);
1643 iv->nonlin_use = use; 1678 iv->nonlin_use = use;
1644 return use; 1679 return use;
1645 } 1680 }
1646 1681
1647 /* Indicate how compare type iv_use can be handled. */ 1682 /* Indicate how compare type iv_use can be handled. */
1753 find_interesting_uses_op (data, *var_p); 1788 find_interesting_uses_op (data, *var_p);
1754 find_interesting_uses_op (data, *bound_p); 1789 find_interesting_uses_op (data, *bound_p);
1755 return; 1790 return;
1756 } 1791 }
1757 1792
1758 record_group_use (data, var_p, var_iv, stmt, USE_COMPARE); 1793 record_group_use (data, var_p, var_iv, stmt, USE_COMPARE, NULL_TREE);
1759 /* Record compare type iv_use for iv on the other side of comparison. */ 1794 /* Record compare type iv_use for iv on the other side of comparison. */
1760 if (ret == COMP_IV_EXPR_2) 1795 if (ret == COMP_IV_EXPR_2)
1761 record_group_use (data, bound_p, bound_iv, stmt, USE_COMPARE); 1796 record_group_use (data, bound_p, bound_iv, stmt, USE_COMPARE, NULL_TREE);
1762 } 1797 }
1763 1798
1764 /* Returns the outermost loop EXPR is obviously invariant in 1799 /* Returns the outermost loop EXPR is obviously invariant in
1765 relative to the loop LOOP, i.e. if all its operands are defined 1800 relative to the loop LOOP, i.e. if all its operands are defined
1766 outside of the returned loop. Returns NULL if EXPR is not 1801 outside of the returned loop. Returns NULL if EXPR is not
2163 return false; 2198 return false;
2164 *mul = wi::sext (wi::divmod_trunc (p0, p1, SIGNED, &res), precision); 2199 *mul = wi::sext (wi::divmod_trunc (p0, p1, SIGNED, &res), precision);
2165 return res == 0; 2200 return res == 0;
2166 2201
2167 default: 2202 default:
2203 if (POLY_INT_CST_P (top)
2204 && POLY_INT_CST_P (bot)
2205 && constant_multiple_p (wi::to_poly_widest (top),
2206 wi::to_poly_widest (bot), mul))
2207 return true;
2208
2168 return false; 2209 return false;
2169 } 2210 }
2170 } 2211 }
2171 2212
2172 /* Return true if memory reference REF with step STEP may be unaligned. */ 2213 /* Return true if memory reference REF with step STEP may be unaligned. */
2365 civ = alloc_iv (data, base, step); 2406 civ = alloc_iv (data, base, step);
2366 /* Fail if base object of this memory reference is unknown. */ 2407 /* Fail if base object of this memory reference is unknown. */
2367 if (civ->base_object == NULL_TREE) 2408 if (civ->base_object == NULL_TREE)
2368 goto fail; 2409 goto fail;
2369 2410
2370 record_group_use (data, op_p, civ, stmt, USE_ADDRESS); 2411 record_group_use (data, op_p, civ, stmt, USE_REF_ADDRESS, TREE_TYPE (*op_p));
2371 return; 2412 return;
2372 2413
2373 fail: 2414 fail:
2374 for_each_index (op_p, idx_record_use, data); 2415 for_each_index (op_p, idx_record_use, data);
2375 } 2416 }
2386 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) 2427 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
2387 { 2428 {
2388 op = USE_FROM_PTR (use_p); 2429 op = USE_FROM_PTR (use_p);
2389 record_invariant (data, op, false); 2430 record_invariant (data, op, false);
2390 } 2431 }
2432 }
2433
2434 /* CALL calls an internal function. If operand *OP_P will become an
2435 address when the call is expanded, return the type of the memory
2436 being addressed, otherwise return null. */
2437
2438 static tree
2439 get_mem_type_for_internal_fn (gcall *call, tree *op_p)
2440 {
2441 switch (gimple_call_internal_fn (call))
2442 {
2443 case IFN_MASK_LOAD:
2444 if (op_p == gimple_call_arg_ptr (call, 0))
2445 return TREE_TYPE (gimple_call_lhs (call));
2446 return NULL_TREE;
2447
2448 case IFN_MASK_STORE:
2449 if (op_p == gimple_call_arg_ptr (call, 0))
2450 return TREE_TYPE (gimple_call_arg (call, 3));
2451 return NULL_TREE;
2452
2453 default:
2454 return NULL_TREE;
2455 }
2456 }
2457
2458 /* IV is a (non-address) iv that describes operand *OP_P of STMT.
2459 Return true if the operand will become an address when STMT
2460 is expanded and record the associated address use if so. */
2461
2462 static bool
2463 find_address_like_use (struct ivopts_data *data, gimple *stmt, tree *op_p,
2464 struct iv *iv)
2465 {
2466 /* Fail if base object of this memory reference is unknown. */
2467 if (iv->base_object == NULL_TREE)
2468 return false;
2469
2470 tree mem_type = NULL_TREE;
2471 if (gcall *call = dyn_cast <gcall *> (stmt))
2472 if (gimple_call_internal_p (call))
2473 mem_type = get_mem_type_for_internal_fn (call, op_p);
2474 if (mem_type)
2475 {
2476 iv = alloc_iv (data, iv->base, iv->step);
2477 record_group_use (data, op_p, iv, stmt, USE_PTR_ADDRESS, mem_type);
2478 return true;
2479 }
2480 return false;
2391 } 2481 }
2392 2482
2393 /* Finds interesting uses of induction variables in the statement STMT. */ 2483 /* Finds interesting uses of induction variables in the statement STMT. */
2394 2484
2395 static void 2485 static void
2472 2562
2473 iv = get_iv (data, op); 2563 iv = get_iv (data, op);
2474 if (!iv) 2564 if (!iv)
2475 continue; 2565 continue;
2476 2566
2477 find_interesting_uses_op (data, op); 2567 if (!find_address_like_use (data, stmt, use_p->use, iv))
2568 find_interesting_uses_op (data, op);
2478 } 2569 }
2479 } 2570 }
2480 2571
2481 /* Finds interesting uses of induction variables outside of loops 2572 /* Finds interesting uses of induction variables outside of loops
2482 on loop exit edge EXIT. */ 2573 on loop exit edge EXIT. */
2501 mode for memory reference represented by USE. */ 2592 mode for memory reference represented by USE. */
2502 2593
2503 static GTY (()) vec<rtx, va_gc> *addr_list; 2594 static GTY (()) vec<rtx, va_gc> *addr_list;
2504 2595
2505 static bool 2596 static bool
2506 addr_offset_valid_p (struct iv_use *use, HOST_WIDE_INT offset) 2597 addr_offset_valid_p (struct iv_use *use, poly_int64 offset)
2507 { 2598 {
2508 rtx reg, addr; 2599 rtx reg, addr;
2509 unsigned list_index; 2600 unsigned list_index;
2510 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base)); 2601 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base));
2511 machine_mode addr_mode, mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p)); 2602 machine_mode addr_mode, mem_mode = TYPE_MODE (use->mem_type);
2512 2603
2513 list_index = (unsigned) as * MAX_MACHINE_MODE + (unsigned) mem_mode; 2604 list_index = (unsigned) as * MAX_MACHINE_MODE + (unsigned) mem_mode;
2514 if (list_index >= vec_safe_length (addr_list)) 2605 if (list_index >= vec_safe_length (addr_list))
2515 vec_safe_grow_cleared (addr_list, list_index + MAX_MACHINE_MODE); 2606 vec_safe_grow_cleared (addr_list, list_index + MAX_MACHINE_MODE);
2516 2607
2535 group_compare_offset (const void *a, const void *b) 2626 group_compare_offset (const void *a, const void *b)
2536 { 2627 {
2537 const struct iv_use *const *u1 = (const struct iv_use *const *) a; 2628 const struct iv_use *const *u1 = (const struct iv_use *const *) a;
2538 const struct iv_use *const *u2 = (const struct iv_use *const *) b; 2629 const struct iv_use *const *u2 = (const struct iv_use *const *) b;
2539 2630
2540 if ((*u1)->addr_offset != (*u2)->addr_offset) 2631 return compare_sizes_for_sort ((*u1)->addr_offset, (*u2)->addr_offset);
2541 return (*u1)->addr_offset < (*u2)->addr_offset ? -1 : 1;
2542 else
2543 return 0;
2544 } 2632 }
2545 2633
2546 /* Check if small groups should be split. Return true if no group 2634 /* Check if small groups should be split. Return true if no group
2547 contains more than two uses with distinct addr_offsets. Return 2635 contains more than two uses with distinct addr_offsets. Return
2548 false otherwise. We want to split such groups because: 2636 false otherwise. We want to split such groups because:
2566 { 2654 {
2567 group = data->vgroups[i]; 2655 group = data->vgroups[i];
2568 if (group->vuses.length () == 1) 2656 if (group->vuses.length () == 1)
2569 continue; 2657 continue;
2570 2658
2571 gcc_assert (group->type == USE_ADDRESS); 2659 gcc_assert (address_p (group->type));
2572 if (group->vuses.length () == 2) 2660 if (group->vuses.length () == 2)
2573 { 2661 {
2574 if (group->vuses[0]->addr_offset > group->vuses[1]->addr_offset) 2662 if (compare_sizes_for_sort (group->vuses[0]->addr_offset,
2663 group->vuses[1]->addr_offset) > 0)
2575 std::swap (group->vuses[0], group->vuses[1]); 2664 std::swap (group->vuses[0], group->vuses[1]);
2576 } 2665 }
2577 else 2666 else
2578 group->vuses.qsort (group_compare_offset); 2667 group->vuses.qsort (group_compare_offset);
2579 2668
2581 continue; 2670 continue;
2582 2671
2583 distinct = 1; 2672 distinct = 1;
2584 for (pre = group->vuses[0], j = 1; j < group->vuses.length (); j++) 2673 for (pre = group->vuses[0], j = 1; j < group->vuses.length (); j++)
2585 { 2674 {
2586 if (group->vuses[j]->addr_offset != pre->addr_offset) 2675 if (maybe_ne (group->vuses[j]->addr_offset, pre->addr_offset))
2587 { 2676 {
2588 pre = group->vuses[j]; 2677 pre = group->vuses[j];
2589 distinct++; 2678 distinct++;
2590 } 2679 }
2591 2680
2617 use->id = 0; 2706 use->id = 0;
2618 use->group_id = group->id; 2707 use->group_id = group->id;
2619 if (group->vuses.length () == 1) 2708 if (group->vuses.length () == 1)
2620 continue; 2709 continue;
2621 2710
2622 gcc_assert (group->type == USE_ADDRESS); 2711 gcc_assert (address_p (use->type));
2623 2712
2624 for (j = 1; j < group->vuses.length ();) 2713 for (j = 1; j < group->vuses.length ();)
2625 { 2714 {
2626 struct iv_use *next = group->vuses[j]; 2715 struct iv_use *next = group->vuses[j];
2627 HOST_WIDE_INT offset = next->addr_offset - use->addr_offset; 2716 poly_int64 offset = next->addr_offset - use->addr_offset;
2628 2717
2629 /* Split group if aksed to, or the offset against the first 2718 /* Split group if aksed to, or the offset against the first
2630 use can't fit in offset part of addressing mode. IV uses 2719 use can't fit in offset part of addressing mode. IV uses
2631 having the same offset are still kept in one group. */ 2720 having the same offset are still kept in one group. */
2632 if (offset != 0 && 2721 if (maybe_ne (offset, 0)
2633 (split_p || !addr_offset_valid_p (use, offset))) 2722 && (split_p || !addr_offset_valid_p (use, offset)))
2634 { 2723 {
2635 if (!new_group) 2724 if (!new_group)
2636 new_group = record_group (data, group->type); 2725 new_group = record_group (data, group->type);
2637 group->vuses.ordered_remove (j); 2726 group->vuses.ordered_remove (j);
2638 new_group->vuses.safe_push (next); 2727 new_group->vuses.safe_push (next);
2689 is true, assume we are inside an address. If TOP_COMPREF is true, assume 2778 is true, assume we are inside an address. If TOP_COMPREF is true, assume
2690 we are at the top-level of the processed address. */ 2779 we are at the top-level of the processed address. */
2691 2780
2692 static tree 2781 static tree
2693 strip_offset_1 (tree expr, bool inside_addr, bool top_compref, 2782 strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
2694 HOST_WIDE_INT *offset) 2783 poly_int64 *offset)
2695 { 2784 {
2696 tree op0 = NULL_TREE, op1 = NULL_TREE, tmp, step; 2785 tree op0 = NULL_TREE, op1 = NULL_TREE, tmp, step;
2697 enum tree_code code; 2786 enum tree_code code;
2698 tree type, orig_type = TREE_TYPE (expr); 2787 tree type, orig_type = TREE_TYPE (expr);
2699 HOST_WIDE_INT off0, off1, st; 2788 poly_int64 off0, off1;
2789 HOST_WIDE_INT st;
2700 tree orig_expr = expr; 2790 tree orig_expr = expr;
2701 2791
2702 STRIP_NOPS (expr); 2792 STRIP_NOPS (expr);
2703 2793
2704 type = TREE_TYPE (expr); 2794 type = TREE_TYPE (expr);
2705 code = TREE_CODE (expr); 2795 code = TREE_CODE (expr);
2706 *offset = 0; 2796 *offset = 0;
2707 2797
2708 switch (code) 2798 switch (code)
2709 { 2799 {
2710 case INTEGER_CST:
2711 if (!cst_and_fits_in_hwi (expr)
2712 || integer_zerop (expr))
2713 return orig_expr;
2714
2715 *offset = int_cst_value (expr);
2716 return build_int_cst (orig_type, 0);
2717
2718 case POINTER_PLUS_EXPR: 2800 case POINTER_PLUS_EXPR:
2719 case PLUS_EXPR: 2801 case PLUS_EXPR:
2720 case MINUS_EXPR: 2802 case MINUS_EXPR:
2721 op0 = TREE_OPERAND (expr, 0); 2803 op0 = TREE_OPERAND (expr, 0);
2722 op1 = TREE_OPERAND (expr, 1); 2804 op1 = TREE_OPERAND (expr, 1);
2830 /* ??? Offset operand? */ 2912 /* ??? Offset operand? */
2831 inside_addr = false; 2913 inside_addr = false;
2832 break; 2914 break;
2833 2915
2834 default: 2916 default:
2917 if (ptrdiff_tree_p (expr, offset) && maybe_ne (*offset, 0))
2918 return build_int_cst (orig_type, 0);
2835 return orig_expr; 2919 return orig_expr;
2836 } 2920 }
2837 2921
2838 /* Default handling of expressions for that we want to recurse into 2922 /* Default handling of expressions for that we want to recurse into
2839 the first operand. */ 2923 the first operand. */
2859 } 2943 }
2860 2944
2861 /* Strips constant offsets from EXPR and stores them to OFFSET. */ 2945 /* Strips constant offsets from EXPR and stores them to OFFSET. */
2862 2946
2863 tree 2947 tree
2864 strip_offset (tree expr, unsigned HOST_WIDE_INT *offset) 2948 strip_offset (tree expr, poly_uint64_pod *offset)
2865 { 2949 {
2866 HOST_WIDE_INT off; 2950 poly_int64 off;
2867 tree core = strip_offset_1 (expr, false, false, &off); 2951 tree core = strip_offset_1 (expr, false, false, &off);
2868 *offset = off; 2952 *offset = off;
2869 return core; 2953 return core;
2870 } 2954 }
2871 2955
2962 static iv_inv_expr_ent * 3046 static iv_inv_expr_ent *
2963 get_loop_invariant_expr (struct ivopts_data *data, tree inv_expr) 3047 get_loop_invariant_expr (struct ivopts_data *data, tree inv_expr)
2964 { 3048 {
2965 STRIP_NOPS (inv_expr); 3049 STRIP_NOPS (inv_expr);
2966 3050
2967 if (TREE_CODE (inv_expr) == INTEGER_CST || TREE_CODE (inv_expr) == SSA_NAME) 3051 if (poly_int_tree_p (inv_expr)
3052 || TREE_CODE (inv_expr) == SSA_NAME)
2968 return NULL; 3053 return NULL;
2969 3054
2970 /* Don't strip constant part away as we used to. */ 3055 /* Don't strip constant part away as we used to. */
2971 3056
2972 /* Stores EXPR in DATA->inv_expr_tab, return pointer to iv_inv_expr_ent. */ 3057 /* Stores EXPR in DATA->inv_expr_tab, return pointer to iv_inv_expr_ent. */
3059 } 3144 }
3060 cand->important = important; 3145 cand->important = important;
3061 cand->incremented_at = incremented_at; 3146 cand->incremented_at = incremented_at;
3062 data->vcands.safe_push (cand); 3147 data->vcands.safe_push (cand);
3063 3148
3064 if (TREE_CODE (step) != INTEGER_CST) 3149 if (!poly_int_tree_p (step))
3065 { 3150 {
3066 find_inv_vars (data, &step, &cand->inv_vars); 3151 find_inv_vars (data, &step, &cand->inv_vars);
3067 3152
3068 iv_inv_expr_ent *inv_expr = get_loop_invariant_expr (data, step); 3153 iv_inv_expr_ent *inv_expr = get_loop_invariant_expr (data, step);
3069 /* Share bitmap between inv_vars and inv_exprs for cand. */ 3154 /* Share bitmap between inv_vars and inv_exprs for cand. */
3135 ones, we must ensure that it is incremented once per iteration. 3220 ones, we must ensure that it is incremented once per iteration.
3136 It must not be in an inner nested loop, or one side of an if 3221 It must not be in an inner nested loop, or one side of an if
3137 statement. */ 3222 statement. */
3138 if (use_bb->loop_father != data->current_loop 3223 if (use_bb->loop_father != data->current_loop
3139 || !dominated_by_p (CDI_DOMINATORS, data->current_loop->latch, use_bb) 3224 || !dominated_by_p (CDI_DOMINATORS, data->current_loop->latch, use_bb)
3140 || stmt_can_throw_internal (use->stmt) 3225 || stmt_can_throw_internal (cfun, use->stmt)
3141 || !cst_and_fits_in_hwi (step)) 3226 || !cst_and_fits_in_hwi (step))
3142 return; 3227 return;
3143 3228
3144 cstepi = int_cst_value (step); 3229 cstepi = int_cst_value (step);
3145 3230
3146 mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p)); 3231 mem_mode = TYPE_MODE (use->mem_type);
3147 if (((USE_LOAD_PRE_INCREMENT (mem_mode) 3232 if (((USE_LOAD_PRE_INCREMENT (mem_mode)
3148 || USE_STORE_PRE_INCREMENT (mem_mode)) 3233 || USE_STORE_PRE_INCREMENT (mem_mode))
3149 && GET_MODE_SIZE (mem_mode) == cstepi) 3234 && known_eq (GET_MODE_SIZE (mem_mode), cstepi))
3150 || ((USE_LOAD_PRE_DECREMENT (mem_mode) 3235 || ((USE_LOAD_PRE_DECREMENT (mem_mode)
3151 || USE_STORE_PRE_DECREMENT (mem_mode)) 3236 || USE_STORE_PRE_DECREMENT (mem_mode))
3152 && GET_MODE_SIZE (mem_mode) == -cstepi)) 3237 && known_eq (GET_MODE_SIZE (mem_mode), -cstepi)))
3153 { 3238 {
3154 enum tree_code code = MINUS_EXPR; 3239 enum tree_code code = MINUS_EXPR;
3155 tree new_base; 3240 tree new_base;
3156 tree new_step = step; 3241 tree new_step = step;
3157 3242
3166 add_candidate_1 (data, new_base, step, important, IP_BEFORE_USE, use, 3251 add_candidate_1 (data, new_base, step, important, IP_BEFORE_USE, use,
3167 use->stmt); 3252 use->stmt);
3168 } 3253 }
3169 if (((USE_LOAD_POST_INCREMENT (mem_mode) 3254 if (((USE_LOAD_POST_INCREMENT (mem_mode)
3170 || USE_STORE_POST_INCREMENT (mem_mode)) 3255 || USE_STORE_POST_INCREMENT (mem_mode))
3171 && GET_MODE_SIZE (mem_mode) == cstepi) 3256 && known_eq (GET_MODE_SIZE (mem_mode), cstepi))
3172 || ((USE_LOAD_POST_DECREMENT (mem_mode) 3257 || ((USE_LOAD_POST_DECREMENT (mem_mode)
3173 || USE_STORE_POST_DECREMENT (mem_mode)) 3258 || USE_STORE_POST_DECREMENT (mem_mode))
3174 && GET_MODE_SIZE (mem_mode) == -cstepi)) 3259 && known_eq (GET_MODE_SIZE (mem_mode), -cstepi)))
3175 { 3260 {
3176 add_candidate_1 (data, base, step, important, IP_AFTER_USE, use, 3261 add_candidate_1 (data, base, step, important, IP_AFTER_USE, use,
3177 use->stmt); 3262 use->stmt);
3178 } 3263 }
3179 } 3264 }
3387 /* Adds candidates based on the value of USE's iv. */ 3472 /* Adds candidates based on the value of USE's iv. */
3388 3473
3389 static void 3474 static void
3390 add_iv_candidate_for_use (struct ivopts_data *data, struct iv_use *use) 3475 add_iv_candidate_for_use (struct ivopts_data *data, struct iv_use *use)
3391 { 3476 {
3392 unsigned HOST_WIDE_INT offset; 3477 poly_uint64 offset;
3393 tree base; 3478 tree base;
3394 tree basetype; 3479 tree basetype;
3395 struct iv *iv = use->iv; 3480 struct iv *iv = use->iv;
3396 3481
3397 add_candidate (data, iv->base, iv->step, false, use); 3482 add_candidate (data, iv->base, iv->step, false, use);
3406 record_common_cand (data, build_int_cst (basetype, 0), iv->step, use); 3491 record_common_cand (data, build_int_cst (basetype, 0), iv->step, use);
3407 3492
3408 /* Record common candidate with constant offset stripped in base. 3493 /* Record common candidate with constant offset stripped in base.
3409 Like the use itself, we also add candidate directly for it. */ 3494 Like the use itself, we also add candidate directly for it. */
3410 base = strip_offset (iv->base, &offset); 3495 base = strip_offset (iv->base, &offset);
3411 if (offset || base != iv->base) 3496 if (maybe_ne (offset, 0U) || base != iv->base)
3412 { 3497 {
3413 record_common_cand (data, base, iv->step, use); 3498 record_common_cand (data, base, iv->step, use);
3414 add_candidate (data, base, iv->step, false, use); 3499 add_candidate (data, base, iv->step, false, use);
3415 } 3500 }
3416 3501
3425 base = TREE_OPERAND (base, 1); 3510 base = TREE_OPERAND (base, 1);
3426 step = fold_convert (sizetype, step); 3511 step = fold_convert (sizetype, step);
3427 record_common_cand (data, base, step, use); 3512 record_common_cand (data, base, step, use);
3428 /* Also record common candidate with offset stripped. */ 3513 /* Also record common candidate with offset stripped. */
3429 base = strip_offset (base, &offset); 3514 base = strip_offset (base, &offset);
3430 if (offset) 3515 if (maybe_ne (offset, 0U))
3431 record_common_cand (data, base, step, use); 3516 record_common_cand (data, base, step, use);
3432 } 3517 }
3433 3518
3434 /* At last, add auto-incremental candidates. Make such variables 3519 /* At last, add auto-incremental candidates. Make such variables
3435 important since other iv uses with same base object may be based 3520 important since other iv uses with same base object may be based
3436 on it. */ 3521 on it. */
3437 if (use != NULL && use->type == USE_ADDRESS) 3522 if (use != NULL && address_p (use->type))
3438 add_autoinc_candidates (data, iv->base, iv->step, true, use); 3523 add_autoinc_candidates (data, iv->base, iv->step, true, use);
3439 } 3524 }
3440 3525
3441 /* Adds candidates based on the uses. */ 3526 /* Adds candidates based on the uses. */
3442 3527
3795 3880
3796 /* If the conversion is not noop, perform it. */ 3881 /* If the conversion is not noop, perform it. */
3797 if (TYPE_PRECISION (utype) < TYPE_PRECISION (ctype)) 3882 if (TYPE_PRECISION (utype) < TYPE_PRECISION (ctype))
3798 { 3883 {
3799 if (cand->orig_iv != NULL && CONVERT_EXPR_P (cbase) 3884 if (cand->orig_iv != NULL && CONVERT_EXPR_P (cbase)
3800 && (CONVERT_EXPR_P (cstep) || TREE_CODE (cstep) == INTEGER_CST)) 3885 && (CONVERT_EXPR_P (cstep) || poly_int_tree_p (cstep)))
3801 { 3886 {
3802 tree inner_base, inner_step, inner_type; 3887 tree inner_base, inner_step, inner_type;
3803 inner_base = TREE_OPERAND (cbase, 0); 3888 inner_base = TREE_OPERAND (cbase, 0);
3804 if (CONVERT_EXPR_P (cstep)) 3889 if (CONVERT_EXPR_P (cstep))
3805 inner_step = TREE_OPERAND (cstep, 0); 3890 inner_step = TREE_OPERAND (cstep, 0);
3899 get_use_type (struct iv_use *use) 3984 get_use_type (struct iv_use *use)
3900 { 3985 {
3901 tree base_type = TREE_TYPE (use->iv->base); 3986 tree base_type = TREE_TYPE (use->iv->base);
3902 tree type; 3987 tree type;
3903 3988
3904 if (use->type == USE_ADDRESS) 3989 if (use->type == USE_REF_ADDRESS)
3905 { 3990 {
3906 /* The base_type may be a void pointer. Create a pointer type based on 3991 /* The base_type may be a void pointer. Create a pointer type based on
3907 the mem_ref instead. */ 3992 the mem_ref instead. */
3908 type = build_pointer_type (TREE_TYPE (*use->op_p)); 3993 type = build_pointer_type (TREE_TYPE (*use->op_p));
3909 gcc_assert (TYPE_ADDR_SPACE (TREE_TYPE (type)) 3994 gcc_assert (TYPE_ADDR_SPACE (TREE_TYPE (type))
4053 if (SSA_VAR_P (expr)) 4138 if (SSA_VAR_P (expr))
4054 return no_cost; 4139 return no_cost;
4055 4140
4056 if (is_gimple_min_invariant (expr)) 4141 if (is_gimple_min_invariant (expr))
4057 { 4142 {
4058 if (TREE_CODE (expr) == INTEGER_CST) 4143 if (poly_int_tree_p (expr))
4059 return comp_cost (integer_cost [speed], 0); 4144 return comp_cost (integer_cost [speed], 0);
4060 4145
4061 if (TREE_CODE (expr) == ADDR_EXPR) 4146 if (TREE_CODE (expr) == ADDR_EXPR)
4062 { 4147 {
4063 tree obj = TREE_OPERAND (expr, 0); 4148 tree obj = TREE_OPERAND (expr, 0);
4218 { 4303 {
4219 unsigned costs[AINC_NONE]; 4304 unsigned costs[AINC_NONE];
4220 }; 4305 };
4221 4306
4222 static comp_cost 4307 static comp_cost
4223 get_address_cost_ainc (HOST_WIDE_INT ainc_step, HOST_WIDE_INT ainc_offset, 4308 get_address_cost_ainc (poly_int64 ainc_step, poly_int64 ainc_offset,
4224 machine_mode addr_mode, machine_mode mem_mode, 4309 machine_mode addr_mode, machine_mode mem_mode,
4225 addr_space_t as, bool speed) 4310 addr_space_t as, bool speed)
4226 { 4311 {
4227 if (!USE_LOAD_PRE_DECREMENT (mem_mode) 4312 if (!USE_LOAD_PRE_DECREMENT (mem_mode)
4228 && !USE_STORE_PRE_DECREMENT (mem_mode) 4313 && !USE_STORE_PRE_DECREMENT (mem_mode)
4291 = address_cost (addr, mem_mode, as, speed); 4376 = address_cost (addr, mem_mode, as, speed);
4292 } 4377 }
4293 ainc_cost_data_list[idx] = data; 4378 ainc_cost_data_list[idx] = data;
4294 } 4379 }
4295 4380
4296 HOST_WIDE_INT msize = GET_MODE_SIZE (mem_mode); 4381 poly_int64 msize = GET_MODE_SIZE (mem_mode);
4297 if (ainc_offset == 0 && msize == ainc_step) 4382 if (known_eq (ainc_offset, 0) && known_eq (msize, ainc_step))
4298 return comp_cost (data->costs[AINC_POST_INC], 0); 4383 return comp_cost (data->costs[AINC_POST_INC], 0);
4299 if (ainc_offset == 0 && msize == -ainc_step) 4384 if (known_eq (ainc_offset, 0) && known_eq (msize, -ainc_step))
4300 return comp_cost (data->costs[AINC_POST_DEC], 0); 4385 return comp_cost (data->costs[AINC_POST_DEC], 0);
4301 if (ainc_offset == msize && msize == ainc_step) 4386 if (known_eq (ainc_offset, msize) && known_eq (msize, ainc_step))
4302 return comp_cost (data->costs[AINC_PRE_INC], 0); 4387 return comp_cost (data->costs[AINC_PRE_INC], 0);
4303 if (ainc_offset == -msize && msize == -ainc_step) 4388 if (known_eq (ainc_offset, -msize) && known_eq (msize, -ainc_step))
4304 return comp_cost (data->costs[AINC_PRE_DEC], 0); 4389 return comp_cost (data->costs[AINC_PRE_DEC], 0);
4305 4390
4306 return infinite_cost; 4391 return infinite_cost;
4307 } 4392 }
4308 4393
4327 tree comp_inv = NULL_TREE, type = aff_var->type; 4412 tree comp_inv = NULL_TREE, type = aff_var->type;
4328 comp_cost var_cost = no_cost, cost = no_cost; 4413 comp_cost var_cost = no_cost, cost = no_cost;
4329 struct mem_address parts = {NULL_TREE, integer_one_node, 4414 struct mem_address parts = {NULL_TREE, integer_one_node,
4330 NULL_TREE, NULL_TREE, NULL_TREE}; 4415 NULL_TREE, NULL_TREE, NULL_TREE};
4331 machine_mode addr_mode = TYPE_MODE (type); 4416 machine_mode addr_mode = TYPE_MODE (type);
4332 machine_mode mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p)); 4417 machine_mode mem_mode = TYPE_MODE (use->mem_type);
4333 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base)); 4418 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (use->iv->base));
4419 /* Only true if ratio != 1. */
4420 bool ok_with_ratio_p = false;
4421 bool ok_without_ratio_p = false;
4334 4422
4335 if (!aff_combination_const_p (aff_inv)) 4423 if (!aff_combination_const_p (aff_inv))
4336 { 4424 {
4337 parts.index = integer_one_node; 4425 parts.index = integer_one_node;
4338 /* Addressing mode "base + index". */ 4426 /* Addressing mode "base + index". */
4339 if (valid_mem_ref_p (mem_mode, as, &parts)) 4427 ok_without_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
4428 if (ratio != 1)
4340 { 4429 {
4341 parts.step = wide_int_to_tree (type, ratio); 4430 parts.step = wide_int_to_tree (type, ratio);
4342 /* Addressing mode "base + index << scale". */ 4431 /* Addressing mode "base + index << scale". */
4343 if (ratio != 1 && !valid_mem_ref_p (mem_mode, as, &parts)) 4432 ok_with_ratio_p = valid_mem_ref_p (mem_mode, as, &parts);
4433 if (!ok_with_ratio_p)
4344 parts.step = NULL_TREE; 4434 parts.step = NULL_TREE;
4345 4435 }
4346 if (aff_inv->offset != 0) 4436 if (ok_with_ratio_p || ok_without_ratio_p)
4437 {
4438 if (maybe_ne (aff_inv->offset, 0))
4347 { 4439 {
4348 parts.offset = wide_int_to_tree (sizetype, aff_inv->offset); 4440 parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
4349 /* Addressing mode "base + index [<< scale] + offset". */ 4441 /* Addressing mode "base + index [<< scale] + offset". */
4350 if (!valid_mem_ref_p (mem_mode, as, &parts)) 4442 if (!valid_mem_ref_p (mem_mode, as, &parts))
4351 parts.offset = NULL_TREE; 4443 parts.offset = NULL_TREE;
4374 else 4466 else
4375 parts.index = NULL_TREE; 4467 parts.index = NULL_TREE;
4376 } 4468 }
4377 else 4469 else
4378 { 4470 {
4379 if (can_autoinc && ratio == 1 && cst_and_fits_in_hwi (cand->iv->step)) 4471 poly_int64 ainc_step;
4380 { 4472 if (can_autoinc
4381 HOST_WIDE_INT ainc_step = int_cst_value (cand->iv->step); 4473 && ratio == 1
4382 HOST_WIDE_INT ainc_offset = (aff_inv->offset).to_shwi (); 4474 && ptrdiff_tree_p (cand->iv->step, &ainc_step))
4475 {
4476 poly_int64 ainc_offset = (aff_inv->offset).force_shwi ();
4383 4477
4384 if (stmt_after_increment (data->current_loop, cand, use->stmt)) 4478 if (stmt_after_increment (data->current_loop, cand, use->stmt))
4385 ainc_offset += ainc_step; 4479 ainc_offset += ainc_step;
4386 cost = get_address_cost_ainc (ainc_step, ainc_offset, 4480 cost = get_address_cost_ainc (ainc_step, ainc_offset,
4387 addr_mode, mem_mode, as, speed); 4481 addr_mode, mem_mode, as, speed);
4438 gcc_assert (memory_address_addr_space_p (mem_mode, addr, as)); 4532 gcc_assert (memory_address_addr_space_p (mem_mode, addr, as));
4439 cost += address_cost (addr, mem_mode, as, speed); 4533 cost += address_cost (addr, mem_mode, as, speed);
4440 4534
4441 if (parts.symbol != NULL_TREE) 4535 if (parts.symbol != NULL_TREE)
4442 cost.complexity += 1; 4536 cost.complexity += 1;
4443 if (parts.step != NULL_TREE && !integer_onep (parts.step)) 4537 /* Don't increase the complexity of adding a scaled index if it's
4538 the only kind of index that the target allows. */
4539 if (parts.step != NULL_TREE && ok_without_ratio_p)
4444 cost.complexity += 1; 4540 cost.complexity += 1;
4445 if (parts.base != NULL_TREE && parts.index != NULL_TREE) 4541 if (parts.base != NULL_TREE && parts.index != NULL_TREE)
4446 cost.complexity += 1; 4542 cost.complexity += 1;
4447 if (parts.offset != NULL_TREE && !integer_zerop (parts.offset)) 4543 if (parts.offset != NULL_TREE && !integer_zerop (parts.offset))
4448 cost.complexity += 1; 4544 cost.complexity += 1;
4455 expected cost more accurate. */ 4551 expected cost more accurate. */
4456 4552
4457 static comp_cost 4553 static comp_cost
4458 get_scaled_computation_cost_at (ivopts_data *data, gimple *at, comp_cost cost) 4554 get_scaled_computation_cost_at (ivopts_data *data, gimple *at, comp_cost cost)
4459 { 4555 {
4460 int loop_freq = data->current_loop->header->frequency; 4556 int loop_freq = data->current_loop->header->count.to_frequency (cfun);
4461 int bb_freq = gimple_bb (at)->frequency; 4557 int bb_freq = gimple_bb (at)->count.to_frequency (cfun);
4462 if (loop_freq != 0) 4558 if (loop_freq != 0)
4463 { 4559 {
4464 gcc_assert (cost.scratch <= cost.cost); 4560 gcc_assert (cost.scratch <= cost.cost);
4465 int scaled_cost 4561 int scaled_cost
4466 = cost.scratch + (cost.cost - cost.scratch) * bb_freq / loop_freq; 4562 = cost.scratch + (cost.cost - cost.scratch) * bb_freq / loop_freq;
4935 tree_to_aff_combination (fold_convert (nit_type, b), nit_type, &tmpb); 5031 tree_to_aff_combination (fold_convert (nit_type, b), nit_type, &tmpb);
4936 aff_combination_scale (&nit, -1); 5032 aff_combination_scale (&nit, -1);
4937 aff_combination_scale (&tmpa, -1); 5033 aff_combination_scale (&tmpa, -1);
4938 aff_combination_add (&tmpb, &tmpa); 5034 aff_combination_add (&tmpb, &tmpa);
4939 aff_combination_add (&tmpb, &nit); 5035 aff_combination_add (&tmpb, &nit);
4940 if (tmpb.n != 0 || tmpb.offset != 1) 5036 if (tmpb.n != 0 || maybe_ne (tmpb.offset, 1))
4941 return false; 5037 return false;
4942 5038
4943 /* Finally, check that CAND->IV->BASE - CAND->IV->STEP * A does not 5039 /* Finally, check that CAND->IV->BASE - CAND->IV->STEP * A does not
4944 overflow. */ 5040 overflow. */
4945 offset = fold_build2 (MULT_EXPR, TREE_TYPE (cand->iv->step), 5041 offset = fold_build2 (MULT_EXPR, TREE_TYPE (cand->iv->step),
5205 switch (group->type) 5301 switch (group->type)
5206 { 5302 {
5207 case USE_NONLINEAR_EXPR: 5303 case USE_NONLINEAR_EXPR:
5208 return determine_group_iv_cost_generic (data, group, cand); 5304 return determine_group_iv_cost_generic (data, group, cand);
5209 5305
5210 case USE_ADDRESS: 5306 case USE_REF_ADDRESS:
5307 case USE_PTR_ADDRESS:
5211 return determine_group_iv_cost_address (data, group, cand); 5308 return determine_group_iv_cost_address (data, group, cand);
5212 5309
5213 case USE_COMPARE: 5310 case USE_COMPARE:
5214 return determine_group_iv_cost_cond (data, group, cand); 5311 return determine_group_iv_cost_cond (data, group, cand);
5215 5312
5223 5320
5224 static bool 5321 static bool
5225 autoinc_possible_for_pair (struct ivopts_data *data, struct iv_use *use, 5322 autoinc_possible_for_pair (struct ivopts_data *data, struct iv_use *use,
5226 struct iv_cand *cand) 5323 struct iv_cand *cand)
5227 { 5324 {
5228 if (use->type != USE_ADDRESS) 5325 if (!address_p (use->type))
5229 return false; 5326 return false;
5230 5327
5231 bool can_autoinc = false; 5328 bool can_autoinc = false;
5232 get_computation_cost (data, use, cand, true, NULL, &can_autoinc, NULL); 5329 get_computation_cost (data, use, cand, true, NULL, &can_autoinc, NULL);
5233 return can_autoinc; 5330 return can_autoinc;
6832 6929
6833 unshare_aff_combination (&aff_inv); 6930 unshare_aff_combination (&aff_inv);
6834 unshare_aff_combination (&aff_var); 6931 unshare_aff_combination (&aff_var);
6835 /* Prefer CSE opportunity than loop invariant by adding offset at last 6932 /* Prefer CSE opportunity than loop invariant by adding offset at last
6836 so that iv_uses have different offsets can be CSEed. */ 6933 so that iv_uses have different offsets can be CSEed. */
6837 widest_int offset = aff_inv.offset; 6934 poly_widest_int offset = aff_inv.offset;
6838 aff_inv.offset = 0; 6935 aff_inv.offset = 0;
6839 6936
6840 gimple_seq stmt_list = NULL, seq = NULL; 6937 gimple_seq stmt_list = NULL, seq = NULL;
6841 tree comp_op1 = aff_combination_to_tree (&aff_inv); 6938 tree comp_op1 = aff_combination_to_tree (&aff_inv);
6842 tree comp_op2 = aff_combination_to_tree (&aff_var); 6939 tree comp_op2 = aff_combination_to_tree (&aff_var);
6981 gsi_move_before (&gsi_iv, &gsi); 7078 gsi_move_before (&gsi_iv, &gsi);
6982 7079
6983 cand->pos = IP_BEFORE_USE; 7080 cand->pos = IP_BEFORE_USE;
6984 cand->incremented_at = use->stmt; 7081 cand->incremented_at = use->stmt;
6985 } 7082 }
7083
7084 /* Return the alias pointer type that should be used for a MEM_REF
7085 associated with USE, which has type USE_PTR_ADDRESS. */
7086
7087 static tree
7088 get_alias_ptr_type_for_ptr_address (iv_use *use)
7089 {
7090 gcall *call = as_a <gcall *> (use->stmt);
7091 switch (gimple_call_internal_fn (call))
7092 {
7093 case IFN_MASK_LOAD:
7094 case IFN_MASK_STORE:
7095 /* The second argument contains the correct alias type. */
7096 gcc_assert (use->op_p = gimple_call_arg_ptr (call, 0));
7097 return TREE_TYPE (gimple_call_arg (call, 1));
7098
7099 default:
7100 gcc_unreachable ();
7101 }
7102 }
7103
6986 7104
6987 /* Rewrites USE (address that is an iv) using candidate CAND. */ 7105 /* Rewrites USE (address that is an iv) using candidate CAND. */
6988 7106
6989 static void 7107 static void
6990 rewrite_use_address (struct ivopts_data *data, 7108 rewrite_use_address (struct ivopts_data *data,
7010 of the use -- but these will use pointer types, so they are recognized 7128 of the use -- but these will use pointer types, so they are recognized
7011 by the create_mem_ref heuristics anyway. */ 7129 by the create_mem_ref heuristics anyway. */
7012 tree iv = var_at_stmt (data->current_loop, cand, use->stmt); 7130 tree iv = var_at_stmt (data->current_loop, cand, use->stmt);
7013 tree base_hint = (cand->iv->base_object) ? iv : NULL_TREE; 7131 tree base_hint = (cand->iv->base_object) ? iv : NULL_TREE;
7014 gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt); 7132 gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
7015 tree type = TREE_TYPE (*use->op_p); 7133 tree type = use->mem_type;
7016 unsigned int align = get_object_alignment (*use->op_p); 7134 tree alias_ptr_type;
7017 if (align != TYPE_ALIGN (type)) 7135 if (use->type == USE_PTR_ADDRESS)
7018 type = build_aligned_type (type, align); 7136 alias_ptr_type = get_alias_ptr_type_for_ptr_address (use);
7019 7137 else
7020 tree ref = create_mem_ref (&bsi, type, &aff, 7138 {
7021 reference_alias_ptr_type (*use->op_p), 7139 gcc_assert (type == TREE_TYPE (*use->op_p));
7140 unsigned int align = get_object_alignment (*use->op_p);
7141 if (align != TYPE_ALIGN (type))
7142 type = build_aligned_type (type, align);
7143 alias_ptr_type = reference_alias_ptr_type (*use->op_p);
7144 }
7145 tree ref = create_mem_ref (&bsi, type, &aff, alias_ptr_type,
7022 iv, base_hint, data->speed); 7146 iv, base_hint, data->speed);
7023 7147
7024 copy_ref_info (ref, *use->op_p); 7148 if (use->type == USE_PTR_ADDRESS)
7149 {
7150 ref = fold_build1 (ADDR_EXPR, build_pointer_type (use->mem_type), ref);
7151 ref = fold_convert (get_use_type (use), ref);
7152 ref = force_gimple_operand_gsi (&bsi, ref, true, NULL_TREE,
7153 true, GSI_SAME_STMT);
7154 }
7155 else
7156 copy_ref_info (ref, *use->op_p);
7157
7025 *use->op_p = ref; 7158 *use->op_p = ref;
7026 } 7159 }
7027 7160
7028 /* Rewrites USE (the condition such that one of the arguments is an iv) using 7161 /* Rewrites USE (the condition such that one of the arguments is an iv) using
7029 candidate CAND. */ 7162 candidate CAND. */
7095 { 7228 {
7096 rewrite_use_nonlinear_expr (data, group->vuses[j], cand); 7229 rewrite_use_nonlinear_expr (data, group->vuses[j], cand);
7097 update_stmt (group->vuses[j]->stmt); 7230 update_stmt (group->vuses[j]->stmt);
7098 } 7231 }
7099 } 7232 }
7100 else if (group->type == USE_ADDRESS) 7233 else if (address_p (group->type))
7101 { 7234 {
7102 for (j = 0; j < group->vuses.length (); j++) 7235 for (j = 0; j < group->vuses.length (); j++)
7103 { 7236 {
7104 rewrite_use_address (data, group->vuses[j], cand); 7237 rewrite_use_address (data, group->vuses[j], cand);
7105 update_stmt (group->vuses[j]->stmt); 7238 update_stmt (group->vuses[j]->stmt);
7143 { 7276 {
7144 bitmap_set_bit (toremove, SSA_NAME_VERSION (info->iv->ssa_name)); 7277 bitmap_set_bit (toremove, SSA_NAME_VERSION (info->iv->ssa_name));
7145 7278
7146 tree def = info->iv->ssa_name; 7279 tree def = info->iv->ssa_name;
7147 7280
7148 if (MAY_HAVE_DEBUG_STMTS && SSA_NAME_DEF_STMT (def)) 7281 if (MAY_HAVE_DEBUG_BIND_STMTS && SSA_NAME_DEF_STMT (def))
7149 { 7282 {
7150 imm_use_iterator imm_iter; 7283 imm_use_iterator imm_iter;
7151 use_operand_p use_p; 7284 use_operand_p use_p;
7152 gimple *stmt; 7285 gimple *stmt;
7153 int count = 0; 7286 int count = 0;
7400 edge exit = single_dom_exit (loop); 7533 edge exit = single_dom_exit (loop);
7401 basic_block *body; 7534 basic_block *body;
7402 7535
7403 gcc_assert (!data->niters); 7536 gcc_assert (!data->niters);
7404 data->current_loop = loop; 7537 data->current_loop = loop;
7405 data->loop_loc = find_loop_location (loop); 7538 data->loop_loc = find_loop_location (loop).get_location_t ();
7406 data->speed = optimize_loop_for_speed_p (loop); 7539 data->speed = optimize_loop_for_speed_p (loop);
7407 7540
7408 if (dump_file && (dump_flags & TDF_DETAILS)) 7541 if (dump_file && (dump_flags & TDF_DETAILS))
7409 { 7542 {
7410 fprintf (dump_file, "Processing loop %d", loop->num); 7543 fprintf (dump_file, "Processing loop %d", loop->num);