1 /* Read and annotate call graph profile from the auto profile data file.
2 Copyright (C) 2014-2015 Free Software Foundation, Inc.
3 Contributed by Dehao Chen (dehao@google.com)
5 This file is part of GCC.
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
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
28 #include "coretypes.h"
33 #include "fold-const.h"
34 #include "tree-pass.h"
38 #include "hard-reg-set.h"
40 #include "dominance.h"
42 #include "basic-block.h"
43 #include "diagnostic-core.h"
46 #include "langhooks.h"
48 #include "tree-pass.h"
50 #include "tree-ssa-alias.h"
52 #include "tree-cfgcleanup.h"
53 #include "tree-ssa-operands.h"
54 #include "tree-into-ssa.h"
55 #include "internal-fn.h"
56 #include "gimple-expr.h"
58 #include "gimple-iterator.h"
59 #include "gimple-ssa.h"
60 #include "plugin-api.h"
63 #include "value-prof.h"
66 #include "alloc-pool.h"
67 #include "symbol-summary.h"
69 #include "ipa-inline.h"
70 #include "tree-inline.h"
71 #include "stringpool.h"
72 #include "auto-profile.h"
74 /* The following routines implements AutoFDO optimization.
76 This optimization uses sampling profiles to annotate basic block counts
77 and uses heuristics to estimate branch probabilities.
79 There are three phases in AutoFDO:
81 Phase 1: Read profile from the profile data file.
82 The following info is read from the profile datafile:
83 * string_table: a map between function name and its index.
84 * autofdo_source_profile: a map from function_instance name to
85 function_instance. This is represented as a forest of
87 * WorkingSet: a histogram of how many instructions are covered for a
88 given percentage of total cycles. This is describing the binary
89 level information (not source level). This info is used to help
90 decide if we want aggressive optimizations that could increase
91 code footprint (e.g. loop unroll etc.)
92 A function instance is an instance of function that could either be a
93 standalone symbol, or a clone of a function that is inlined into another
96 Phase 2: Early inline + value profile transformation.
97 Early inline uses autofdo_source_profile to find if a callsite is:
98 * inlined in the profiled binary.
99 * callee body is hot in the profiling run.
100 If both condition satisfies, early inline will inline the callsite
101 regardless of the code growth.
102 Phase 2 is an iterative process. During each iteration, we also check
103 if an indirect callsite is promoted and inlined in the profiling run.
104 If yes, vpt will happen to force promote it and in the next iteration,
105 einline will inline the promoted callsite in the next iteration.
107 Phase 3: Annotate control flow graph.
108 AutoFDO uses a separate pass to:
109 * Annotate basic block count
110 * Estimate branch probability
112 After the above 3 phases, all profile is readily annotated on the GCC IR.
113 AutoFDO tries to reuse all FDO infrastructure as much as possible to make
114 use of the profile. E.g. it uses existing mechanism to calculate the basic
115 block/edge frequency, as well as the cgraph node/edge count.
118 #define DEFAULT_AUTO_PROFILE_FILE "fbdata.afdo"
119 #define AUTO_PROFILE_VERSION 1
124 /* Represent a source location: (function_decl, lineno). */
125 typedef std::pair
<tree
, unsigned> decl_lineno
;
127 /* Represent an inline stack. vector[0] is the leaf node. */
128 typedef auto_vec
<decl_lineno
> inline_stack
;
130 /* String array that stores function names. */
131 typedef auto_vec
<char *> string_vector
;
133 /* Map from function name's index in string_table to target's
135 typedef std::map
<unsigned, gcov_type
> icall_target_map
;
137 /* Set of gimple stmts. Used to track if the stmt has already been promoted
139 typedef std::set
<gimple
> stmt_set
;
141 /* Represent count info of an inline stack. */
144 /* Sampled count of the inline stack. */
147 /* Map from indirect call target to its sample count. */
148 icall_target_map targets
;
150 /* Whether this inline stack is already used in annotation.
152 Each inline stack should only be used to annotate IR once.
153 This will be enforced when instruction-level discriminator
158 /* operator< for "const char *". */
159 struct string_compare
161 bool operator()(const char *a
, const char *b
) const
163 return strcmp (a
, b
) < 0;
167 /* Store a string array, indexed by string position in the array. */
176 /* For a given string, returns its index. */
177 int get_index (const char *name
) const;
179 /* For a given decl, returns the index of the decl name. */
180 int get_index_by_decl (tree decl
) const;
182 /* For a given index, returns the string. */
183 const char *get_name (int index
) const;
185 /* Read profile, return TRUE on success. */
189 typedef std::map
<const char *, unsigned, string_compare
> string_index_map
;
190 string_vector vector_
;
191 string_index_map map_
;
194 /* Profile of a function instance:
195 1. total_count of the function.
196 2. head_count (entry basic block count) of the function (only valid when
197 function is a top-level function_instance, i.e. it is the original copy
198 instead of the inlined copy).
199 3. map from source location (decl_lineno) to profile (count_info).
200 4. map from callsite to callee function_instance. */
201 class function_instance
204 typedef auto_vec
<function_instance
*> function_instance_stack
;
206 /* Read the profile and return a function_instance with head count as
207 HEAD_COUNT. Recursively read callsites to create nested function_instances
208 too. STACK is used to track the recursive creation process. */
209 static function_instance
*
210 read_function_instance (function_instance_stack
*stack
,
211 gcov_type head_count
);
213 /* Recursively deallocate all callsites (nested function_instances). */
214 ~function_instance ();
233 /* Traverse callsites of the current function_instance to find one at the
234 location of LINENO and callee name represented in DECL. */
235 function_instance
*get_function_instance_by_decl (unsigned lineno
,
238 /* Store the profile info for LOC in INFO. Return TRUE if profile info
240 bool get_count_info (location_t loc
, count_info
*info
) const;
242 /* Read the inlined indirect call target profile for STMT and store it in
243 MAP, return the total count for all inlined indirect calls. */
244 gcov_type
find_icall_target_map (gcall
*stmt
, icall_target_map
*map
) const;
246 /* Sum of counts that is used during annotation. */
247 gcov_type
total_annotated_count () const;
249 /* Mark LOC as annotated. */
250 void mark_annotated (location_t loc
);
253 /* Callsite, represented as (decl_lineno, callee_function_name_index). */
254 typedef std::pair
<unsigned, unsigned> callsite
;
256 /* Map from callsite to callee function_instance. */
257 typedef std::map
<callsite
, function_instance
*> callsite_map
;
259 function_instance (unsigned name
, gcov_type head_count
)
260 : name_ (name
), total_count_ (0), head_count_ (head_count
)
264 /* Map from source location (decl_lineno) to profile (count_info). */
265 typedef std::map
<unsigned, count_info
> position_count_map
;
267 /* function_instance name index in the string_table. */
270 /* Total sample count. */
271 gcov_type total_count_
;
273 /* Entry BB's sample count. */
274 gcov_type head_count_
;
276 /* Map from callsite location to callee function_instance. */
277 callsite_map callsites
;
279 /* Map from source location to count_info. */
280 position_count_map pos_counts
;
283 /* Profile for all functions. */
284 class autofdo_source_profile
287 static autofdo_source_profile
*
290 autofdo_source_profile
*map
= new autofdo_source_profile ();
298 ~autofdo_source_profile ();
300 /* For a given DECL, returns the top-level function_instance. */
301 function_instance
*get_function_instance_by_decl (tree decl
) const;
303 /* Find count_info for a given gimple STMT. If found, store the count_info
304 in INFO and return true; otherwise return false. */
305 bool get_count_info (gimple stmt
, count_info
*info
) const;
307 /* Find total count of the callee of EDGE. */
308 gcov_type
get_callsite_total_count (struct cgraph_edge
*edge
) const;
310 /* Update value profile INFO for STMT from the inlined indirect callsite.
311 Return true if INFO is updated. */
312 bool update_inlined_ind_target (gcall
*stmt
, count_info
*info
);
314 /* Mark LOC as annotated. */
315 void mark_annotated (location_t loc
);
318 /* Map from function_instance name index (in string_table) to
319 function_instance. */
320 typedef std::map
<unsigned, function_instance
*> name_function_instance_map
;
322 autofdo_source_profile () {}
324 /* Read AutoFDO profile and returns TRUE on success. */
327 /* Return the function_instance in the profile that correspond to the
330 get_function_instance_by_inline_stack (const inline_stack
&stack
) const;
332 name_function_instance_map map_
;
335 /* Store the strings read from the profile data file. */
336 static string_table
*afdo_string_table
;
338 /* Store the AutoFDO source profile. */
339 static autofdo_source_profile
*afdo_source_profile
;
341 /* gcov_ctr_summary structure to store the profile_info. */
342 static struct gcov_ctr_summary
*afdo_profile_info
;
344 /* Helper functions. */
346 /* Return the original name of NAME: strip the suffix that starts
347 with '.' Caller is responsible for freeing RET. */
350 get_original_name (const char *name
)
352 char *ret
= xstrdup (name
);
353 char *find
= strchr (ret
, '.');
359 /* Return the combined location, which is a 32bit integer in which
360 higher 16 bits stores the line offset of LOC to the start lineno
361 of DECL, The lower 16 bits stores the discriminator. */
364 get_combined_location (location_t loc
, tree decl
)
366 /* TODO: allow more bits for line and less bits for discriminator. */
367 if (LOCATION_LINE (loc
) - DECL_SOURCE_LINE (decl
) >= (1<<16))
368 warning_at (loc
, OPT_Woverflow
, "Offset exceeds 16 bytes.");
369 return ((LOCATION_LINE (loc
) - DECL_SOURCE_LINE (decl
)) << 16);
372 /* Return the function decl of a given lexical BLOCK. */
375 get_function_decl_from_block (tree block
)
379 if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block
) == UNKNOWN_LOCATION
))
382 for (decl
= BLOCK_ABSTRACT_ORIGIN (block
);
383 decl
&& (TREE_CODE (decl
) == BLOCK
);
384 decl
= BLOCK_ABSTRACT_ORIGIN (decl
))
385 if (TREE_CODE (decl
) == FUNCTION_DECL
)
390 /* Store inline stack for STMT in STACK. */
393 get_inline_stack (location_t locus
, inline_stack
*stack
)
395 if (LOCATION_LOCUS (locus
) == UNKNOWN_LOCATION
)
398 tree block
= LOCATION_BLOCK (locus
);
399 if (block
&& TREE_CODE (block
) == BLOCK
)
402 for (block
= BLOCK_SUPERCONTEXT (block
);
403 block
&& (TREE_CODE (block
) == BLOCK
);
404 block
= BLOCK_SUPERCONTEXT (block
))
406 location_t tmp_locus
= BLOCK_SOURCE_LOCATION (block
);
407 if (LOCATION_LOCUS (tmp_locus
) == UNKNOWN_LOCATION
)
410 tree decl
= get_function_decl_from_block (block
);
412 std::make_pair (decl
, get_combined_location (locus
, decl
)));
418 std::make_pair (current_function_decl
,
419 get_combined_location (locus
, current_function_decl
)));
422 /* Return STMT's combined location, which is a 32bit integer in which
423 higher 16 bits stores the line offset of LOC to the start lineno
424 of DECL, The lower 16 bits stores the discriminator. */
427 get_relative_location_for_stmt (gimple stmt
)
429 location_t locus
= gimple_location (stmt
);
430 if (LOCATION_LOCUS (locus
) == UNKNOWN_LOCATION
)
431 return UNKNOWN_LOCATION
;
433 for (tree block
= gimple_block (stmt
); block
&& (TREE_CODE (block
) == BLOCK
);
434 block
= BLOCK_SUPERCONTEXT (block
))
435 if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block
)) != UNKNOWN_LOCATION
)
436 return get_combined_location (locus
,
437 get_function_decl_from_block (block
));
438 return get_combined_location (locus
, current_function_decl
);
441 /* Return true if BB contains indirect call. */
444 has_indirect_call (basic_block bb
)
446 gimple_stmt_iterator gsi
;
448 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
450 gimple stmt
= gsi_stmt (gsi
);
451 if (gimple_code (stmt
) == GIMPLE_CALL
&& !gimple_call_internal_p (stmt
)
452 && (gimple_call_fn (stmt
) == NULL
453 || TREE_CODE (gimple_call_fn (stmt
)) != FUNCTION_DECL
))
459 /* Member functions for string_table. */
463 string_table::~string_table ()
465 for (unsigned i
= 0; i
< vector_
.length (); i
++)
470 /* Return the index of a given function NAME. Return -1 if NAME is not
471 found in string table. */
474 string_table::get_index (const char *name
) const
478 string_index_map::const_iterator iter
= map_
.find (name
);
479 if (iter
== map_
.end ())
485 /* Return the index of a given function DECL. Return -1 if DECL is not
486 found in string table. */
489 string_table::get_index_by_decl (tree decl
) const
492 = get_original_name (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
)));
493 int ret
= get_index (name
);
497 ret
= get_index (lang_hooks
.dwarf_name (decl
, 0));
500 if (DECL_ABSTRACT_ORIGIN (decl
))
501 return get_index_by_decl (DECL_ABSTRACT_ORIGIN (decl
));
506 /* Return the function name of a given INDEX. */
509 string_table::get_name (int index
) const
511 gcc_assert (index
> 0 && index
< (int)vector_
.length ());
512 return vector_
[index
];
515 /* Read the string table. Return TRUE if reading is successful. */
518 string_table::read ()
520 if (gcov_read_unsigned () != GCOV_TAG_AFDO_FILE_NAMES
)
522 /* Skip the length of the section. */
523 gcov_read_unsigned ();
524 /* Read in the file name table. */
525 unsigned string_num
= gcov_read_unsigned ();
526 for (unsigned i
= 0; i
< string_num
; i
++)
528 vector_
.safe_push (get_original_name (gcov_read_string ()));
529 map_
[vector_
.last ()] = i
;
534 /* Member functions for function_instance. */
536 function_instance::~function_instance ()
538 for (callsite_map::iterator iter
= callsites
.begin ();
539 iter
!= callsites
.end (); ++iter
)
543 /* Traverse callsites of the current function_instance to find one at the
544 location of LINENO and callee name represented in DECL. */
547 function_instance::get_function_instance_by_decl (unsigned lineno
,
550 int func_name_idx
= afdo_string_table
->get_index_by_decl (decl
);
551 if (func_name_idx
!= -1)
553 callsite_map::const_iterator ret
554 = callsites
.find (std::make_pair (lineno
, func_name_idx
));
555 if (ret
!= callsites
.end ())
559 = afdo_string_table
->get_index (lang_hooks
.dwarf_name (decl
, 0));
560 if (func_name_idx
!= -1)
562 callsite_map::const_iterator ret
563 = callsites
.find (std::make_pair (lineno
, func_name_idx
));
564 if (ret
!= callsites
.end ())
567 if (DECL_ABSTRACT_ORIGIN (decl
))
568 return get_function_instance_by_decl (lineno
, DECL_ABSTRACT_ORIGIN (decl
));
573 /* Store the profile info for LOC in INFO. Return TRUE if profile info
577 function_instance::get_count_info (location_t loc
, count_info
*info
) const
579 position_count_map::const_iterator iter
= pos_counts
.find (loc
);
580 if (iter
== pos_counts
.end ())
582 *info
= iter
->second
;
586 /* Mark LOC as annotated. */
589 function_instance::mark_annotated (location_t loc
)
591 position_count_map::iterator iter
= pos_counts
.find (loc
);
592 if (iter
== pos_counts
.end ())
594 iter
->second
.annotated
= true;
597 /* Read the inlined indirect call target profile for STMT and store it in
598 MAP, return the total count for all inlined indirect calls. */
601 function_instance::find_icall_target_map (gcall
*stmt
,
602 icall_target_map
*map
) const
605 unsigned stmt_offset
= get_relative_location_for_stmt (stmt
);
607 for (callsite_map::const_iterator iter
= callsites
.begin ();
608 iter
!= callsites
.end (); ++iter
)
610 unsigned callee
= iter
->second
->name ();
611 /* Check if callsite location match the stmt. */
612 if (iter
->first
.first
!= stmt_offset
)
614 struct cgraph_node
*node
= cgraph_node::get_for_asmname (
615 get_identifier (afdo_string_table
->get_name (callee
)));
618 if (!check_ic_target (stmt
, node
))
620 (*map
)[callee
] = iter
->second
->total_count ();
621 ret
+= iter
->second
->total_count ();
626 /* Read the profile and create a function_instance with head count as
627 HEAD_COUNT. Recursively read callsites to create nested function_instances
628 too. STACK is used to track the recursive creation process. */
630 /* function instance profile format:
634 NUM_POS_COUNTS: 4 bytes
635 NUM_CALLSITES: 4 byte
637 POS_1_OFFSET: 4 bytes
641 VALUE_PROFILE_TYPE: 4 bytes
651 CALLSITE_1_OFFSET: 4 bytes
652 FUNCTION_INSTANCE_PROFILE (nested)
658 function_instance::read_function_instance (function_instance_stack
*stack
,
659 gcov_type head_count
)
661 unsigned name
= gcov_read_unsigned ();
662 unsigned num_pos_counts
= gcov_read_unsigned ();
663 unsigned num_callsites
= gcov_read_unsigned ();
664 function_instance
*s
= new function_instance (name
, head_count
);
665 stack
->safe_push (s
);
667 for (unsigned i
= 0; i
< num_pos_counts
; i
++)
669 unsigned offset
= gcov_read_unsigned () & 0xffff0000;
670 unsigned num_targets
= gcov_read_unsigned ();
671 gcov_type count
= gcov_read_counter ();
672 s
->pos_counts
[offset
].count
= count
;
673 for (unsigned j
= 0; j
< stack
->length (); j
++)
674 (*stack
)[j
]->total_count_
+= count
;
675 for (unsigned j
= 0; j
< num_targets
; j
++)
677 /* Only indirect call target histogram is supported now. */
678 gcov_read_unsigned ();
679 gcov_type target_idx
= gcov_read_counter ();
680 s
->pos_counts
[offset
].targets
[target_idx
] = gcov_read_counter ();
683 for (unsigned i
= 0; i
< num_callsites
; i
++)
685 unsigned offset
= gcov_read_unsigned ();
686 function_instance
*callee_function_instance
687 = read_function_instance (stack
, 0);
688 s
->callsites
[std::make_pair (offset
, callee_function_instance
->name ())]
689 = callee_function_instance
;
695 /* Sum of counts that is used during annotation. */
698 function_instance::total_annotated_count () const
701 for (callsite_map::const_iterator iter
= callsites
.begin ();
702 iter
!= callsites
.end (); ++iter
)
703 ret
+= iter
->second
->total_annotated_count ();
704 for (position_count_map::const_iterator iter
= pos_counts
.begin ();
705 iter
!= pos_counts
.end (); ++iter
)
706 if (iter
->second
.annotated
)
707 ret
+= iter
->second
.count
;
711 /* Member functions for autofdo_source_profile. */
713 autofdo_source_profile::~autofdo_source_profile ()
715 for (name_function_instance_map::const_iterator iter
= map_
.begin ();
716 iter
!= map_
.end (); ++iter
)
720 /* For a given DECL, returns the top-level function_instance. */
723 autofdo_source_profile::get_function_instance_by_decl (tree decl
) const
725 int index
= afdo_string_table
->get_index_by_decl (decl
);
728 name_function_instance_map::const_iterator ret
= map_
.find (index
);
729 return ret
== map_
.end () ? NULL
: ret
->second
;
732 /* Find count_info for a given gimple STMT. If found, store the count_info
733 in INFO and return true; otherwise return false. */
736 autofdo_source_profile::get_count_info (gimple stmt
, count_info
*info
) const
738 if (LOCATION_LOCUS (gimple_location (stmt
)) == cfun
->function_end_locus
)
742 get_inline_stack (gimple_location (stmt
), &stack
);
743 if (stack
.length () == 0)
745 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
748 return s
->get_count_info (stack
[0].second
, info
);
751 /* Mark LOC as annotated. */
754 autofdo_source_profile::mark_annotated (location_t loc
)
757 get_inline_stack (loc
, &stack
);
758 if (stack
.length () == 0)
760 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
763 s
->mark_annotated (stack
[0].second
);
766 /* Update value profile INFO for STMT from the inlined indirect callsite.
767 Return true if INFO is updated. */
770 autofdo_source_profile::update_inlined_ind_target (gcall
*stmt
,
773 if (LOCATION_LOCUS (gimple_location (stmt
)) == cfun
->function_end_locus
)
777 get_count_info (stmt
, &old_info
);
779 for (icall_target_map::const_iterator iter
= old_info
.targets
.begin ();
780 iter
!= old_info
.targets
.end (); ++iter
)
781 total
+= iter
->second
;
783 /* Program behavior changed, original promoted (and inlined) target is not
784 hot any more. Will avoid promote the original target.
786 To check if original promoted target is still hot, we check the total
787 count of the unpromoted targets (stored in old_info). If it is no less
788 than half of the callsite count (stored in INFO), the original promoted
789 target is considered not hot any more. */
790 if (total
>= info
->count
/ 2)
794 get_inline_stack (gimple_location (stmt
), &stack
);
795 if (stack
.length () == 0)
797 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
800 icall_target_map map
;
801 if (s
->find_icall_target_map (stmt
, &map
) == 0)
803 for (icall_target_map::const_iterator iter
= map
.begin ();
804 iter
!= map
.end (); ++iter
)
805 info
->targets
[iter
->first
] = iter
->second
;
809 /* Find total count of the callee of EDGE. */
812 autofdo_source_profile::get_callsite_total_count (
813 struct cgraph_edge
*edge
) const
816 stack
.safe_push (std::make_pair (edge
->callee
->decl
, 0));
817 get_inline_stack (gimple_location (edge
->call_stmt
), &stack
);
819 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
821 || afdo_string_table
->get_index (IDENTIFIER_POINTER (
822 DECL_ASSEMBLER_NAME (edge
->callee
->decl
))) != s
->name ())
825 return s
->total_count ();
828 /* Read AutoFDO profile and returns TRUE on success. */
830 /* source profile format:
832 GCOV_TAG_AFDO_FUNCTION: 4 bytes
834 NUM_FUNCTIONS: 4 bytes
838 FUNCTION_INSTANCE_N. */
841 autofdo_source_profile::read ()
843 if (gcov_read_unsigned () != GCOV_TAG_AFDO_FUNCTION
)
845 inform (0, "Not expected TAG.");
849 /* Skip the length of the section. */
850 gcov_read_unsigned ();
852 /* Read in the function/callsite profile, and store it in local
854 unsigned function_num
= gcov_read_unsigned ();
855 for (unsigned i
= 0; i
< function_num
; i
++)
857 function_instance::function_instance_stack stack
;
858 function_instance
*s
= function_instance::read_function_instance (
859 &stack
, gcov_read_counter ());
860 afdo_profile_info
->sum_all
+= s
->total_count ();
861 map_
[s
->name ()] = s
;
866 /* Return the function_instance in the profile that correspond to the
870 autofdo_source_profile::get_function_instance_by_inline_stack (
871 const inline_stack
&stack
) const
873 name_function_instance_map::const_iterator iter
= map_
.find (
874 afdo_string_table
->get_index_by_decl (stack
[stack
.length () - 1].first
));
875 if (iter
== map_
.end())
877 function_instance
*s
= iter
->second
;
878 for (unsigned i
= stack
.length() - 1; i
> 0; i
--)
880 s
= s
->get_function_instance_by_decl (
881 stack
[i
].second
, stack
[i
- 1].first
);
888 /* Module profile is only used by LIPO. Here we simply ignore it. */
891 fake_read_autofdo_module_profile ()
893 /* Read in the module info. */
894 gcov_read_unsigned ();
896 /* Skip the length of the section. */
897 gcov_read_unsigned ();
899 /* Read in the file name table. */
900 unsigned total_module_num
= gcov_read_unsigned ();
901 gcc_assert (total_module_num
== 0);
904 /* Read data from profile data file. */
909 if (gcov_open (auto_profile_file
, 1) == 0)
910 error ("Cannot open profile file %s.", auto_profile_file
);
912 if (gcov_read_unsigned () != GCOV_DATA_MAGIC
)
913 error ("AutoFDO profile magic number does not mathch.");
915 /* Skip the version number. */
916 unsigned version
= gcov_read_unsigned ();
917 if (version
!= AUTO_PROFILE_VERSION
)
918 error ("AutoFDO profile version %u does match %u.",
919 version
, AUTO_PROFILE_VERSION
);
921 /* Skip the empty integer. */
922 gcov_read_unsigned ();
925 afdo_string_table
= new string_table ();
926 if (!afdo_string_table
->read())
927 error ("Cannot read string table from %s.", auto_profile_file
);
929 /* autofdo_source_profile. */
930 afdo_source_profile
= autofdo_source_profile::create ();
931 if (afdo_source_profile
== NULL
)
932 error ("Cannot read function profile from %s.", auto_profile_file
);
934 /* autofdo_module_profile. */
935 fake_read_autofdo_module_profile ();
937 /* Read in the working set. */
938 if (gcov_read_unsigned () != GCOV_TAG_AFDO_WORKING_SET
)
939 error ("Cannot read working set from %s.", auto_profile_file
);
941 /* Skip the length of the section. */
942 gcov_read_unsigned ();
943 gcov_working_set_t set
[128];
944 for (unsigned i
= 0; i
< 128; i
++)
946 set
[i
].num_counters
= gcov_read_unsigned ();
947 set
[i
].min_counter
= gcov_read_counter ();
949 add_working_set (set
);
952 /* From AutoFDO profiles, find values inside STMT for that we want to measure
953 histograms for indirect-call optimization.
955 This function is actually served for 2 purposes:
956 * before annotation, we need to mark histogram, promote and inline
957 * after annotation, we just need to mark, and let follow-up logic to
958 decide if it needs to promote and inline. */
961 afdo_indirect_call (gimple_stmt_iterator
*gsi
, const icall_target_map
&map
,
964 gimple gs
= gsi_stmt (*gsi
);
967 if (map
.size () == 0)
969 gcall
*stmt
= dyn_cast
<gcall
*> (gs
);
970 if ((!stmt
) || gimple_call_fndecl (stmt
) != NULL_TREE
)
973 callee
= gimple_call_fn (stmt
);
975 histogram_value hist
= gimple_alloc_histogram_value (
976 cfun
, HIST_TYPE_INDIR_CALL
, stmt
, callee
);
977 hist
->n_counters
= 3;
978 hist
->hvalue
.counters
= XNEWVEC (gcov_type
, hist
->n_counters
);
979 gimple_add_histogram_value (cfun
, stmt
, hist
);
982 icall_target_map::const_iterator max_iter
= map
.end ();
984 for (icall_target_map::const_iterator iter
= map
.begin ();
985 iter
!= map
.end (); ++iter
)
987 total
+= iter
->second
;
988 if (max_iter
== map
.end () || max_iter
->second
< iter
->second
)
992 hist
->hvalue
.counters
[0]
993 = (unsigned long long)afdo_string_table
->get_name (max_iter
->first
);
994 hist
->hvalue
.counters
[1] = max_iter
->second
;
995 hist
->hvalue
.counters
[2] = total
;
1000 struct cgraph_edge
*indirect_edge
1001 = cgraph_node::get (current_function_decl
)->get_edge (stmt
);
1002 struct cgraph_node
*direct_call
= cgraph_node::get_for_asmname (
1003 get_identifier ((const char *) hist
->hvalue
.counters
[0]));
1005 if (direct_call
== NULL
|| !check_ic_target (stmt
, direct_call
))
1007 if (DECL_STRUCT_FUNCTION (direct_call
->decl
) == NULL
)
1009 struct cgraph_edge
*new_edge
1010 = indirect_edge
->make_speculative (direct_call
, 0, 0);
1011 new_edge
->redirect_call_stmt_to_callee ();
1012 gimple_remove_histogram_value (cfun
, stmt
, hist
);
1013 inline_call (new_edge
, true, NULL
, NULL
, false);
1016 /* From AutoFDO profiles, find values inside STMT for that we want to measure
1017 histograms and adds them to list VALUES. */
1020 afdo_vpt (gimple_stmt_iterator
*gsi
, const icall_target_map
&map
,
1023 afdo_indirect_call (gsi
, map
, transform
);
1026 typedef std::set
<basic_block
> bb_set
;
1027 typedef std::set
<edge
> edge_set
;
1030 is_bb_annotated (const basic_block bb
, const bb_set
&annotated
)
1032 return annotated
.find (bb
) != annotated
.end ();
1036 set_bb_annotated (basic_block bb
, bb_set
*annotated
)
1038 annotated
->insert (bb
);
1042 is_edge_annotated (const edge e
, const edge_set
&annotated
)
1044 return annotated
.find (e
) != annotated
.end ();
1048 set_edge_annotated (edge e
, edge_set
*annotated
)
1050 annotated
->insert (e
);
1053 /* For a given BB, set its execution count. Attach value profile if a stmt
1054 is not in PROMOTED, because we only want to promote an indirect call once.
1055 Return TRUE if BB is annotated. */
1058 afdo_set_bb_count (basic_block bb
, const stmt_set
&promoted
)
1060 gimple_stmt_iterator gsi
;
1063 gcov_type max_count
= 0;
1064 bool has_annotated
= false;
1066 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1069 gimple stmt
= gsi_stmt (gsi
);
1070 if (gimple_clobber_p (stmt
) || is_gimple_debug (stmt
))
1072 if (afdo_source_profile
->get_count_info (stmt
, &info
))
1074 if (info
.count
> max_count
)
1075 max_count
= info
.count
;
1076 has_annotated
= true;
1077 if (info
.targets
.size () > 0
1078 && promoted
.find (stmt
) == promoted
.end ())
1079 afdo_vpt (&gsi
, info
.targets
, false);
1086 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1087 afdo_source_profile
->mark_annotated (gimple_location (gsi_stmt (gsi
)));
1088 for (gphi_iterator gpi
= gsi_start_phis (bb
);
1092 gphi
*phi
= gpi
.phi ();
1094 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
1095 afdo_source_profile
->mark_annotated (gimple_phi_arg_location (phi
, i
));
1097 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1098 afdo_source_profile
->mark_annotated (e
->goto_locus
);
1100 bb
->count
= max_count
;
1104 /* BB1 and BB2 are in an equivalent class iff:
1105 1. BB1 dominates BB2.
1106 2. BB2 post-dominates BB1.
1107 3. BB1 and BB2 are in the same loop nest.
1108 This function finds the equivalent class for each basic block, and
1109 stores a pointer to the first BB in its equivalent class. Meanwhile,
1110 set bb counts for the same equivalent class to be idenical. Update
1111 ANNOTATED_BB for the first BB in its equivalent class. */
1114 afdo_find_equiv_class (bb_set
*annotated_bb
)
1118 FOR_ALL_BB_FN (bb
, cfun
)
1121 FOR_ALL_BB_FN (bb
, cfun
)
1123 vec
<basic_block
> dom_bbs
;
1127 if (bb
->aux
!= NULL
)
1130 dom_bbs
= get_dominated_by (CDI_DOMINATORS
, bb
);
1131 FOR_EACH_VEC_ELT (dom_bbs
, i
, bb1
)
1132 if (bb1
->aux
== NULL
&& dominated_by_p (CDI_POST_DOMINATORS
, bb
, bb1
)
1133 && bb1
->loop_father
== bb
->loop_father
)
1136 if (bb1
->count
> bb
->count
&& is_bb_annotated (bb1
, *annotated_bb
))
1138 bb
->count
= bb1
->count
;
1139 set_bb_annotated (bb
, annotated_bb
);
1142 dom_bbs
= get_dominated_by (CDI_POST_DOMINATORS
, bb
);
1143 FOR_EACH_VEC_ELT (dom_bbs
, i
, bb1
)
1144 if (bb1
->aux
== NULL
&& dominated_by_p (CDI_DOMINATORS
, bb
, bb1
)
1145 && bb1
->loop_father
== bb
->loop_father
)
1148 if (bb1
->count
> bb
->count
&& is_bb_annotated (bb1
, *annotated_bb
))
1150 bb
->count
= bb1
->count
;
1151 set_bb_annotated (bb
, annotated_bb
);
1157 /* If a basic block's count is known, and only one of its in/out edges' count
1158 is unknown, its count can be calculated. Meanwhile, if all of the in/out
1159 edges' counts are known, then the basic block's unknown count can also be
1161 IS_SUCC is true if out edges of a basic blocks are examined.
1162 Update ANNOTATED_BB and ANNOTATED_EDGE accordingly.
1163 Return TRUE if any basic block/edge count is changed. */
1166 afdo_propagate_edge (bool is_succ
, bb_set
*annotated_bb
,
1167 edge_set
*annotated_edge
)
1170 bool changed
= false;
1172 FOR_EACH_BB_FN (bb
, cfun
)
1174 edge e
, unknown_edge
= NULL
;
1176 int num_unknown_edge
= 0;
1177 gcov_type total_known_count
= 0;
1179 FOR_EACH_EDGE (e
, ei
, is_succ
? bb
->succs
: bb
->preds
)
1180 if (!is_edge_annotated (e
, *annotated_edge
))
1181 num_unknown_edge
++, unknown_edge
= e
;
1183 total_known_count
+= e
->count
;
1185 if (num_unknown_edge
== 0)
1187 if (total_known_count
> bb
->count
)
1189 bb
->count
= total_known_count
;
1192 if (!is_bb_annotated (bb
, *annotated_bb
))
1194 set_bb_annotated (bb
, annotated_bb
);
1198 else if (num_unknown_edge
== 1 && is_bb_annotated (bb
, *annotated_bb
))
1200 if (bb
->count
>= total_known_count
)
1201 unknown_edge
->count
= bb
->count
- total_known_count
;
1203 unknown_edge
->count
= 0;
1204 set_edge_annotated (unknown_edge
, annotated_edge
);
1211 /* Special propagation for circuit expressions. Because GCC translates
1212 control flow into data flow for circuit expressions. E.g.
1219 will be translated into:
1234 tmp = PHI (0 (BB1), 0 (BB.t1), 1 (BB.t2)
1240 In this case, we need to propagate through PHI to determine the edge
1241 count of BB1->BB.t1, BB.t1->BB.t2.
1242 Update ANNOTATED_EDGE accordingly. */
1245 afdo_propagate_circuit (const bb_set
&annotated_bb
, edge_set
*annotated_edge
)
1248 FOR_ALL_BB_FN (bb
, cfun
)
1251 tree cmp_rhs
, cmp_lhs
;
1252 gimple cmp_stmt
= last_stmt (bb
);
1256 if (!cmp_stmt
|| gimple_code (cmp_stmt
) != GIMPLE_COND
)
1258 cmp_rhs
= gimple_cond_rhs (cmp_stmt
);
1259 cmp_lhs
= gimple_cond_lhs (cmp_stmt
);
1260 if (!TREE_CONSTANT (cmp_rhs
)
1261 || !(integer_zerop (cmp_rhs
) || integer_onep (cmp_rhs
)))
1263 if (TREE_CODE (cmp_lhs
) != SSA_NAME
)
1265 if (!is_bb_annotated (bb
, annotated_bb
))
1267 def_stmt
= SSA_NAME_DEF_STMT (cmp_lhs
);
1268 while (def_stmt
&& gimple_code (def_stmt
) == GIMPLE_ASSIGN
1269 && gimple_assign_single_p (def_stmt
)
1270 && TREE_CODE (gimple_assign_rhs1 (def_stmt
)) == SSA_NAME
)
1271 def_stmt
= SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt
));
1274 gphi
*phi_stmt
= dyn_cast
<gphi
*> (def_stmt
);
1277 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1279 unsigned i
, total
= 0;
1281 bool check_value_one
= (((integer_onep (cmp_rhs
))
1282 ^ (gimple_cond_code (cmp_stmt
) == EQ_EXPR
))
1283 ^ ((e
->flags
& EDGE_TRUE_VALUE
) != 0));
1284 if (!is_edge_annotated (e
, *annotated_edge
))
1286 for (i
= 0; i
< gimple_phi_num_args (phi_stmt
); i
++)
1288 tree val
= gimple_phi_arg_def (phi_stmt
, i
);
1289 edge ep
= gimple_phi_arg_edge (phi_stmt
, i
);
1291 if (!TREE_CONSTANT (val
)
1292 || !(integer_zerop (val
) || integer_onep (val
)))
1294 if (check_value_one
^ integer_onep (val
))
1298 if (e
->probability
== 0 && !is_edge_annotated (ep
, *annotated_edge
))
1300 ep
->probability
= 0;
1302 set_edge_annotated (ep
, annotated_edge
);
1305 if (total
== 1 && !is_edge_annotated (only_one
, *annotated_edge
))
1307 only_one
->probability
= e
->probability
;
1308 only_one
->count
= e
->count
;
1309 set_edge_annotated (only_one
, annotated_edge
);
1315 /* Propagate the basic block count and edge count on the control flow
1316 graph. We do the propagation iteratively until stablize. */
1319 afdo_propagate (bb_set
*annotated_bb
, edge_set
*annotated_edge
)
1322 bool changed
= true;
1325 FOR_ALL_BB_FN (bb
, cfun
)
1327 bb
->count
= ((basic_block
)bb
->aux
)->count
;
1328 if (is_bb_annotated ((const basic_block
)bb
->aux
, *annotated_bb
))
1329 set_bb_annotated (bb
, annotated_bb
);
1332 while (changed
&& i
++ < 10)
1336 if (afdo_propagate_edge (true, annotated_bb
, annotated_edge
))
1338 if (afdo_propagate_edge (false, annotated_bb
, annotated_edge
))
1340 afdo_propagate_circuit (*annotated_bb
, annotated_edge
);
1344 /* Propagate counts on control flow graph and calculate branch
1348 afdo_calculate_branch_prob (bb_set
*annotated_bb
, edge_set
*annotated_edge
)
1351 bool has_sample
= false;
1353 FOR_EACH_BB_FN (bb
, cfun
)
1365 calculate_dominance_info (CDI_POST_DOMINATORS
);
1366 calculate_dominance_info (CDI_DOMINATORS
);
1367 loop_optimizer_init (0);
1369 afdo_find_equiv_class (annotated_bb
);
1370 afdo_propagate (annotated_bb
, annotated_edge
);
1372 FOR_EACH_BB_FN (bb
, cfun
)
1376 int num_unknown_succ
= 0;
1377 gcov_type total_count
= 0;
1379 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1381 if (!is_edge_annotated (e
, *annotated_edge
))
1384 total_count
+= e
->count
;
1386 if (num_unknown_succ
== 0 && total_count
> 0)
1388 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1389 e
->probability
= (double)e
->count
* REG_BR_PROB_BASE
/ total_count
;
1392 FOR_ALL_BB_FN (bb
, cfun
)
1397 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1398 e
->count
= (double)bb
->count
* e
->probability
/ REG_BR_PROB_BASE
;
1402 loop_optimizer_finalize ();
1403 free_dominance_info (CDI_DOMINATORS
);
1404 free_dominance_info (CDI_POST_DOMINATORS
);
1407 /* Perform value profile transformation using AutoFDO profile. Add the
1408 promoted stmts to PROMOTED_STMTS. Return TRUE if there is any
1409 indirect call promoted. */
1412 afdo_vpt_for_early_inline (stmt_set
*promoted_stmts
)
1415 if (afdo_source_profile
->get_function_instance_by_decl (
1416 current_function_decl
) == NULL
)
1419 compute_inline_parameters (cgraph_node::get (current_function_decl
), true);
1421 bool has_vpt
= false;
1422 FOR_EACH_BB_FN (bb
, cfun
)
1424 if (!has_indirect_call (bb
))
1426 gimple_stmt_iterator gsi
;
1428 gcov_type bb_count
= 0;
1429 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1432 gimple stmt
= gsi_stmt (gsi
);
1433 if (afdo_source_profile
->get_count_info (stmt
, &info
))
1434 bb_count
= MAX (bb_count
, info
.count
);
1437 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1439 gcall
*stmt
= dyn_cast
<gcall
*> (gsi_stmt (gsi
));
1440 /* IC_promotion and early_inline_2 is done in multiple iterations.
1441 No need to promoted the stmt if its in promoted_stmts (means
1442 it is already been promoted in the previous iterations). */
1443 if ((!stmt
) || gimple_call_fn (stmt
) == NULL
1444 || TREE_CODE (gimple_call_fn (stmt
)) == FUNCTION_DECL
1445 || promoted_stmts
->find (stmt
) != promoted_stmts
->end ())
1449 afdo_source_profile
->get_count_info (stmt
, &info
);
1450 info
.count
= bb_count
;
1451 if (afdo_source_profile
->update_inlined_ind_target (stmt
, &info
))
1453 /* Promote the indirect call and update the promoted_stmts. */
1454 promoted_stmts
->insert (stmt
);
1455 afdo_vpt (&gsi
, info
.targets
, true);
1463 optimize_inline_calls (current_function_decl
);
1470 /* Annotate auto profile to the control flow graph. Do not annotate value
1471 profile for stmts in PROMOTED_STMTS. */
1474 afdo_annotate_cfg (const stmt_set
&promoted_stmts
)
1477 bb_set annotated_bb
;
1478 edge_set annotated_edge
;
1479 const function_instance
*s
1480 = afdo_source_profile
->get_function_instance_by_decl (
1481 current_function_decl
);
1485 cgraph_node::get (current_function_decl
)->count
= s
->head_count ();
1486 ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
= s
->head_count ();
1487 gcov_type max_count
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1489 FOR_EACH_BB_FN (bb
, cfun
)
1495 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1498 if (afdo_set_bb_count (bb
, promoted_stmts
))
1499 set_bb_annotated (bb
, &annotated_bb
);
1500 if (bb
->count
> max_count
)
1501 max_count
= bb
->count
;
1503 if (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
1504 > ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
->count
)
1506 ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
->count
1507 = ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1508 set_bb_annotated (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
, &annotated_bb
);
1510 if (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
1511 > EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
->count
)
1513 EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
->count
1514 = ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1515 set_bb_annotated (EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
, &annotated_bb
);
1517 afdo_source_profile
->mark_annotated (
1518 DECL_SOURCE_LOCATION (current_function_decl
));
1519 afdo_source_profile
->mark_annotated (cfun
->function_start_locus
);
1520 afdo_source_profile
->mark_annotated (cfun
->function_end_locus
);
1523 afdo_calculate_branch_prob (&annotated_bb
, &annotated_edge
);
1525 profile_status_for_fn (cfun
) = PROFILE_READ
;
1527 if (flag_value_profile_transformations
)
1529 gimple_value_profile_transformations ();
1530 free_dominance_info (CDI_DOMINATORS
);
1531 free_dominance_info (CDI_POST_DOMINATORS
);
1532 update_ssa (TODO_update_ssa
);
1536 /* Wrapper function to invoke early inliner. */
1541 compute_inline_parameters (cgraph_node::get (current_function_decl
), true);
1542 unsigned todo
= early_inliner (cfun
);
1543 if (todo
& TODO_update_ssa_any
)
1544 update_ssa (TODO_update_ssa
);
1547 /* Use AutoFDO profile to annoate the control flow graph.
1548 Return the todo flag. */
1553 struct cgraph_node
*node
;
1555 if (symtab
->state
== FINISHED
)
1558 init_node_map (true);
1559 profile_info
= autofdo::afdo_profile_info
;
1561 FOR_EACH_FUNCTION (node
)
1563 if (!gimple_has_body_p (node
->decl
))
1566 /* Don't profile functions produced for builtin stuff. */
1567 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
1570 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
1572 /* First do indirect call promotion and early inline to make the
1573 IR match the profiled binary before actual annotation.
1575 This is needed because an indirect call might have been promoted
1576 and inlined in the profiled binary. If we do not promote and
1577 inline these indirect calls before annotation, the profile for
1578 these promoted functions will be lost.
1580 e.g. foo() --indirect_call--> bar()
1581 In profiled binary, the callsite is promoted and inlined, making
1582 the profile look like:
1592 Before AutoFDO pass, loc_foo_2 is not promoted thus not inlined.
1593 If we perform annotation on it, the profile inside bar@loc_foo2
1596 To avoid this, we promote loc_foo_2 and inline the promoted bar
1597 function before annotation, so the profile inside bar@loc_foo2
1599 autofdo::stmt_set promoted_stmts
;
1600 for (int i
= 0; i
< PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS
); i
++)
1602 if (!flag_value_profile_transformations
1603 || !autofdo::afdo_vpt_for_early_inline (&promoted_stmts
))
1609 autofdo::afdo_annotate_cfg (promoted_stmts
);
1610 compute_function_frequency ();
1612 /* Local pure-const may imply need to fixup the cfg. */
1613 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
1614 cleanup_tree_cfg ();
1616 free_dominance_info (CDI_DOMINATORS
);
1617 free_dominance_info (CDI_POST_DOMINATORS
);
1618 cgraph_edge::rebuild_edges ();
1619 compute_inline_parameters (cgraph_node::get (current_function_decl
), true);
1623 return TODO_rebuild_cgraph_edges
;
1625 } /* namespace autofdo. */
1627 /* Read the profile from the profile data file. */
1630 read_autofdo_file (void)
1632 if (auto_profile_file
== NULL
)
1633 auto_profile_file
= DEFAULT_AUTO_PROFILE_FILE
;
1635 autofdo::afdo_profile_info
= (struct gcov_ctr_summary
*)xcalloc (
1636 1, sizeof (struct gcov_ctr_summary
));
1637 autofdo::afdo_profile_info
->runs
= 1;
1638 autofdo::afdo_profile_info
->sum_max
= 0;
1639 autofdo::afdo_profile_info
->sum_all
= 0;
1641 /* Read the profile from the profile file. */
1642 autofdo::read_profile ();
1645 /* Free the resources. */
1648 end_auto_profile (void)
1650 delete autofdo::afdo_source_profile
;
1651 delete autofdo::afdo_string_table
;
1652 profile_info
= NULL
;
1655 /* Returns TRUE if EDGE is hot enough to be inlined early. */
1658 afdo_callsite_hot_enough_for_early_inline (struct cgraph_edge
*edge
)
1661 = autofdo::afdo_source_profile
->get_callsite_total_count (edge
);
1666 const struct gcov_ctr_summary
*saved_profile_info
= profile_info
;
1667 /* At early inline stage, profile_info is not set yet. We need to
1668 temporarily set it to afdo_profile_info to calculate hotness. */
1669 profile_info
= autofdo::afdo_profile_info
;
1670 is_hot
= maybe_hot_count_p (NULL
, count
);
1671 profile_info
= saved_profile_info
;
1681 const pass_data pass_data_ipa_auto_profile
= {
1682 SIMPLE_IPA_PASS
, "afdo", /* name */
1683 OPTGROUP_NONE
, /* optinfo_flags */
1684 TV_IPA_AUTOFDO
, /* tv_id */
1685 0, /* properties_required */
1686 0, /* properties_provided */
1687 0, /* properties_destroyed */
1688 0, /* todo_flags_start */
1689 0, /* todo_flags_finish */
1692 class pass_ipa_auto_profile
: public simple_ipa_opt_pass
1695 pass_ipa_auto_profile (gcc::context
*ctxt
)
1696 : simple_ipa_opt_pass (pass_data_ipa_auto_profile
, ctxt
)
1700 /* opt_pass methods: */
1704 return flag_auto_profile
;
1706 virtual unsigned int
1707 execute (function
*)
1709 return autofdo::auto_profile ();
1711 }; // class pass_ipa_auto_profile
1715 simple_ipa_opt_pass
*
1716 make_pass_ipa_auto_profile (gcc::context
*ctxt
)
1718 return new pass_ipa_auto_profile (ctxt
);