var-tracking.c (169690) | var-tracking.c (235623) |
---|---|
1/* Variable tracking routines for the GNU compiler. 2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 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 8 the Free Software Foundation; either version 2, or (at your option) --- 245 unchanged lines hidden (view full) --- 254} *variable; 255 256/* Hash function for DECL for VARIABLE_HTAB. */ 257#define VARIABLE_HASH_VAL(decl) (DECL_UID (decl)) 258 259/* Pointer to the BB's information specific to variable tracking pass. */ 260#define VTI(BB) ((variable_tracking_info) (BB)->aux) 261 | 1/* Variable tracking routines for the GNU compiler. 2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 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 8 the Free Software Foundation; either version 2, or (at your option) --- 245 unchanged lines hidden (view full) --- 254} *variable; 255 256/* Hash function for DECL for VARIABLE_HTAB. */ 257#define VARIABLE_HASH_VAL(decl) (DECL_UID (decl)) 258 259/* Pointer to the BB's information specific to variable tracking pass. */ 260#define VTI(BB) ((variable_tracking_info) (BB)->aux) 261 |
262/* Macro to access MEM_OFFSET as an HOST_WIDE_INT. Evaluates MEM twice. */ 263#define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0) 264 |
|
262/* Alloc pool for struct attrs_def. */ 263static alloc_pool attrs_pool; 264 265/* Alloc pool for struct variable_def. */ 266static alloc_pool var_pool; 267 268/* Alloc pool for struct location_chain_def. */ 269static alloc_pool loc_chain_pool; --- 652 unchanged lines hidden (view full) --- 922/* Set the location part of variable MEM_EXPR (LOC) in dataflow set 923 SET to LOC. 924 Adjust the address first if it is stack pointer based. */ 925 926static void 927var_mem_set (dataflow_set *set, rtx loc) 928{ 929 tree decl = MEM_EXPR (loc); | 265/* Alloc pool for struct attrs_def. */ 266static alloc_pool attrs_pool; 267 268/* Alloc pool for struct variable_def. */ 269static alloc_pool var_pool; 270 271/* Alloc pool for struct location_chain_def. */ 272static alloc_pool loc_chain_pool; --- 652 unchanged lines hidden (view full) --- 925/* Set the location part of variable MEM_EXPR (LOC) in dataflow set 926 SET to LOC. 927 Adjust the address first if it is stack pointer based. */ 928 929static void 930var_mem_set (dataflow_set *set, rtx loc) 931{ 932 tree decl = MEM_EXPR (loc); |
930 HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0; | 933 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc); |
931 932 decl = var_debug_decl (decl); 933 934 set_variable_part (set, loc, decl, offset); 935} 936 937/* Delete and set the location part of variable MEM_EXPR (LOC) in 938 dataflow set SET to LOC. If MODIFY is true, any other live copies 939 of the same variable part are also deleted from the dataflow set, 940 otherwise the variable part is assumed to be copied from another 941 location holding the same part. 942 Adjust the address first if it is stack pointer based. */ 943 944static void 945var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify) 946{ 947 tree decl = MEM_EXPR (loc); | 934 935 decl = var_debug_decl (decl); 936 937 set_variable_part (set, loc, decl, offset); 938} 939 940/* Delete and set the location part of variable MEM_EXPR (LOC) in 941 dataflow set SET to LOC. If MODIFY is true, any other live copies 942 of the same variable part are also deleted from the dataflow set, 943 otherwise the variable part is assumed to be copied from another 944 location holding the same part. 945 Adjust the address first if it is stack pointer based. */ 946 947static void 948var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify) 949{ 950 tree decl = MEM_EXPR (loc); |
948 HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0; | 951 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc); |
949 950 decl = var_debug_decl (decl); 951 952 if (modify) 953 clobber_variable_part (set, NULL, decl, offset); 954 var_mem_set (set, loc); 955} 956 957/* Delete the location part LOC from dataflow set SET. If CLOBBER is 958 true, also delete any other live copies of the same variable part. 959 Adjust the address first if it is stack pointer based. */ 960 961static void 962var_mem_delete (dataflow_set *set, rtx loc, bool clobber) 963{ 964 tree decl = MEM_EXPR (loc); | 952 953 decl = var_debug_decl (decl); 954 955 if (modify) 956 clobber_variable_part (set, NULL, decl, offset); 957 var_mem_set (set, loc); 958} 959 960/* Delete the location part LOC from dataflow set SET. If CLOBBER is 961 true, also delete any other live copies of the same variable part. 962 Adjust the address first if it is stack pointer based. */ 963 964static void 965var_mem_delete (dataflow_set *set, rtx loc, bool clobber) 966{ 967 tree decl = MEM_EXPR (loc); |
965 HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0; | 968 HOST_WIDE_INT offset = INT_MEM_OFFSET (loc); |
966 967 decl = var_debug_decl (decl); 968 if (clobber) 969 clobber_variable_part (set, NULL, decl, offset); 970 delete_variable_part (set, loc, decl, offset); 971} 972 973/* Initialize dataflow set SET to be empty. --- 561 unchanged lines hidden (view full) --- 1535 if (MEM_SIZE (decl_rtl) 1536 && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS) 1537 return 0; 1538 } 1539 1540 return 1; 1541} 1542 | 969 970 decl = var_debug_decl (decl); 971 if (clobber) 972 clobber_variable_part (set, NULL, decl, offset); 973 delete_variable_part (set, loc, decl, offset); 974} 975 976/* Initialize dataflow set SET to be empty. --- 561 unchanged lines hidden (view full) --- 1538 if (MEM_SIZE (decl_rtl) 1539 && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS) 1540 return 0; 1541 } 1542 1543 return 1; 1544} 1545 |
1546/* Return true if OFFSET is a valid offset for a register or memory 1547 access we want to track. This is used to reject out-of-bounds 1548 accesses that can cause assertions to fail later. Note that we 1549 don't reject negative offsets because they can be generated for 1550 paradoxical subregs on big-endian architectures. */ 1551 1552static inline bool 1553offset_valid_for_tracked_p (HOST_WIDE_INT offset) 1554{ 1555 return (-MAX_VAR_PARTS < offset) && (offset < MAX_VAR_PARTS); 1556} 1557 |
|
1543/* Determine whether a given LOC refers to the same variable part as 1544 EXPR+OFFSET. */ 1545 1546static bool 1547same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset) 1548{ 1549 tree expr2; 1550 HOST_WIDE_INT offset2; --- 4 unchanged lines hidden (view full) --- 1555 if (REG_P (loc)) 1556 { 1557 expr2 = REG_EXPR (loc); 1558 offset2 = REG_OFFSET (loc); 1559 } 1560 else if (MEM_P (loc)) 1561 { 1562 expr2 = MEM_EXPR (loc); | 1558/* Determine whether a given LOC refers to the same variable part as 1559 EXPR+OFFSET. */ 1560 1561static bool 1562same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset) 1563{ 1564 tree expr2; 1565 HOST_WIDE_INT offset2; --- 4 unchanged lines hidden (view full) --- 1570 if (REG_P (loc)) 1571 { 1572 expr2 = REG_EXPR (loc); 1573 offset2 = REG_OFFSET (loc); 1574 } 1575 else if (MEM_P (loc)) 1576 { 1577 expr2 = MEM_EXPR (loc); |
1563 offset2 = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0; | 1578 offset2 = INT_MEM_OFFSET (loc); |
1564 } 1565 else 1566 return false; 1567 1568 if (! expr2 || ! DECL_P (expr2)) 1569 return false; 1570 1571 expr = var_debug_decl (expr); --- 13 unchanged lines hidden (view full) --- 1585 1586 if (REG_P (*loc)) 1587 { 1588 gcc_assert (REGNO (*loc) < FIRST_PSEUDO_REGISTER); 1589 VTI (bb)->n_mos++; 1590 } 1591 else if (MEM_P (*loc) 1592 && MEM_EXPR (*loc) | 1579 } 1580 else 1581 return false; 1582 1583 if (! expr2 || ! DECL_P (expr2)) 1584 return false; 1585 1586 expr = var_debug_decl (expr); --- 13 unchanged lines hidden (view full) --- 1600 1601 if (REG_P (*loc)) 1602 { 1603 gcc_assert (REGNO (*loc) < FIRST_PSEUDO_REGISTER); 1604 VTI (bb)->n_mos++; 1605 } 1606 else if (MEM_P (*loc) 1607 && MEM_EXPR (*loc) |
1593 && track_expr_p (MEM_EXPR (*loc))) | 1608 && track_expr_p (MEM_EXPR (*loc)) 1609 && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc))) |
1594 { 1595 VTI (bb)->n_mos++; 1596 } 1597 1598 return 0; 1599} 1600 1601/* Helper function for finding all uses of REG/MEM in X in insn INSN. */ --- 19 unchanged lines hidden (view full) --- 1621static int 1622add_uses (rtx *loc, void *insn) 1623{ 1624 if (REG_P (*loc)) 1625 { 1626 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1627 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1628 | 1610 { 1611 VTI (bb)->n_mos++; 1612 } 1613 1614 return 0; 1615} 1616 1617/* Helper function for finding all uses of REG/MEM in X in insn INSN. */ --- 19 unchanged lines hidden (view full) --- 1637static int 1638add_uses (rtx *loc, void *insn) 1639{ 1640 if (REG_P (*loc)) 1641 { 1642 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1643 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1644 |
1629 mo->type = ((REG_EXPR (*loc) && track_expr_p (REG_EXPR (*loc))) 1630 ? MO_USE : MO_USE_NO_VAR); | 1645 if (REG_EXPR (*loc) 1646 && track_expr_p (REG_EXPR (*loc)) 1647 && offset_valid_for_tracked_p (REG_OFFSET (*loc))) 1648 mo->type = MO_USE; 1649 else 1650 mo->type = MO_USE_NO_VAR; |
1631 mo->u.loc = *loc; 1632 mo->insn = (rtx) insn; 1633 } 1634 else if (MEM_P (*loc) 1635 && MEM_EXPR (*loc) | 1651 mo->u.loc = *loc; 1652 mo->insn = (rtx) insn; 1653 } 1654 else if (MEM_P (*loc) 1655 && MEM_EXPR (*loc) |
1636 && track_expr_p (MEM_EXPR (*loc))) | 1656 && track_expr_p (MEM_EXPR (*loc)) 1657 && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc))) |
1637 { 1638 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1639 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1640 1641 mo->type = MO_USE; 1642 mo->u.loc = *loc; 1643 mo->insn = (rtx) insn; 1644 } --- 17 unchanged lines hidden (view full) --- 1662add_stores (rtx loc, rtx expr, void *insn) 1663{ 1664 if (REG_P (loc)) 1665 { 1666 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1667 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1668 1669 if (GET_CODE (expr) == CLOBBER | 1658 { 1659 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1660 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1661 1662 mo->type = MO_USE; 1663 mo->u.loc = *loc; 1664 mo->insn = (rtx) insn; 1665 } --- 17 unchanged lines hidden (view full) --- 1683add_stores (rtx loc, rtx expr, void *insn) 1684{ 1685 if (REG_P (loc)) 1686 { 1687 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1688 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1689 1690 if (GET_CODE (expr) == CLOBBER |
1670 || ! REG_EXPR (loc) 1671 || ! track_expr_p (REG_EXPR (loc))) | 1691 || !(REG_EXPR (loc) 1692 && track_expr_p (REG_EXPR (loc)) 1693 && offset_valid_for_tracked_p (REG_OFFSET (loc)))) |
1672 mo->type = MO_CLOBBER; 1673 else if (GET_CODE (expr) == SET 1674 && SET_DEST (expr) == loc 1675 && same_variable_part_p (SET_SRC (expr), 1676 REG_EXPR (loc), 1677 REG_OFFSET (loc))) 1678 mo->type = MO_COPY; 1679 else 1680 mo->type = MO_SET; 1681 mo->u.loc = loc; 1682 mo->insn = NEXT_INSN ((rtx) insn); 1683 } 1684 else if (MEM_P (loc) 1685 && MEM_EXPR (loc) | 1694 mo->type = MO_CLOBBER; 1695 else if (GET_CODE (expr) == SET 1696 && SET_DEST (expr) == loc 1697 && same_variable_part_p (SET_SRC (expr), 1698 REG_EXPR (loc), 1699 REG_OFFSET (loc))) 1700 mo->type = MO_COPY; 1701 else 1702 mo->type = MO_SET; 1703 mo->u.loc = loc; 1704 mo->insn = NEXT_INSN ((rtx) insn); 1705 } 1706 else if (MEM_P (loc) 1707 && MEM_EXPR (loc) |
1686 && track_expr_p (MEM_EXPR (loc))) | 1708 && track_expr_p (MEM_EXPR (loc)) 1709 && offset_valid_for_tracked_p (INT_MEM_OFFSET (loc))) |
1687 { 1688 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1689 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1690 1691 if (GET_CODE (expr) == CLOBBER) 1692 mo->type = MO_CLOBBER; 1693 else if (GET_CODE (expr) == SET 1694 && SET_DEST (expr) == loc 1695 && same_variable_part_p (SET_SRC (expr), 1696 MEM_EXPR (loc), | 1710 { 1711 basic_block bb = BLOCK_FOR_INSN ((rtx) insn); 1712 micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; 1713 1714 if (GET_CODE (expr) == CLOBBER) 1715 mo->type = MO_CLOBBER; 1716 else if (GET_CODE (expr) == SET 1717 && SET_DEST (expr) == loc 1718 && same_variable_part_p (SET_SRC (expr), 1719 MEM_EXPR (loc), |
1697 MEM_OFFSET (loc) 1698 ? INTVAL (MEM_OFFSET (loc)) : 0)) | 1720 INT_MEM_OFFSET (loc))) |
1699 mo->type = MO_COPY; 1700 else 1701 mo->type = MO_SET; 1702 mo->u.loc = loc; 1703 mo->insn = NEXT_INSN ((rtx) insn); 1704 } 1705} 1706 --- 1014 unchanged lines hidden (view full) --- 2721 return true; 2722 } 2723 } 2724 else if (MEM_P (rtl)) 2725 { 2726 if (MEM_ATTRS (rtl)) 2727 { 2728 *declp = MEM_EXPR (rtl); | 1721 mo->type = MO_COPY; 1722 else 1723 mo->type = MO_SET; 1724 mo->u.loc = loc; 1725 mo->insn = NEXT_INSN ((rtx) insn); 1726 } 1727} 1728 --- 1014 unchanged lines hidden (view full) --- 2743 return true; 2744 } 2745 } 2746 else if (MEM_P (rtl)) 2747 { 2748 if (MEM_ATTRS (rtl)) 2749 { 2750 *declp = MEM_EXPR (rtl); |
2729 *offsetp = MEM_OFFSET (rtl) ? INTVAL (MEM_OFFSET (rtl)) : 0; | 2751 *offsetp = INT_MEM_OFFSET (rtl); |
2730 return true; 2731 } 2732 } 2733 return false; 2734} 2735 2736/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */ 2737 --- 276 unchanged lines hidden --- | 2752 return true; 2753 } 2754 } 2755 return false; 2756} 2757 2758/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */ 2759 --- 276 unchanged lines hidden --- |