The attached patch defines a new parameter to decide if icall promotion (LIPO) is using a new hotness based heuristic or not. (See Honza's speculative call support patch for reference).
David
Index: params.def =================================================================== --- params.def (revision 201420) +++ params.def (working copy) @@ -903,6 +903,13 @@ DEFPARAM (PARAM_ALWAYS_INLINE_ICALL_TARG "force inline indirect call target when promoted", 0, 0, 0) +/* Do not check the icall target count distribution, but use + hotness info to decide if promotion should be done. */ +DEFPARAM (PARAM_ICALL_USE_HOTNESS_HEUR, + "icall-use-hotness-heur", + "use hotness based heuristics to match inliner", + 0, 0, 0) + /* Force the compiler to be in LIPO mode even there is no profile data available. -fripa is also needed. */ DEFPARAM (PARAM_FORCE_LIPO_MODE, Index: value-prof.c =================================================================== --- value-prof.c (revision 201419) +++ value-prof.c (working copy) @@ -1558,6 +1558,7 @@ gimple_ic_transform_mult_targ (gimple st gimple modify1, modify2; struct cgraph_node *direct_call1 = 0, *direct_call2 = 0; int perc_threshold, count_threshold, always_inline; + int use_hotness_heur = false; location_t locus; val1 = histogram->hvalue.counters [1]; @@ -1576,9 +1577,18 @@ gimple_ic_transform_mult_targ (gimple st perc_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_PERCENT_THRESHOLD); count_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_COUNT_THRESHOLD); always_inline = PARAM_VALUE (PARAM_ALWAYS_INLINE_ICALL_TARGET); + use_hotness_heur = PARAM_VALUE (PARAM_ICALL_USE_HOTNESS_HEUR); - if (100 * count1 < all * perc_threshold || count1 < count_threshold) - return false; + if (!use_hotness_heur) + { + if (100 * count1 < all * perc_threshold || count1 < count_threshold) + return false; + } + else + { + if (!maybe_hot_count_p (cfun, count1)) + return false; + } if (check_ic_counter (stmt, &count1, &count2, all)) return false; @@ -1597,9 +1607,17 @@ gimple_ic_transform_mult_targ (gimple st direct_call1 = find_func_by_global_id (val1, flag_auto_profile); - if (val2 && (100 * count2 >= all * perc_threshold) - && count2 > count_threshold) - direct_call2 = find_func_by_global_id (val2, flag_auto_profile); + if (!use_hotness_heur) + { + if (val2 && (100 * count2 >= all * perc_threshold) + && count2 > count_threshold) + direct_call2 = find_func_by_global_id (val2, flag_auto_profile); + } + else + { + if (maybe_hot_count_p (cfun, count2)) + direct_call2 = find_func_by_global_id (val2, flag_auto_profile); + } locus = (stmt != NULL) ? gimple_location (stmt) : DECL_SOURCE_LOCATION (current_function_decl);