Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* Transformations based on profile information for values. | 1 /* Transformations based on profile information for values. |
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 | 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
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 |
8 the terms of the GNU General Public License as published by the Free | 8 the terms of the GNU General Public License as published by the Free |
9 Software Foundation; either version 3, or (at your option) any later | 9 Software Foundation; either version 3, or (at your option) any later |
10 version. | 10 version. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type, | 87 static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type, |
88 gcov_type); | 88 gcov_type); |
89 static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *); | 89 static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *); |
90 static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *); | 90 static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *); |
91 static bool gimple_mod_subtract_transform (gimple_stmt_iterator *); | 91 static bool gimple_mod_subtract_transform (gimple_stmt_iterator *); |
92 static bool gimple_stringops_transform (gimple_stmt_iterator *); | 92 static bool gimple_stringops_transform (gimple_stmt_iterator *); |
93 static bool gimple_ic_transform (gimple); | 93 static bool gimple_ic_transform (gimple); |
94 | 94 |
95 /* Allocate histogram value. */ | 95 /* Allocate histogram value. */ |
96 | 96 |
97 static histogram_value | 97 histogram_value |
98 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED, | 98 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED, |
99 enum hist_type type, gimple stmt, tree value) | 99 enum hist_type type, gimple stmt, tree value) |
100 { | 100 { |
101 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist)); | 101 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist)); |
102 hist->hvalue.value = value; | 102 hist->hvalue.value = value; |
103 hist->hvalue.stmt = stmt; | 103 hist->hvalue.stmt = stmt; |
104 hist->type = type; | 104 hist->type = type; |
105 return hist; | 105 return hist; |
106 } | 106 } |
107 | 107 |
(...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1198 } | 1198 } |
1199 else | 1199 else |
1200 error ("Inconsistent profile: indirect call target (%d) does not exist", func_id); | 1200 error ("Inconsistent profile: indirect call target (%d) does not exist", func_id); |
1201 | 1201 |
1202 return NULL; | 1202 return NULL; |
1203 } | 1203 } |
1204 | 1204 |
1205 return VEC_index (cgraph_node_ptr, cgraph_node_map, func_id); | 1205 return VEC_index (cgraph_node_ptr, cgraph_node_map, func_id); |
1206 } | 1206 } |
1207 | 1207 |
1208 /* Return cgraph node for function with name. We need this because | |
1209 AutoFDO doesn't record the function id for each function | |
1210 in the profile. | |
1211 TODO: need to transform this lookup method to hash table. */ | |
1212 | |
1213 static struct cgraph_node * | |
1214 find_func_by_name (char *name) | |
1215 { | |
1216 struct cgraph_node *n; | |
1217 struct cgraph_node *ret = NULL; | |
1218 int match = 0; | |
1219 | |
1220 for (n = cgraph_nodes; n; n = n->next) | |
1221 { | |
1222 const char *fname = IDENTIFIER_POINTER (decl_assembler_name (n->decl)); | |
1223 if (!strcmp(fname, name)) | |
davidxl
2013/04/17 17:18:37
You can use assembler_name_hash to find the cgraph
dehao
2013/04/17 20:56:17
Done.
| |
1224 { | |
1225 match ++; | |
1226 ret = n; | |
1227 } | |
1228 } | |
1229 if (match == 1) | |
1230 return ret; | |
1231 else | |
1232 return NULL; | |
1233 } | |
1234 | |
1208 /* Initialize map of gids (gid -> cgraph node) */ | 1235 /* Initialize map of gids (gid -> cgraph node) */ |
1209 | 1236 |
1210 static htab_t gid_map = NULL; | 1237 static htab_t gid_map = NULL; |
1211 | 1238 |
1212 typedef struct func_gid_entry | 1239 typedef struct func_gid_entry |
1213 { | 1240 { |
1214 struct cgraph_node *node; | 1241 struct cgraph_node *node; |
1215 unsigned HOST_WIDEST_INT gid; | 1242 unsigned HOST_WIDEST_INT gid; |
1216 } func_gid_entry_t; | 1243 } func_gid_entry_t; |
1217 | 1244 |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1555 gcov_type prob1, prob2; | 1582 gcov_type prob1, prob2; |
1556 gimple modify1, modify2; | 1583 gimple modify1, modify2; |
1557 struct cgraph_node *direct_call1 = 0, *direct_call2 = 0; | 1584 struct cgraph_node *direct_call1 = 0, *direct_call2 = 0; |
1558 int perc_threshold, count_threshold, always_inline; | 1585 int perc_threshold, count_threshold, always_inline; |
1559 location_t locus; | 1586 location_t locus; |
1560 | 1587 |
1561 val1 = histogram->hvalue.counters [1]; | 1588 val1 = histogram->hvalue.counters [1]; |
1562 count1 = histogram->hvalue.counters [2]; | 1589 count1 = histogram->hvalue.counters [2]; |
1563 val2 = histogram->hvalue.counters [3]; | 1590 val2 = histogram->hvalue.counters [3]; |
1564 count2 = histogram->hvalue.counters [4]; | 1591 count2 = histogram->hvalue.counters [4]; |
1565 bb_all = gimple_bb (stmt)->count; | 1592 bb_all = flag_auto_profile ? histogram->hvalue.counters[0] |
1593 » » » : gimple_bb (stmt)->count; | |
1566 all = bb_all; | 1594 all = bb_all; |
1567 | 1595 |
1568 gimple_remove_histogram_value (cfun, stmt, histogram); | 1596 gimple_remove_histogram_value (cfun, stmt, histogram); |
1569 | 1597 |
1570 if (count1 == 0) | 1598 if (count1 == 0) |
1571 return false; | 1599 return false; |
1572 | 1600 |
1573 perc_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_PERCENT_THRESHOLD); | 1601 perc_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_PERCENT_THRESHOLD); |
1574 count_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_COUNT_THRESHOLD); | 1602 count_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_COUNT_THRESHOLD); |
1575 always_inline = PARAM_VALUE (PARAM_ALWAYS_INLINE_ICALL_TARGET); | 1603 always_inline = PARAM_VALUE (PARAM_ALWAYS_INLINE_ICALL_TARGET); |
1576 | 1604 |
1577 if (100 * count1 < all * perc_threshold || count1 < count_threshold) | 1605 if (100 * count1 < all * perc_threshold || count1 < count_threshold) |
1578 return false; | 1606 return false; |
1579 | 1607 |
1580 if (check_ic_counter (stmt, &count1, &count2, all)) | 1608 if (check_ic_counter (stmt, &count1, &count2, all)) |
1581 return false; | 1609 return false; |
1582 | 1610 |
1583 if (all > 0) | 1611 if (all > 0) |
1584 { | 1612 { |
1585 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all; | 1613 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all; |
1586 if (all - count1 > 0) | 1614 if (all - count1 > 0) |
1587 prob2 = (count2 * REG_BR_PROB_BASE | 1615 prob2 = (count2 * REG_BR_PROB_BASE |
1588 + (all - count1) / 2) / (all - count1); | 1616 + (all - count1) / 2) / (all - count1); |
1589 else | 1617 else |
1590 prob2 = 0; | 1618 prob2 = 0; |
1591 } | 1619 } |
1592 else | 1620 else |
1593 prob1 = prob2 = 0; | 1621 prob1 = prob2 = 0; |
1594 | 1622 |
1595 direct_call1 = find_func_by_global_id (val1); | 1623 if (flag_auto_profile) |
1624 direct_call1 = find_func_by_name ((char *) val1); | |
1625 else | |
1626 direct_call1 = find_func_by_global_id (val1); | |
davidxl
2013/04/17 17:18:37
May be add a parameter to find_func_by_global_id (
dehao
2013/04/17 20:56:17
Done.
| |
1596 | 1627 |
1597 if (val2 && (100 * count2 >= all * perc_threshold) | 1628 if (val2 && (100 * count2 >= all * perc_threshold) |
1598 && count2 > count_threshold) | 1629 && count2 > count_threshold) |
1599 direct_call2 = find_func_by_global_id (val2); | 1630 { |
1631 if (flag_auto_profile) | |
1632 » direct_call2 = find_func_by_name ((char *) val2); | |
1633 else | |
1634 » direct_call2 = find_func_by_global_id (val2); | |
1635 } | |
1600 | 1636 |
1601 locus = (stmt != NULL) ? gimple_location (stmt) | 1637 locus = (stmt != NULL) ? gimple_location (stmt) |
1602 : DECL_SOURCE_LOCATION (current_function_decl); | 1638 : DECL_SOURCE_LOCATION (current_function_decl); |
1603 if (direct_call1 == NULL | 1639 if (direct_call1 == NULL |
1604 || !check_ic_target (stmt, direct_call1)) | 1640 || !check_ic_target (stmt, direct_call1)) |
1605 { | 1641 { |
1606 if (flag_opt_info >= OPT_INFO_MAX) | 1642 if (flag_opt_info >= OPT_INFO_MAX && !flag_auto_profile) |
1607 { | 1643 { |
1608 if (!direct_call1) | 1644 if (!direct_call1) |
1609 inform (locus, "Can not find indirect call target decl " | 1645 inform (locus, "Can not find indirect call target decl " |
1610 "(%d:%d)[cnt:%u] in current module", | 1646 "(%d:%d)[cnt:%u] in current module", |
1611 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), | 1647 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), |
1612 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1); | 1648 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1); |
1613 else | 1649 else |
1614 inform (locus, | 1650 inform (locus, |
1615 "Can not find promote indirect call target decl -- type mism atch " | 1651 "Can not find promote indirect call target decl -- type mism atch " |
1616 "(%d:%d)[cnt:%u] in current module", | 1652 "(%d:%d)[cnt:%u] in current module", |
(...skipping 21 matching lines...) Expand all Loading... | |
1638 { | 1674 { |
1639 /* TODO: should mark the call edge. */ | 1675 /* TODO: should mark the call edge. */ |
1640 DECL_DISREGARD_INLINE_LIMITS (direct_call1->decl) = 1; | 1676 DECL_DISREGARD_INLINE_LIMITS (direct_call1->decl) = 1; |
1641 } | 1677 } |
1642 if (dump_file) | 1678 if (dump_file) |
1643 { | 1679 { |
1644 fprintf (dump_file, "Indirect call -> direct call "); | 1680 fprintf (dump_file, "Indirect call -> direct call "); |
1645 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); | 1681 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); |
1646 fprintf (dump_file, "=> "); | 1682 fprintf (dump_file, "=> "); |
1647 print_generic_expr (dump_file, direct_call1->decl, TDF_SLIM); | 1683 print_generic_expr (dump_file, direct_call1->decl, TDF_SLIM); |
1648 fprintf (dump_file, " (module_id:%d, func_id:%d)\n", | 1684 if (flag_auto_profile) |
1649 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), | 1685 » fprintf (dump_file, " (%s)\n", (char *) val1); |
1650 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1)); | 1686 else |
1687 » fprintf (dump_file, " (module_id:%d, func_id:%d)\n", | |
1688 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1), | |
1689 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1)); | |
1651 fprintf (dump_file, "Transformation on insn:\n"); | 1690 fprintf (dump_file, "Transformation on insn:\n"); |
1652 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | 1691 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); |
1653 fprintf (dump_file, "==>\n"); | 1692 fprintf (dump_file, "==>\n"); |
1654 print_gimple_stmt (dump_file, modify1, 0, TDF_SLIM); | 1693 print_gimple_stmt (dump_file, modify1, 0, TDF_SLIM); |
1655 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC | 1694 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC |
1656 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count1, all); | 1695 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count1, all); |
1657 } | 1696 } |
1658 | 1697 |
1659 if (direct_call2 && check_ic_target (stmt, direct_call2) | 1698 if (direct_call2 && check_ic_target (stmt, direct_call2) |
1660 /* Don't indirect-call promote if the target is in auxiliary module and | 1699 /* Don't indirect-call promote if the target is in auxiliary module and |
(...skipping 15 matching lines...) Expand all Loading... | |
1676 { | 1715 { |
1677 /* TODO: should mark the call edge. */ | 1716 /* TODO: should mark the call edge. */ |
1678 DECL_DISREGARD_INLINE_LIMITS (direct_call2->decl) = 1; | 1717 DECL_DISREGARD_INLINE_LIMITS (direct_call2->decl) = 1; |
1679 } | 1718 } |
1680 if (dump_file) | 1719 if (dump_file) |
1681 { | 1720 { |
1682 fprintf (dump_file, "Indirect call -> direct call "); | 1721 fprintf (dump_file, "Indirect call -> direct call "); |
1683 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); | 1722 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); |
1684 fprintf (dump_file, "=> "); | 1723 fprintf (dump_file, "=> "); |
1685 print_generic_expr (dump_file, direct_call2->decl, TDF_SLIM); | 1724 print_generic_expr (dump_file, direct_call2->decl, TDF_SLIM); |
1686 fprintf (dump_file, " (module_id:%d, func_id:%d)\n", | 1725 » if (flag_auto_profile) |
1687 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val2), | 1726 » fprintf (dump_file, " (%s)\n", (char *) val2); |
1688 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val2)); | 1727 » else |
1728 » fprintf (dump_file, " (module_id:%d, func_id:%d)\n", | |
1729 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val2), | |
1730 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val2)); | |
1689 fprintf (dump_file, "Transformation on insn\n"); | 1731 fprintf (dump_file, "Transformation on insn\n"); |
1690 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | 1732 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); |
1691 fprintf (dump_file, "=>\n"); | 1733 fprintf (dump_file, "=>\n"); |
1692 print_gimple_stmt (dump_file, modify2, 0, TDF_SLIM); | 1734 print_gimple_stmt (dump_file, modify2, 0, TDF_SLIM); |
1693 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC | 1735 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC |
1694 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count2, | 1736 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count2, |
1695 all - count1); | 1737 all - count1); |
1696 } | 1738 } |
1697 } | 1739 } |
1698 | 1740 |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2204 gcc_unreachable (); | 2246 gcc_unreachable (); |
2205 } | 2247 } |
2206 if (dump_file) | 2248 if (dump_file) |
2207 { | 2249 { |
2208 fprintf (dump_file, "Stmt "); | 2250 fprintf (dump_file, "Stmt "); |
2209 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM); | 2251 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM); |
2210 dump_histogram_value (dump_file, hist); | 2252 dump_histogram_value (dump_file, hist); |
2211 } | 2253 } |
2212 } | 2254 } |
2213 } | 2255 } |
OLD | NEW |