1 /* Read and annotate call graph profile from the auto profile data file.
2 Copyright (C) 2014-2019 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/>. */
25 #include "coretypes.h"
30 #include "alloc-pool.h"
31 #include "tree-pass.h"
35 #include "diagnostic-core.h"
37 #include "langhooks.h"
40 #include "tree-cfgcleanup.h"
41 #include "tree-into-ssa.h"
42 #include "gimple-iterator.h"
43 #include "value-prof.h"
45 #include "symbol-summary.h"
47 #include "ipa-fnsummary.h"
48 #include "ipa-inline.h"
49 #include "tree-inline.h"
50 #include "auto-profile.h"
51 #include "tree-pretty-print.h"
52 #include "gimple-pretty-print.h"
54 /* The following routines implements AutoFDO optimization.
56 This optimization uses sampling profiles to annotate basic block counts
57 and uses heuristics to estimate branch probabilities.
59 There are three phases in AutoFDO:
61 Phase 1: Read profile from the profile data file.
62 The following info is read from the profile datafile:
63 * string_table: a map between function name and its index.
64 * autofdo_source_profile: a map from function_instance name to
65 function_instance. This is represented as a forest of
67 * WorkingSet: a histogram of how many instructions are covered for a
68 given percentage of total cycles. This is describing the binary
69 level information (not source level). This info is used to help
70 decide if we want aggressive optimizations that could increase
71 code footprint (e.g. loop unroll etc.)
72 A function instance is an instance of function that could either be a
73 standalone symbol, or a clone of a function that is inlined into another
76 Phase 2: Early inline + value profile transformation.
77 Early inline uses autofdo_source_profile to find if a callsite is:
78 * inlined in the profiled binary.
79 * callee body is hot in the profiling run.
80 If both condition satisfies, early inline will inline the callsite
81 regardless of the code growth.
82 Phase 2 is an iterative process. During each iteration, we also check
83 if an indirect callsite is promoted and inlined in the profiling run.
84 If yes, vpt will happen to force promote it and in the next iteration,
85 einline will inline the promoted callsite in the next iteration.
87 Phase 3: Annotate control flow graph.
88 AutoFDO uses a separate pass to:
89 * Annotate basic block count
90 * Estimate branch probability
92 After the above 3 phases, all profile is readily annotated on the GCC IR.
93 AutoFDO tries to reuse all FDO infrastructure as much as possible to make
94 use of the profile. E.g. it uses existing mechanism to calculate the basic
95 block/edge frequency, as well as the cgraph node/edge count.
98 #define DEFAULT_AUTO_PROFILE_FILE "fbdata.afdo"
99 #define AUTO_PROFILE_VERSION 1
104 /* Intermediate edge info used when propagating AutoFDO profile information.
105 We can't edge->count() directly since it's computed from edge's probability
106 while probability is yet not decided during propagation. */
107 #define AFDO_EINFO(e) ((class edge_info *) e->aux)
111 edge_info () : count_ (profile_count::zero ().afdo ()), annotated_ (false) {}
112 bool is_annotated () const { return annotated_
; }
113 void set_annotated () { annotated_
= true; }
114 profile_count
get_count () const { return count_
; }
115 void set_count (profile_count count
) { count_
= count
; }
117 profile_count count_
;
121 /* Represent a source location: (function_decl, lineno). */
122 typedef std::pair
<tree
, unsigned> decl_lineno
;
124 /* Represent an inline stack. vector[0] is the leaf node. */
125 typedef auto_vec
<decl_lineno
> inline_stack
;
127 /* String array that stores function names. */
128 typedef auto_vec
<char *> string_vector
;
130 /* Map from function name's index in string_table to target's
132 typedef std::map
<unsigned, gcov_type
> icall_target_map
;
134 /* Set of gimple stmts. Used to track if the stmt has already been promoted
136 typedef std::set
<gimple
*> stmt_set
;
138 /* Represent count info of an inline stack. */
142 /* Sampled count of the inline stack. */
145 /* Map from indirect call target to its sample count. */
146 icall_target_map targets
;
148 /* Whether this inline stack is already used in annotation.
150 Each inline stack should only be used to annotate IR once.
151 This will be enforced when instruction-level discriminator
156 /* operator< for "const char *". */
157 struct string_compare
159 bool operator()(const char *a
, const char *b
) const
161 return strcmp (a
, b
) < 0;
165 /* Store a string array, indexed by string position in the array. */
174 /* For a given string, returns its index. */
175 int get_index (const char *name
) const;
177 /* For a given decl, returns the index of the decl name. */
178 int get_index_by_decl (tree decl
) const;
180 /* For a given index, returns the string. */
181 const char *get_name (int index
) const;
183 /* Read profile, return TRUE on success. */
187 typedef std::map
<const char *, unsigned, string_compare
> string_index_map
;
188 string_vector vector_
;
189 string_index_map map_
;
192 /* Profile of a function instance:
193 1. total_count of the function.
194 2. head_count (entry basic block count) of the function (only valid when
195 function is a top-level function_instance, i.e. it is the original copy
196 instead of the inlined copy).
197 3. map from source location (decl_lineno) to profile (count_info).
198 4. map from callsite to callee function_instance. */
199 class function_instance
202 typedef auto_vec
<function_instance
*> function_instance_stack
;
204 /* Read the profile and return a function_instance with head count as
205 HEAD_COUNT. Recursively read callsites to create nested function_instances
206 too. STACK is used to track the recursive creation process. */
207 static function_instance
*
208 read_function_instance (function_instance_stack
*stack
,
209 gcov_type head_count
);
211 /* Recursively deallocate all callsites (nested function_instances). */
212 ~function_instance ();
231 /* Traverse callsites of the current function_instance to find one at the
232 location of LINENO and callee name represented in DECL. */
233 function_instance
*get_function_instance_by_decl (unsigned lineno
,
236 /* Store the profile info for LOC in INFO. Return TRUE if profile info
238 bool get_count_info (location_t loc
, count_info
*info
) const;
240 /* Read the inlined indirect call target profile for STMT and store it in
241 MAP, return the total count for all inlined indirect calls. */
242 gcov_type
find_icall_target_map (gcall
*stmt
, icall_target_map
*map
) const;
244 /* Sum of counts that is used during annotation. */
245 gcov_type
total_annotated_count () const;
247 /* Mark LOC as annotated. */
248 void mark_annotated (location_t loc
);
251 /* Callsite, represented as (decl_lineno, callee_function_name_index). */
252 typedef std::pair
<unsigned, unsigned> callsite
;
254 /* Map from callsite to callee function_instance. */
255 typedef std::map
<callsite
, function_instance
*> callsite_map
;
257 function_instance (unsigned name
, gcov_type head_count
)
258 : name_ (name
), total_count_ (0), head_count_ (head_count
)
262 /* Map from source location (decl_lineno) to profile (count_info). */
263 typedef std::map
<unsigned, count_info
> position_count_map
;
265 /* function_instance name index in the string_table. */
268 /* Total sample count. */
269 gcov_type total_count_
;
271 /* Entry BB's sample count. */
272 gcov_type head_count_
;
274 /* Map from callsite location to callee function_instance. */
275 callsite_map callsites
;
277 /* Map from source location to count_info. */
278 position_count_map pos_counts
;
281 /* Profile for all functions. */
282 class autofdo_source_profile
285 static autofdo_source_profile
*
288 autofdo_source_profile
*map
= new autofdo_source_profile ();
296 ~autofdo_source_profile ();
298 /* For a given DECL, returns the top-level function_instance. */
299 function_instance
*get_function_instance_by_decl (tree decl
) const;
301 /* Find count_info for a given gimple STMT. If found, store the count_info
302 in INFO and return true; otherwise return false. */
303 bool get_count_info (gimple
*stmt
, count_info
*info
) const;
305 /* Find total count of the callee of EDGE. */
306 gcov_type
get_callsite_total_count (struct cgraph_edge
*edge
) const;
308 /* Update value profile INFO for STMT from the inlined indirect callsite.
309 Return true if INFO is updated. */
310 bool update_inlined_ind_target (gcall
*stmt
, count_info
*info
);
312 /* Mark LOC as annotated. */
313 void mark_annotated (location_t loc
);
316 /* Map from function_instance name index (in string_table) to
317 function_instance. */
318 typedef std::map
<unsigned, function_instance
*> name_function_instance_map
;
320 autofdo_source_profile () {}
322 /* Read AutoFDO profile and returns TRUE on success. */
325 /* Return the function_instance in the profile that correspond to the
328 get_function_instance_by_inline_stack (const inline_stack
&stack
) const;
330 name_function_instance_map map_
;
333 /* Store the strings read from the profile data file. */
334 static string_table
*afdo_string_table
;
336 /* Store the AutoFDO source profile. */
337 static autofdo_source_profile
*afdo_source_profile
;
339 /* gcov_summary structure to store the profile_info. */
340 static gcov_summary
*afdo_profile_info
;
342 /* Helper functions. */
344 /* Return the original name of NAME: strip the suffix that starts
345 with '.' Caller is responsible for freeing RET. */
348 get_original_name (const char *name
)
350 char *ret
= xstrdup (name
);
351 char *find
= strchr (ret
, '.');
357 /* Return the combined location, which is a 32bit integer in which
358 higher 16 bits stores the line offset of LOC to the start lineno
359 of DECL, The lower 16 bits stores the discriminator. */
362 get_combined_location (location_t loc
, tree decl
)
364 /* TODO: allow more bits for line and less bits for discriminator. */
365 if (LOCATION_LINE (loc
) - DECL_SOURCE_LINE (decl
) >= (1<<16))
366 warning_at (loc
, OPT_Woverflow
, "offset exceeds 16 bytes");
367 return ((LOCATION_LINE (loc
) - DECL_SOURCE_LINE (decl
)) << 16);
370 /* Return the function decl of a given lexical BLOCK. */
373 get_function_decl_from_block (tree block
)
375 if (!inlined_function_outer_scope_p (block
))
378 return BLOCK_ABSTRACT_ORIGIN (block
);
381 /* Store inline stack for STMT in STACK. */
384 get_inline_stack (location_t locus
, inline_stack
*stack
)
386 if (LOCATION_LOCUS (locus
) == UNKNOWN_LOCATION
)
389 tree block
= LOCATION_BLOCK (locus
);
390 if (block
&& TREE_CODE (block
) == BLOCK
)
393 for (block
= BLOCK_SUPERCONTEXT (block
);
394 block
&& (TREE_CODE (block
) == BLOCK
);
395 block
= BLOCK_SUPERCONTEXT (block
))
397 location_t tmp_locus
= BLOCK_SOURCE_LOCATION (block
);
398 if (LOCATION_LOCUS (tmp_locus
) == UNKNOWN_LOCATION
)
401 tree decl
= get_function_decl_from_block (block
);
403 std::make_pair (decl
, get_combined_location (locus
, decl
)));
409 std::make_pair (current_function_decl
,
410 get_combined_location (locus
, current_function_decl
)));
413 /* Return STMT's combined location, which is a 32bit integer in which
414 higher 16 bits stores the line offset of LOC to the start lineno
415 of DECL, The lower 16 bits stores the discriminator. */
418 get_relative_location_for_stmt (gimple
*stmt
)
420 location_t locus
= gimple_location (stmt
);
421 if (LOCATION_LOCUS (locus
) == UNKNOWN_LOCATION
)
422 return UNKNOWN_LOCATION
;
424 for (tree block
= gimple_block (stmt
); block
&& (TREE_CODE (block
) == BLOCK
);
425 block
= BLOCK_SUPERCONTEXT (block
))
426 if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block
)) != UNKNOWN_LOCATION
)
427 return get_combined_location (locus
,
428 get_function_decl_from_block (block
));
429 return get_combined_location (locus
, current_function_decl
);
432 /* Return true if BB contains indirect call. */
435 has_indirect_call (basic_block bb
)
437 gimple_stmt_iterator gsi
;
439 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
441 gimple
*stmt
= gsi_stmt (gsi
);
442 if (gimple_code (stmt
) == GIMPLE_CALL
&& !gimple_call_internal_p (stmt
)
443 && (gimple_call_fn (stmt
) == NULL
444 || TREE_CODE (gimple_call_fn (stmt
)) != FUNCTION_DECL
))
450 /* Member functions for string_table. */
454 string_table::~string_table ()
456 for (unsigned i
= 0; i
< vector_
.length (); i
++)
461 /* Return the index of a given function NAME. Return -1 if NAME is not
462 found in string table. */
465 string_table::get_index (const char *name
) const
469 string_index_map::const_iterator iter
= map_
.find (name
);
470 if (iter
== map_
.end ())
476 /* Return the index of a given function DECL. Return -1 if DECL is not
477 found in string table. */
480 string_table::get_index_by_decl (tree decl
) const
483 = get_original_name (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
)));
484 int ret
= get_index (name
);
488 ret
= get_index (lang_hooks
.dwarf_name (decl
, 0));
491 if (DECL_FROM_INLINE (decl
))
492 return get_index_by_decl (DECL_ABSTRACT_ORIGIN (decl
));
497 /* Return the function name of a given INDEX. */
500 string_table::get_name (int index
) const
502 gcc_assert (index
> 0 && index
< (int)vector_
.length ());
503 return vector_
[index
];
506 /* Read the string table. Return TRUE if reading is successful. */
509 string_table::read ()
511 if (gcov_read_unsigned () != GCOV_TAG_AFDO_FILE_NAMES
)
513 /* Skip the length of the section. */
514 gcov_read_unsigned ();
515 /* Read in the file name table. */
516 unsigned string_num
= gcov_read_unsigned ();
517 for (unsigned i
= 0; i
< string_num
; i
++)
519 vector_
.safe_push (get_original_name (gcov_read_string ()));
520 map_
[vector_
.last ()] = i
;
525 /* Member functions for function_instance. */
527 function_instance::~function_instance ()
529 for (callsite_map::iterator iter
= callsites
.begin ();
530 iter
!= callsites
.end (); ++iter
)
534 /* Traverse callsites of the current function_instance to find one at the
535 location of LINENO and callee name represented in DECL. */
538 function_instance::get_function_instance_by_decl (unsigned lineno
,
541 int func_name_idx
= afdo_string_table
->get_index_by_decl (decl
);
542 if (func_name_idx
!= -1)
544 callsite_map::const_iterator ret
545 = callsites
.find (std::make_pair (lineno
, func_name_idx
));
546 if (ret
!= callsites
.end ())
550 = afdo_string_table
->get_index (lang_hooks
.dwarf_name (decl
, 0));
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 ())
558 if (DECL_FROM_INLINE (decl
))
559 return get_function_instance_by_decl (lineno
, DECL_ABSTRACT_ORIGIN (decl
));
564 /* Store the profile info for LOC in INFO. Return TRUE if profile info
568 function_instance::get_count_info (location_t loc
, count_info
*info
) const
570 position_count_map::const_iterator iter
= pos_counts
.find (loc
);
571 if (iter
== pos_counts
.end ())
573 *info
= iter
->second
;
577 /* Mark LOC as annotated. */
580 function_instance::mark_annotated (location_t loc
)
582 position_count_map::iterator iter
= pos_counts
.find (loc
);
583 if (iter
== pos_counts
.end ())
585 iter
->second
.annotated
= true;
588 /* Read the inlined indirect call target profile for STMT and store it in
589 MAP, return the total count for all inlined indirect calls. */
592 function_instance::find_icall_target_map (gcall
*stmt
,
593 icall_target_map
*map
) const
596 unsigned stmt_offset
= get_relative_location_for_stmt (stmt
);
598 for (callsite_map::const_iterator iter
= callsites
.begin ();
599 iter
!= callsites
.end (); ++iter
)
601 unsigned callee
= iter
->second
->name ();
602 /* Check if callsite location match the stmt. */
603 if (iter
->first
.first
!= stmt_offset
)
605 struct cgraph_node
*node
= cgraph_node::get_for_asmname (
606 get_identifier (afdo_string_table
->get_name (callee
)));
609 if (!check_ic_target (stmt
, node
))
611 (*map
)[callee
] = iter
->second
->total_count ();
612 ret
+= iter
->second
->total_count ();
617 /* Read the profile and create a function_instance with head count as
618 HEAD_COUNT. Recursively read callsites to create nested function_instances
619 too. STACK is used to track the recursive creation process. */
621 /* function instance profile format:
625 NUM_POS_COUNTS: 4 bytes
626 NUM_CALLSITES: 4 byte
628 POS_1_OFFSET: 4 bytes
632 VALUE_PROFILE_TYPE: 4 bytes
642 CALLSITE_1_OFFSET: 4 bytes
643 FUNCTION_INSTANCE_PROFILE (nested)
649 function_instance::read_function_instance (function_instance_stack
*stack
,
650 gcov_type head_count
)
652 unsigned name
= gcov_read_unsigned ();
653 unsigned num_pos_counts
= gcov_read_unsigned ();
654 unsigned num_callsites
= gcov_read_unsigned ();
655 function_instance
*s
= new function_instance (name
, head_count
);
656 stack
->safe_push (s
);
658 for (unsigned i
= 0; i
< num_pos_counts
; i
++)
660 unsigned offset
= gcov_read_unsigned () & 0xffff0000;
661 unsigned num_targets
= gcov_read_unsigned ();
662 gcov_type count
= gcov_read_counter ();
663 s
->pos_counts
[offset
].count
= count
;
664 for (unsigned j
= 0; j
< stack
->length (); j
++)
665 (*stack
)[j
]->total_count_
+= count
;
666 for (unsigned j
= 0; j
< num_targets
; j
++)
668 /* Only indirect call target histogram is supported now. */
669 gcov_read_unsigned ();
670 gcov_type target_idx
= gcov_read_counter ();
671 s
->pos_counts
[offset
].targets
[target_idx
] = gcov_read_counter ();
674 for (unsigned i
= 0; i
< num_callsites
; i
++)
676 unsigned offset
= gcov_read_unsigned ();
677 function_instance
*callee_function_instance
678 = read_function_instance (stack
, 0);
679 s
->callsites
[std::make_pair (offset
, callee_function_instance
->name ())]
680 = callee_function_instance
;
686 /* Sum of counts that is used during annotation. */
689 function_instance::total_annotated_count () const
692 for (callsite_map::const_iterator iter
= callsites
.begin ();
693 iter
!= callsites
.end (); ++iter
)
694 ret
+= iter
->second
->total_annotated_count ();
695 for (position_count_map::const_iterator iter
= pos_counts
.begin ();
696 iter
!= pos_counts
.end (); ++iter
)
697 if (iter
->second
.annotated
)
698 ret
+= iter
->second
.count
;
702 /* Member functions for autofdo_source_profile. */
704 autofdo_source_profile::~autofdo_source_profile ()
706 for (name_function_instance_map::const_iterator iter
= map_
.begin ();
707 iter
!= map_
.end (); ++iter
)
711 /* For a given DECL, returns the top-level function_instance. */
714 autofdo_source_profile::get_function_instance_by_decl (tree decl
) const
716 int index
= afdo_string_table
->get_index_by_decl (decl
);
719 name_function_instance_map::const_iterator ret
= map_
.find (index
);
720 return ret
== map_
.end () ? NULL
: ret
->second
;
723 /* Find count_info for a given gimple STMT. If found, store the count_info
724 in INFO and return true; otherwise return false. */
727 autofdo_source_profile::get_count_info (gimple
*stmt
, count_info
*info
) const
729 if (LOCATION_LOCUS (gimple_location (stmt
)) == cfun
->function_end_locus
)
733 get_inline_stack (gimple_location (stmt
), &stack
);
734 if (stack
.length () == 0)
736 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
739 return s
->get_count_info (stack
[0].second
, info
);
742 /* Mark LOC as annotated. */
745 autofdo_source_profile::mark_annotated (location_t loc
)
748 get_inline_stack (loc
, &stack
);
749 if (stack
.length () == 0)
751 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
754 s
->mark_annotated (stack
[0].second
);
757 /* Update value profile INFO for STMT from the inlined indirect callsite.
758 Return true if INFO is updated. */
761 autofdo_source_profile::update_inlined_ind_target (gcall
*stmt
,
766 fprintf (dump_file
, "Checking indirect call -> direct call ");
767 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
770 if (LOCATION_LOCUS (gimple_location (stmt
)) == cfun
->function_end_locus
)
773 fprintf (dump_file
, " good locus\n");
778 get_count_info (stmt
, &old_info
);
780 for (icall_target_map::const_iterator iter
= old_info
.targets
.begin ();
781 iter
!= old_info
.targets
.end (); ++iter
)
782 total
+= iter
->second
;
784 /* Program behavior changed, original promoted (and inlined) target is not
785 hot any more. Will avoid promote the original target.
787 To check if original promoted target is still hot, we check the total
788 count of the unpromoted targets (stored in TOTAL). If a callsite count
789 (stored in INFO) is smaller than half of the total count, the original
790 promoted target is considered not hot any more. */
791 if (info
->count
< total
/ 2)
794 fprintf (dump_file
, " not hot anymore %ld < %ld",
801 get_inline_stack (gimple_location (stmt
), &stack
);
802 if (stack
.length () == 0)
805 fprintf (dump_file
, " no inline stack\n");
808 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
812 fprintf (dump_file
, " function not found in inline stack\n");
815 icall_target_map map
;
816 if (s
->find_icall_target_map (stmt
, &map
) == 0)
819 fprintf (dump_file
, " no target map\n");
822 for (icall_target_map::const_iterator iter
= map
.begin ();
823 iter
!= map
.end (); ++iter
)
824 info
->targets
[iter
->first
] = iter
->second
;
826 fprintf (dump_file
, " looks good\n");
830 /* Find total count of the callee of EDGE. */
833 autofdo_source_profile::get_callsite_total_count (
834 struct cgraph_edge
*edge
) const
837 stack
.safe_push (std::make_pair (edge
->callee
->decl
, 0));
838 get_inline_stack (gimple_location (edge
->call_stmt
), &stack
);
840 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
842 || afdo_string_table
->get_index (IDENTIFIER_POINTER (
843 DECL_ASSEMBLER_NAME (edge
->callee
->decl
))) != s
->name ())
846 return s
->total_count ();
849 /* Read AutoFDO profile and returns TRUE on success. */
851 /* source profile format:
853 GCOV_TAG_AFDO_FUNCTION: 4 bytes
855 NUM_FUNCTIONS: 4 bytes
859 FUNCTION_INSTANCE_N. */
862 autofdo_source_profile::read ()
864 if (gcov_read_unsigned () != GCOV_TAG_AFDO_FUNCTION
)
866 inform (UNKNOWN_LOCATION
, "Not expected TAG.");
870 /* Skip the length of the section. */
871 gcov_read_unsigned ();
873 /* Read in the function/callsite profile, and store it in local
875 unsigned function_num
= gcov_read_unsigned ();
876 for (unsigned i
= 0; i
< function_num
; i
++)
878 function_instance::function_instance_stack stack
;
879 function_instance
*s
= function_instance::read_function_instance (
880 &stack
, gcov_read_counter ());
881 map_
[s
->name ()] = s
;
886 /* Return the function_instance in the profile that correspond to the
890 autofdo_source_profile::get_function_instance_by_inline_stack (
891 const inline_stack
&stack
) const
893 name_function_instance_map::const_iterator iter
= map_
.find (
894 afdo_string_table
->get_index_by_decl (stack
[stack
.length () - 1].first
));
895 if (iter
== map_
.end())
897 function_instance
*s
= iter
->second
;
898 for (unsigned i
= stack
.length() - 1; i
> 0; i
--)
900 s
= s
->get_function_instance_by_decl (
901 stack
[i
].second
, stack
[i
- 1].first
);
908 /* Module profile is only used by LIPO. Here we simply ignore it. */
911 fake_read_autofdo_module_profile ()
913 /* Read in the module info. */
914 gcov_read_unsigned ();
916 /* Skip the length of the section. */
917 gcov_read_unsigned ();
919 /* Read in the file name table. */
920 unsigned total_module_num
= gcov_read_unsigned ();
921 gcc_assert (total_module_num
== 0);
924 /* Read data from profile data file. */
929 if (gcov_open (auto_profile_file
, 1) == 0)
931 error ("cannot open profile file %s", auto_profile_file
);
935 if (gcov_read_unsigned () != GCOV_DATA_MAGIC
)
937 error ("AutoFDO profile magic number does not match");
941 /* Skip the version number. */
942 unsigned version
= gcov_read_unsigned ();
943 if (version
!= AUTO_PROFILE_VERSION
)
945 error ("AutoFDO profile version %u does match %u",
946 version
, AUTO_PROFILE_VERSION
);
950 /* Skip the empty integer. */
951 gcov_read_unsigned ();
954 afdo_string_table
= new string_table ();
955 if (!afdo_string_table
->read())
957 error ("cannot read string table from %s", auto_profile_file
);
961 /* autofdo_source_profile. */
962 afdo_source_profile
= autofdo_source_profile::create ();
963 if (afdo_source_profile
== NULL
)
965 error ("cannot read function profile from %s", auto_profile_file
);
969 /* autofdo_module_profile. */
970 fake_read_autofdo_module_profile ();
973 /* From AutoFDO profiles, find values inside STMT for that we want to measure
974 histograms for indirect-call optimization.
976 This function is actually served for 2 purposes:
977 * before annotation, we need to mark histogram, promote and inline
978 * after annotation, we just need to mark, and let follow-up logic to
979 decide if it needs to promote and inline. */
982 afdo_indirect_call (gimple_stmt_iterator
*gsi
, const icall_target_map
&map
,
985 gimple
*gs
= gsi_stmt (*gsi
);
988 if (map
.size () == 0)
990 gcall
*stmt
= dyn_cast
<gcall
*> (gs
);
992 || gimple_call_internal_p (stmt
)
993 || gimple_call_fndecl (stmt
) != NULL_TREE
)
997 icall_target_map::const_iterator max_iter
= map
.end ();
999 for (icall_target_map::const_iterator iter
= map
.begin ();
1000 iter
!= map
.end (); ++iter
)
1002 total
+= iter
->second
;
1003 if (max_iter
== map
.end () || max_iter
->second
< iter
->second
)
1006 struct cgraph_node
*direct_call
= cgraph_node::get_for_asmname (
1007 get_identifier (afdo_string_table
->get_name (max_iter
->first
)));
1008 if (direct_call
== NULL
|| !direct_call
->profile_id
)
1011 callee
= gimple_call_fn (stmt
);
1013 histogram_value hist
= gimple_alloc_histogram_value (
1014 cfun
, HIST_TYPE_INDIR_CALL
, stmt
, callee
);
1015 hist
->n_counters
= 3;
1016 hist
->hvalue
.counters
= XNEWVEC (gcov_type
, hist
->n_counters
);
1017 gimple_add_histogram_value (cfun
, stmt
, hist
);
1019 hist
->hvalue
.counters
[0] = direct_call
->profile_id
;
1020 hist
->hvalue
.counters
[1] = max_iter
->second
;
1021 hist
->hvalue
.counters
[2] = total
;
1026 struct cgraph_edge
*indirect_edge
1027 = cgraph_node::get (current_function_decl
)->get_edge (stmt
);
1031 fprintf (dump_file
, "Indirect call -> direct call ");
1032 print_generic_expr (dump_file
, callee
, TDF_SLIM
);
1033 fprintf (dump_file
, " => ");
1034 print_generic_expr (dump_file
, direct_call
->decl
, TDF_SLIM
);
1037 if (direct_call
== NULL
|| !check_ic_target (stmt
, direct_call
))
1040 fprintf (dump_file
, " not transforming\n");
1043 if (DECL_STRUCT_FUNCTION (direct_call
->decl
) == NULL
)
1046 fprintf (dump_file
, " no declaration\n");
1052 fprintf (dump_file
, " transformation on insn ");
1053 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1054 fprintf (dump_file
, "\n");
1057 /* FIXME: Count should be initialized. */
1058 struct cgraph_edge
*new_edge
1059 = indirect_edge
->make_speculative (direct_call
,
1060 profile_count::uninitialized ());
1061 new_edge
->redirect_call_stmt_to_callee ();
1062 gimple_remove_histogram_value (cfun
, stmt
, hist
);
1063 inline_call (new_edge
, true, NULL
, NULL
, false);
1066 /* From AutoFDO profiles, find values inside STMT for that we want to measure
1067 histograms and adds them to list VALUES. */
1070 afdo_vpt (gimple_stmt_iterator
*gsi
, const icall_target_map
&map
,
1073 afdo_indirect_call (gsi
, map
, transform
);
1076 typedef std::set
<basic_block
> bb_set
;
1077 typedef std::set
<edge
> edge_set
;
1080 is_bb_annotated (const basic_block bb
, const bb_set
&annotated
)
1082 return annotated
.find (bb
) != annotated
.end ();
1086 set_bb_annotated (basic_block bb
, bb_set
*annotated
)
1088 annotated
->insert (bb
);
1091 /* For a given BB, set its execution count. Attach value profile if a stmt
1092 is not in PROMOTED, because we only want to promote an indirect call once.
1093 Return TRUE if BB is annotated. */
1096 afdo_set_bb_count (basic_block bb
, const stmt_set
&promoted
)
1098 gimple_stmt_iterator gsi
;
1101 gcov_type max_count
= 0;
1102 bool has_annotated
= false;
1104 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1107 gimple
*stmt
= gsi_stmt (gsi
);
1108 if (gimple_clobber_p (stmt
) || is_gimple_debug (stmt
))
1110 if (afdo_source_profile
->get_count_info (stmt
, &info
))
1112 if (info
.count
> max_count
)
1113 max_count
= info
.count
;
1114 has_annotated
= true;
1115 if (info
.targets
.size () > 0
1116 && promoted
.find (stmt
) == promoted
.end ())
1117 afdo_vpt (&gsi
, info
.targets
, false);
1124 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1125 afdo_source_profile
->mark_annotated (gimple_location (gsi_stmt (gsi
)));
1126 for (gphi_iterator gpi
= gsi_start_phis (bb
);
1130 gphi
*phi
= gpi
.phi ();
1132 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
1133 afdo_source_profile
->mark_annotated (gimple_phi_arg_location (phi
, i
));
1135 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1136 afdo_source_profile
->mark_annotated (e
->goto_locus
);
1138 bb
->count
= profile_count::from_gcov_type (max_count
).afdo ();
1142 /* BB1 and BB2 are in an equivalent class iff:
1143 1. BB1 dominates BB2.
1144 2. BB2 post-dominates BB1.
1145 3. BB1 and BB2 are in the same loop nest.
1146 This function finds the equivalent class for each basic block, and
1147 stores a pointer to the first BB in its equivalent class. Meanwhile,
1148 set bb counts for the same equivalent class to be idenical. Update
1149 ANNOTATED_BB for the first BB in its equivalent class. */
1152 afdo_find_equiv_class (bb_set
*annotated_bb
)
1156 FOR_ALL_BB_FN (bb
, cfun
)
1159 FOR_ALL_BB_FN (bb
, cfun
)
1161 vec
<basic_block
> dom_bbs
;
1165 if (bb
->aux
!= NULL
)
1168 dom_bbs
= get_dominated_by (CDI_DOMINATORS
, bb
);
1169 FOR_EACH_VEC_ELT (dom_bbs
, i
, bb1
)
1170 if (bb1
->aux
== NULL
&& dominated_by_p (CDI_POST_DOMINATORS
, bb
, bb1
)
1171 && bb1
->loop_father
== bb
->loop_father
)
1174 if (bb1
->count
> bb
->count
&& is_bb_annotated (bb1
, *annotated_bb
))
1176 bb
->count
= bb1
->count
;
1177 set_bb_annotated (bb
, annotated_bb
);
1180 dom_bbs
= get_dominated_by (CDI_POST_DOMINATORS
, bb
);
1181 FOR_EACH_VEC_ELT (dom_bbs
, i
, bb1
)
1182 if (bb1
->aux
== NULL
&& dominated_by_p (CDI_DOMINATORS
, bb
, bb1
)
1183 && bb1
->loop_father
== bb
->loop_father
)
1186 if (bb1
->count
> bb
->count
&& is_bb_annotated (bb1
, *annotated_bb
))
1188 bb
->count
= bb1
->count
;
1189 set_bb_annotated (bb
, annotated_bb
);
1195 /* If a basic block's count is known, and only one of its in/out edges' count
1196 is unknown, its count can be calculated. Meanwhile, if all of the in/out
1197 edges' counts are known, then the basic block's unknown count can also be
1199 IS_SUCC is true if out edges of a basic blocks are examined.
1200 Update ANNOTATED_BB accordingly.
1201 Return TRUE if any basic block/edge count is changed. */
1204 afdo_propagate_edge (bool is_succ
, bb_set
*annotated_bb
)
1207 bool changed
= false;
1209 FOR_EACH_BB_FN (bb
, cfun
)
1211 edge e
, unknown_edge
= NULL
;
1213 int num_unknown_edge
= 0;
1214 profile_count total_known_count
= profile_count::zero ().afdo ();
1216 FOR_EACH_EDGE (e
, ei
, is_succ
? bb
->succs
: bb
->preds
)
1218 gcc_assert (AFDO_EINFO (e
) != NULL
);
1219 if (! AFDO_EINFO (e
)->is_annotated ())
1220 num_unknown_edge
++, unknown_edge
= e
;
1222 total_known_count
+= AFDO_EINFO (e
)->get_count ();
1225 /* Be careful not to annotate block with no successor in special cases. */
1226 if (num_unknown_edge
== 0 && total_known_count
> bb
->count
)
1228 bb
->count
= total_known_count
;
1229 if (!is_bb_annotated (bb
, *annotated_bb
))
1230 set_bb_annotated (bb
, annotated_bb
);
1233 else if (num_unknown_edge
== 1 && is_bb_annotated (bb
, *annotated_bb
))
1235 if (bb
->count
> total_known_count
)
1236 AFDO_EINFO (unknown_edge
)->set_count (bb
->count
- total_known_count
);
1238 AFDO_EINFO (unknown_edge
)->set_count (profile_count::zero().afdo ());
1239 AFDO_EINFO (unknown_edge
)->set_annotated ();
1246 /* Special propagation for circuit expressions. Because GCC translates
1247 control flow into data flow for circuit expressions. E.g.
1254 will be translated into:
1269 tmp = PHI (0 (BB1), 0 (BB.t1), 1 (BB.t2)
1275 In this case, we need to propagate through PHI to determine the edge
1276 count of BB1->BB.t1, BB.t1->BB.t2. */
1279 afdo_propagate_circuit (const bb_set
&annotated_bb
)
1282 FOR_ALL_BB_FN (bb
, cfun
)
1285 tree cmp_rhs
, cmp_lhs
;
1286 gimple
*cmp_stmt
= last_stmt (bb
);
1290 if (!cmp_stmt
|| gimple_code (cmp_stmt
) != GIMPLE_COND
)
1292 cmp_rhs
= gimple_cond_rhs (cmp_stmt
);
1293 cmp_lhs
= gimple_cond_lhs (cmp_stmt
);
1294 if (!TREE_CONSTANT (cmp_rhs
)
1295 || !(integer_zerop (cmp_rhs
) || integer_onep (cmp_rhs
)))
1297 if (TREE_CODE (cmp_lhs
) != SSA_NAME
)
1299 if (!is_bb_annotated (bb
, annotated_bb
))
1301 def_stmt
= SSA_NAME_DEF_STMT (cmp_lhs
);
1302 while (def_stmt
&& gimple_code (def_stmt
) == GIMPLE_ASSIGN
1303 && gimple_assign_single_p (def_stmt
)
1304 && TREE_CODE (gimple_assign_rhs1 (def_stmt
)) == SSA_NAME
)
1305 def_stmt
= SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt
));
1308 gphi
*phi_stmt
= dyn_cast
<gphi
*> (def_stmt
);
1311 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1313 unsigned i
, total
= 0;
1315 bool check_value_one
= (((integer_onep (cmp_rhs
))
1316 ^ (gimple_cond_code (cmp_stmt
) == EQ_EXPR
))
1317 ^ ((e
->flags
& EDGE_TRUE_VALUE
) != 0));
1318 if (! AFDO_EINFO (e
)->is_annotated ())
1320 for (i
= 0; i
< gimple_phi_num_args (phi_stmt
); i
++)
1322 tree val
= gimple_phi_arg_def (phi_stmt
, i
);
1323 edge ep
= gimple_phi_arg_edge (phi_stmt
, i
);
1325 if (!TREE_CONSTANT (val
)
1326 || !(integer_zerop (val
) || integer_onep (val
)))
1328 if (check_value_one
^ integer_onep (val
))
1332 if (! (AFDO_EINFO (e
)->get_count ()).nonzero_p ()
1333 && ! AFDO_EINFO (ep
)->is_annotated ())
1335 AFDO_EINFO (ep
)->set_count (profile_count::zero ().afdo ());
1336 AFDO_EINFO (ep
)->set_annotated ();
1339 if (total
== 1 && ! AFDO_EINFO (only_one
)->is_annotated ())
1341 AFDO_EINFO (only_one
)->set_count (AFDO_EINFO (e
)->get_count ());
1342 AFDO_EINFO (only_one
)->set_annotated ();
1348 /* Propagate the basic block count and edge count on the control flow
1349 graph. We do the propagation iteratively until stablize. */
1352 afdo_propagate (bb_set
*annotated_bb
)
1355 bool changed
= true;
1358 FOR_ALL_BB_FN (bb
, cfun
)
1360 bb
->count
= ((basic_block
)bb
->aux
)->count
;
1361 if (is_bb_annotated ((basic_block
)bb
->aux
, *annotated_bb
))
1362 set_bb_annotated (bb
, annotated_bb
);
1365 while (changed
&& i
++ < 10)
1369 if (afdo_propagate_edge (true, annotated_bb
))
1371 if (afdo_propagate_edge (false, annotated_bb
))
1373 afdo_propagate_circuit (*annotated_bb
);
1377 /* Propagate counts on control flow graph and calculate branch
1381 afdo_calculate_branch_prob (bb_set
*annotated_bb
)
1387 calculate_dominance_info (CDI_POST_DOMINATORS
);
1388 calculate_dominance_info (CDI_DOMINATORS
);
1389 loop_optimizer_init (0);
1391 FOR_ALL_BB_FN (bb
, cfun
)
1393 gcc_assert (bb
->aux
== NULL
);
1394 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1396 gcc_assert (e
->aux
== NULL
);
1397 e
->aux
= new edge_info ();
1401 afdo_find_equiv_class (annotated_bb
);
1402 afdo_propagate (annotated_bb
);
1404 FOR_EACH_BB_FN (bb
, cfun
)
1406 int num_unknown_succ
= 0;
1407 profile_count total_count
= profile_count::zero ().afdo ();
1409 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1411 gcc_assert (AFDO_EINFO (e
) != NULL
);
1412 if (! AFDO_EINFO (e
)->is_annotated ())
1415 total_count
+= AFDO_EINFO (e
)->get_count ();
1417 if (num_unknown_succ
== 0 && total_count
> profile_count::zero ())
1419 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1421 = AFDO_EINFO (e
)->get_count ().probability_in (total_count
);
1424 FOR_ALL_BB_FN (bb
, cfun
)
1427 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1428 if (AFDO_EINFO (e
) != NULL
)
1430 delete AFDO_EINFO (e
);
1435 loop_optimizer_finalize ();
1436 free_dominance_info (CDI_DOMINATORS
);
1437 free_dominance_info (CDI_POST_DOMINATORS
);
1440 /* Perform value profile transformation using AutoFDO profile. Add the
1441 promoted stmts to PROMOTED_STMTS. Return TRUE if there is any
1442 indirect call promoted. */
1445 afdo_vpt_for_early_inline (stmt_set
*promoted_stmts
)
1448 if (afdo_source_profile
->get_function_instance_by_decl (
1449 current_function_decl
) == NULL
)
1452 compute_fn_summary (cgraph_node::get (current_function_decl
), true);
1454 bool has_vpt
= false;
1455 FOR_EACH_BB_FN (bb
, cfun
)
1457 if (!has_indirect_call (bb
))
1459 gimple_stmt_iterator gsi
;
1461 gcov_type bb_count
= 0;
1462 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1465 gimple
*stmt
= gsi_stmt (gsi
);
1466 if (afdo_source_profile
->get_count_info (stmt
, &info
))
1467 bb_count
= MAX (bb_count
, info
.count
);
1470 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1472 gcall
*stmt
= dyn_cast
<gcall
*> (gsi_stmt (gsi
));
1473 /* IC_promotion and early_inline_2 is done in multiple iterations.
1474 No need to promoted the stmt if its in promoted_stmts (means
1475 it is already been promoted in the previous iterations). */
1476 if ((!stmt
) || gimple_call_fn (stmt
) == NULL
1477 || TREE_CODE (gimple_call_fn (stmt
)) == FUNCTION_DECL
1478 || promoted_stmts
->find (stmt
) != promoted_stmts
->end ())
1482 afdo_source_profile
->get_count_info (stmt
, &info
);
1483 info
.count
= bb_count
;
1484 if (afdo_source_profile
->update_inlined_ind_target (stmt
, &info
))
1486 /* Promote the indirect call and update the promoted_stmts. */
1487 promoted_stmts
->insert (stmt
);
1488 afdo_vpt (&gsi
, info
.targets
, true);
1496 unsigned todo
= optimize_inline_calls (current_function_decl
);
1497 if (todo
& TODO_update_ssa_any
)
1498 update_ssa (TODO_update_ssa
);
1505 /* Annotate auto profile to the control flow graph. Do not annotate value
1506 profile for stmts in PROMOTED_STMTS. */
1509 afdo_annotate_cfg (const stmt_set
&promoted_stmts
)
1512 bb_set annotated_bb
;
1513 const function_instance
*s
1514 = afdo_source_profile
->get_function_instance_by_decl (
1515 current_function_decl
);
1519 cgraph_node::get (current_function_decl
)->count
1520 = profile_count::from_gcov_type (s
->head_count ()).afdo ();
1521 ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
1522 = profile_count::from_gcov_type (s
->head_count ()).afdo ();
1523 EXIT_BLOCK_PTR_FOR_FN (cfun
)->count
= profile_count::zero ().afdo ();
1524 profile_count max_count
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1526 FOR_EACH_BB_FN (bb
, cfun
)
1528 /* As autoFDO uses sampling approach, we have to assume that all
1529 counters are zero when not seen by autoFDO. */
1530 bb
->count
= profile_count::zero ().afdo ();
1531 if (afdo_set_bb_count (bb
, promoted_stmts
))
1532 set_bb_annotated (bb
, &annotated_bb
);
1533 if (bb
->count
> max_count
)
1534 max_count
= bb
->count
;
1536 if (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
1537 > ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
->count
)
1539 ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
->count
1540 = ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1541 set_bb_annotated (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
, &annotated_bb
);
1543 if (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
1544 > EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
->count
)
1546 EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
->count
1547 = ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1548 set_bb_annotated (EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
, &annotated_bb
);
1550 afdo_source_profile
->mark_annotated (
1551 DECL_SOURCE_LOCATION (current_function_decl
));
1552 afdo_source_profile
->mark_annotated (cfun
->function_start_locus
);
1553 afdo_source_profile
->mark_annotated (cfun
->function_end_locus
);
1554 if (max_count
> profile_count::zero ())
1556 /* Calculate, propagate count and probability information on CFG. */
1557 afdo_calculate_branch_prob (&annotated_bb
);
1559 update_max_bb_count ();
1560 profile_status_for_fn (cfun
) = PROFILE_READ
;
1561 if (flag_value_profile_transformations
)
1563 gimple_value_profile_transformations ();
1564 free_dominance_info (CDI_DOMINATORS
);
1565 free_dominance_info (CDI_POST_DOMINATORS
);
1566 update_ssa (TODO_update_ssa
);
1570 /* Wrapper function to invoke early inliner. */
1575 compute_fn_summary (cgraph_node::get (current_function_decl
), true);
1576 unsigned todo
= early_inliner (cfun
);
1577 if (todo
& TODO_update_ssa_any
)
1578 update_ssa (TODO_update_ssa
);
1581 /* Use AutoFDO profile to annoate the control flow graph.
1582 Return the todo flag. */
1587 struct cgraph_node
*node
;
1589 if (symtab
->state
== FINISHED
)
1592 init_node_map (true);
1593 profile_info
= autofdo::afdo_profile_info
;
1595 FOR_EACH_FUNCTION (node
)
1597 if (!gimple_has_body_p (node
->decl
))
1600 /* Don't profile functions produced for builtin stuff. */
1601 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
1604 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
1606 /* First do indirect call promotion and early inline to make the
1607 IR match the profiled binary before actual annotation.
1609 This is needed because an indirect call might have been promoted
1610 and inlined in the profiled binary. If we do not promote and
1611 inline these indirect calls before annotation, the profile for
1612 these promoted functions will be lost.
1614 e.g. foo() --indirect_call--> bar()
1615 In profiled binary, the callsite is promoted and inlined, making
1616 the profile look like:
1626 Before AutoFDO pass, loc_foo_2 is not promoted thus not inlined.
1627 If we perform annotation on it, the profile inside bar@loc_foo2
1630 To avoid this, we promote loc_foo_2 and inline the promoted bar
1631 function before annotation, so the profile inside bar@loc_foo2
1633 autofdo::stmt_set promoted_stmts
;
1634 for (int i
= 0; i
< PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS
); i
++)
1636 if (!flag_value_profile_transformations
1637 || !autofdo::afdo_vpt_for_early_inline (&promoted_stmts
))
1643 autofdo::afdo_annotate_cfg (promoted_stmts
);
1644 compute_function_frequency ();
1646 /* Local pure-const may imply need to fixup the cfg. */
1647 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
1648 cleanup_tree_cfg ();
1650 free_dominance_info (CDI_DOMINATORS
);
1651 free_dominance_info (CDI_POST_DOMINATORS
);
1652 cgraph_edge::rebuild_edges ();
1653 compute_fn_summary (cgraph_node::get (current_function_decl
), true);
1657 return TODO_rebuild_cgraph_edges
;
1659 } /* namespace autofdo. */
1661 /* Read the profile from the profile data file. */
1664 read_autofdo_file (void)
1666 if (auto_profile_file
== NULL
)
1667 auto_profile_file
= DEFAULT_AUTO_PROFILE_FILE
;
1669 autofdo::afdo_profile_info
= XNEW (gcov_summary
);
1670 autofdo::afdo_profile_info
->runs
= 1;
1671 autofdo::afdo_profile_info
->sum_max
= 0;
1673 /* Read the profile from the profile file. */
1674 autofdo::read_profile ();
1677 /* Free the resources. */
1680 end_auto_profile (void)
1682 delete autofdo::afdo_source_profile
;
1683 delete autofdo::afdo_string_table
;
1684 profile_info
= NULL
;
1687 /* Returns TRUE if EDGE is hot enough to be inlined early. */
1690 afdo_callsite_hot_enough_for_early_inline (struct cgraph_edge
*edge
)
1693 = autofdo::afdo_source_profile
->get_callsite_total_count (edge
);
1698 profile_count pcount
= profile_count::from_gcov_type (count
).afdo ();
1699 gcov_summary
*saved_profile_info
= profile_info
;
1700 /* At early inline stage, profile_info is not set yet. We need to
1701 temporarily set it to afdo_profile_info to calculate hotness. */
1702 profile_info
= autofdo::afdo_profile_info
;
1703 is_hot
= maybe_hot_count_p (NULL
, pcount
);
1704 profile_info
= saved_profile_info
;
1714 const pass_data pass_data_ipa_auto_profile
= {
1715 SIMPLE_IPA_PASS
, "afdo", /* name */
1716 OPTGROUP_NONE
, /* optinfo_flags */
1717 TV_IPA_AUTOFDO
, /* tv_id */
1718 0, /* properties_required */
1719 0, /* properties_provided */
1720 0, /* properties_destroyed */
1721 0, /* todo_flags_start */
1722 0, /* todo_flags_finish */
1725 class pass_ipa_auto_profile
: public simple_ipa_opt_pass
1728 pass_ipa_auto_profile (gcc::context
*ctxt
)
1729 : simple_ipa_opt_pass (pass_data_ipa_auto_profile
, ctxt
)
1733 /* opt_pass methods: */
1737 return flag_auto_profile
;
1739 virtual unsigned int
1740 execute (function
*)
1742 return autofdo::auto_profile ();
1744 }; // class pass_ipa_auto_profile
1748 simple_ipa_opt_pass
*
1749 make_pass_ipa_auto_profile (gcc::context
*ctxt
)
1751 return new pass_ipa_auto_profile (ctxt
);