1 /* Read and annotate call graph profile from the auto profile data file.
2 Copyright (C) 2014. 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"
30 #include "tree-pass.h"
38 #include "hard-reg-set.h"
41 #include "dominance.h"
43 #include "basic-block.h"
44 #include "diagnostic-core.h"
47 #include "langhooks.h"
49 #include "tree-pass.h"
51 #include "tree-ssa-alias.h"
53 #include "tree-cfgcleanup.h"
54 #include "tree-ssa-operands.h"
55 #include "tree-into-ssa.h"
56 #include "internal-fn.h"
58 #include "gimple-expr.h"
60 #include "gimple-iterator.h"
61 #include "gimple-ssa.h"
63 #include "plugin-api.h"
66 #include "value-prof.h"
69 #include "alloc-pool.h"
71 #include "ipa-inline.h"
72 #include "tree-inline.h"
73 #include "stringpool.h"
74 #include "auto-profile.h"
76 /* The following routines implements AutoFDO optimization.
78 This optimization uses sampling profiles to annotate basic block counts
79 and uses heuristics to estimate branch probabilities.
81 There are three phases in AutoFDO:
83 Phase 1: Read profile from the profile data file.
84 The following info is read from the profile datafile:
85 * string_table: a map between function name and its index.
86 * autofdo_source_profile: a map from function_instance name to
87 function_instance. This is represented as a forest of
89 * WorkingSet: a histogram of how many instructions are covered for a
90 given percentage of total cycles. This is describing the binary
91 level information (not source level). This info is used to help
92 decide if we want aggressive optimizations that could increase
93 code footprint (e.g. loop unroll etc.)
94 A function instance is an instance of function that could either be a
95 standalone symbol, or a clone of a function that is inlined into another
98 Phase 2: Early inline + valur profile transformation.
99 Early inline uses autofdo_source_profile to find if a callsite is:
100 * inlined in the profiled binary.
101 * callee body is hot in the profiling run.
102 If both condition satisfies, early inline will inline the callsite
103 regardless of the code growth.
104 Phase 2 is an iterative process. During each iteration, we also check
105 if an indirect callsite is promoted and inlined in the profiling run.
106 If yes, vpt will happen to force promote it and in the next iteration,
107 einline will inline the promoted callsite in the next iteration.
109 Phase 3: Annotate control flow graph.
110 AutoFDO uses a separate pass to:
111 * Annotate basic block count
112 * Estimate branch probability
114 After the above 3 phases, all profile is readily annotated on the GCC IR.
115 AutoFDO tries to reuse all FDO infrastructure as much as possible to make
116 use of the profile. E.g. it uses existing mechanism to calculate the basic
117 block/edge frequency, as well as the cgraph node/edge count.
120 #define DEFAULT_AUTO_PROFILE_FILE "fbdata.afdo"
121 #define AUTO_PROFILE_VERSION 1
126 /* Represent a source location: (function_decl, lineno). */
127 typedef std::pair
<tree
, unsigned> decl_lineno
;
129 /* Represent an inline stack. vector[0] is the leaf node. */
130 typedef auto_vec
<decl_lineno
> inline_stack
;
132 /* String array that stores function names. */
133 typedef auto_vec
<char *> string_vector
;
135 /* Map from function name's index in string_table to target's
137 typedef std::map
<unsigned, gcov_type
> icall_target_map
;
139 /* Set of gimple stmts. Used to track if the stmt has already been promoted
141 typedef std::set
<gimple
> stmt_set
;
143 /* Represent count info of an inline stack. */
146 /* Sampled count of the inline stack. */
149 /* Map from indirect call target to its sample count. */
150 icall_target_map targets
;
152 /* Whether this inline stack is already used in annotation.
154 Each inline stack should only be used to annotate IR once.
155 This will be enforced when instruction-level discriminator
160 /* operator< for "const char *". */
161 struct string_compare
163 bool operator()(const char *a
, const char *b
) const
165 return strcmp (a
, b
) < 0;
169 /* Store a string array, indexed by string position in the array. */
178 /* For a given string, returns its index. */
179 int get_index (const char *name
) const;
181 /* For a given decl, returns the index of the decl name. */
182 int get_index_by_decl (tree decl
) const;
184 /* For a given index, returns the string. */
185 const char *get_name (int index
) const;
187 /* Read profile, return TRUE on success. */
191 typedef std::map
<const char *, unsigned, string_compare
> string_index_map
;
192 string_vector vector_
;
193 string_index_map map_
;
196 /* Profile of a function instance:
197 1. total_count of the function.
198 2. head_count (entry basic block count) of the function (only valid when
199 function is a top-level function_instance, i.e. it is the original copy
200 instead of the inlined copy).
201 3. map from source location (decl_lineno) to profile (count_info).
202 4. map from callsite to callee function_instance. */
203 class function_instance
206 typedef auto_vec
<function_instance
*> function_instance_stack
;
208 /* Read the profile and return a function_instance with head count as
209 HEAD_COUNT. Recursively read callsites to create nested function_instances
210 too. STACK is used to track the recursive creation process. */
211 static function_instance
*
212 read_function_instance (function_instance_stack
*stack
,
213 gcov_type head_count
);
215 /* Recursively deallocate all callsites (nested function_instances). */
216 ~function_instance ();
235 /* Traverse callsites of the current function_instance to find one at the
236 location of LINENO and callee name represented in DECL. */
237 function_instance
*get_function_instance_by_decl (unsigned lineno
,
240 /* Store the profile info for LOC in INFO. Return TRUE if profile info
242 bool get_count_info (location_t loc
, count_info
*info
) const;
244 /* Read the inlined indirect call target profile for STMT and store it in
245 MAP, return the total count for all inlined indirect calls. */
246 gcov_type
find_icall_target_map (gimple stmt
, icall_target_map
*map
) const;
248 /* Sum of counts that is used during annotation. */
249 gcov_type
total_annotated_count () const;
251 /* Mark LOC as annotated. */
252 void mark_annotated (location_t loc
);
255 /* Callsite, represented as (decl_lineno, callee_function_name_index). */
256 typedef std::pair
<unsigned, unsigned> callsite
;
258 /* Map from callsite to callee function_instance. */
259 typedef std::map
<callsite
, function_instance
*> callsite_map
;
261 function_instance (unsigned name
, gcov_type head_count
)
262 : name_ (name
), total_count_ (0), head_count_ (head_count
)
266 /* Map from source location (decl_lineno) to profile (count_info). */
267 typedef std::map
<unsigned, count_info
> position_count_map
;
269 /* function_instance name index in the string_table. */
272 /* Total sample count. */
273 gcov_type total_count_
;
275 /* Entry BB's sample count. */
276 gcov_type head_count_
;
278 /* Map from callsite location to callee function_instance. */
279 callsite_map callsites
;
281 /* Map from source location to count_info. */
282 position_count_map pos_counts
;
285 /* Profile for all functions. */
286 class autofdo_source_profile
289 static autofdo_source_profile
*
292 autofdo_source_profile
*map
= new autofdo_source_profile ();
300 ~autofdo_source_profile ();
302 /* For a given DECL, returns the top-level function_instance. */
303 function_instance
*get_function_instance_by_decl (tree decl
) const;
305 /* Find count_info for a given gimple STMT. If found, store the count_info
306 in INFO and return true; otherwise return false. */
307 bool get_count_info (gimple stmt
, count_info
*info
) const;
309 /* Find total count of the callee of EDGE. */
310 gcov_type
get_callsite_total_count (struct cgraph_edge
*edge
) const;
312 /* Update value profile INFO for STMT from the inlined indirect callsite.
313 Return true if INFO is updated. */
314 bool update_inlined_ind_target (gimple stmt
, count_info
*info
);
316 /* Mark LOC as annotated. */
317 void mark_annotated (location_t loc
);
320 /* Map from function_instance name index (in string_table) to
321 function_instance. */
322 typedef std::map
<unsigned, function_instance
*> name_function_instance_map
;
324 autofdo_source_profile () {}
326 /* Read AutoFDO profile and returns TRUE on success. */
329 /* Return the function_instance in the profile that correspond to the
332 get_function_instance_by_inline_stack (const inline_stack
&stack
) const;
334 name_function_instance_map map_
;
337 /* Store the strings read from the profile data file. */
338 static string_table
*afdo_string_table
;
340 /* Store the AutoFDO source profile. */
341 static autofdo_source_profile
*afdo_source_profile
;
343 /* gcov_ctr_summary structure to store the profile_info. */
344 static struct gcov_ctr_summary
*afdo_profile_info
;
346 /* Helper functions. */
348 /* Return the original name of NAME: strip the suffix that starts
349 with '.' Caller is responsible for freeing RET. */
352 get_original_name (const char *name
)
354 char *ret
= xstrdup (name
);
355 char *find
= strchr (ret
, '.');
361 /* Return the combined location, which is a 32bit integer in which
362 higher 16 bits stores the line offset of LOC to the start lineno
363 of DECL, The lower 16 bits stores the discrimnator. */
366 get_combined_location (location_t loc
, tree decl
)
368 /* TODO: allow more bits for line and less bits for discriminator. */
369 if (LOCATION_LINE (loc
) - DECL_SOURCE_LINE (decl
) >= (1<<16))
370 warning_at (loc
, OPT_Woverflow
, "Offset exceeds 16 bytes.");
371 return ((LOCATION_LINE (loc
) - DECL_SOURCE_LINE (decl
)) << 16);
374 /* Return the function decl of a given lexical BLOCK. */
377 get_function_decl_from_block (tree block
)
381 if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block
) == UNKNOWN_LOCATION
))
384 for (decl
= BLOCK_ABSTRACT_ORIGIN (block
);
385 decl
&& (TREE_CODE (decl
) == BLOCK
);
386 decl
= BLOCK_ABSTRACT_ORIGIN (decl
))
387 if (TREE_CODE (decl
) == FUNCTION_DECL
)
392 /* Store inline stack for STMT in STACK. */
395 get_inline_stack (location_t locus
, inline_stack
*stack
)
397 if (LOCATION_LOCUS (locus
) == UNKNOWN_LOCATION
)
400 tree block
= LOCATION_BLOCK (locus
);
401 if (block
&& TREE_CODE (block
) == BLOCK
)
404 for (block
= BLOCK_SUPERCONTEXT (block
);
405 block
&& (TREE_CODE (block
) == BLOCK
);
406 block
= BLOCK_SUPERCONTEXT (block
))
408 location_t tmp_locus
= BLOCK_SOURCE_LOCATION (block
);
409 if (LOCATION_LOCUS (tmp_locus
) == UNKNOWN_LOCATION
)
412 tree decl
= get_function_decl_from_block (block
);
414 std::make_pair (decl
, get_combined_location (locus
, decl
)));
420 std::make_pair (current_function_decl
,
421 get_combined_location (locus
, current_function_decl
)));
424 /* Return STMT's combined location, which is a 32bit integer in which
425 higher 16 bits stores the line offset of LOC to the start lineno
426 of DECL, The lower 16 bits stores the discrimnator. */
429 get_relative_location_for_stmt (gimple stmt
)
431 location_t locus
= gimple_location (stmt
);
432 if (LOCATION_LOCUS (locus
) == UNKNOWN_LOCATION
)
433 return UNKNOWN_LOCATION
;
435 for (tree block
= gimple_block (stmt
); block
&& (TREE_CODE (block
) == BLOCK
);
436 block
= BLOCK_SUPERCONTEXT (block
))
437 if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block
)) != UNKNOWN_LOCATION
)
438 return get_combined_location (locus
,
439 get_function_decl_from_block (block
));
440 return get_combined_location (locus
, current_function_decl
);
443 /* Return true if BB contains indirect call. */
446 has_indirect_call (basic_block bb
)
448 gimple_stmt_iterator gsi
;
450 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
452 gimple stmt
= gsi_stmt (gsi
);
453 if (gimple_code (stmt
) == GIMPLE_CALL
&& !gimple_call_internal_p (stmt
)
454 && (gimple_call_fn (stmt
) == NULL
455 || TREE_CODE (gimple_call_fn (stmt
)) != FUNCTION_DECL
))
461 /* Member functions for string_table. */
465 string_table::~string_table ()
467 for (unsigned i
= 0; i
< vector_
.length (); i
++)
472 /* Return the index of a given function NAME. Return -1 if NAME is not
473 found in string table. */
476 string_table::get_index (const char *name
) const
480 string_index_map::const_iterator iter
= map_
.find (name
);
481 if (iter
== map_
.end ())
487 /* Return the index of a given function DECL. Return -1 if DECL is not
488 found in string table. */
491 string_table::get_index_by_decl (tree decl
) const
494 = get_original_name (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
)));
495 int ret
= get_index (name
);
499 ret
= get_index (lang_hooks
.dwarf_name (decl
, 0));
502 if (DECL_ABSTRACT_ORIGIN (decl
))
503 return get_index_by_decl (DECL_ABSTRACT_ORIGIN (decl
));
508 /* Return the function name of a given INDEX. */
511 string_table::get_name (int index
) const
513 gcc_assert (index
> 0 && index
< (int)vector_
.length ());
514 return vector_
[index
];
517 /* Read the string table. Return TRUE if reading is successful. */
520 string_table::read ()
522 if (gcov_read_unsigned () != GCOV_TAG_AFDO_FILE_NAMES
)
524 /* Skip the length of the section. */
525 gcov_read_unsigned ();
526 /* Read in the file name table. */
527 unsigned string_num
= gcov_read_unsigned ();
528 for (unsigned i
= 0; i
< string_num
; i
++)
530 vector_
.safe_push (get_original_name (gcov_read_string ()));
531 map_
[vector_
.last ()] = i
;
536 /* Member functions for function_instance. */
538 function_instance::~function_instance ()
540 for (callsite_map::iterator iter
= callsites
.begin ();
541 iter
!= callsites
.end (); ++iter
)
545 /* Traverse callsites of the current function_instance to find one at the
546 location of LINENO and callee name represented in DECL. */
549 function_instance::get_function_instance_by_decl (unsigned lineno
,
552 int func_name_idx
= afdo_string_table
->get_index_by_decl (decl
);
553 if (func_name_idx
!= -1)
555 callsite_map::const_iterator ret
556 = callsites
.find (std::make_pair (lineno
, func_name_idx
));
557 if (ret
!= callsites
.end ())
561 = afdo_string_table
->get_index (lang_hooks
.dwarf_name (decl
, 0));
562 if (func_name_idx
!= -1)
564 callsite_map::const_iterator ret
565 = callsites
.find (std::make_pair (lineno
, func_name_idx
));
566 if (ret
!= callsites
.end ())
569 if (DECL_ABSTRACT_ORIGIN (decl
))
570 return get_function_instance_by_decl (lineno
, DECL_ABSTRACT_ORIGIN (decl
));
575 /* Store the profile info for LOC in INFO. Return TRUE if profile info
579 function_instance::get_count_info (location_t loc
, count_info
*info
) const
581 position_count_map::const_iterator iter
= pos_counts
.find (loc
);
582 if (iter
== pos_counts
.end ())
584 *info
= iter
->second
;
588 /* Mark LOC as annotated. */
591 function_instance::mark_annotated (location_t loc
)
593 position_count_map::iterator iter
= pos_counts
.find (loc
);
594 if (iter
== pos_counts
.end ())
596 iter
->second
.annotated
= true;
599 /* Read the inlinied indirect call target profile for STMT and store it in
600 MAP, return the total count for all inlined indirect calls. */
603 function_instance::find_icall_target_map (gimple stmt
,
604 icall_target_map
*map
) const
607 unsigned stmt_offset
= get_relative_location_for_stmt (stmt
);
609 for (callsite_map::const_iterator iter
= callsites
.begin ();
610 iter
!= callsites
.end (); ++iter
)
612 unsigned callee
= iter
->second
->name ();
613 /* Check if callsite location match the stmt. */
614 if (iter
->first
.first
!= stmt_offset
)
616 struct cgraph_node
*node
= cgraph_node::get_for_asmname (
617 get_identifier (afdo_string_table
->get_name (callee
)));
620 if (!check_ic_target (stmt
, node
))
622 (*map
)[callee
] = iter
->second
->total_count ();
623 ret
+= iter
->second
->total_count ();
628 /* Read the profile and create a function_instance with head count as
629 HEAD_COUNT. Recursively read callsites to create nested function_instances
630 too. STACK is used to track the recursive creation process. */
632 /* function instance profile format:
636 NUM_POS_COUNTS: 4 bytes
637 NUM_CALLSITES: 4 byte
639 POS_1_OFFSET: 4 bytes
643 VALUE_PROFILE_TYPE: 4 bytes
653 CALLSITE_1_OFFSET: 4 bytes
654 FUNCTION_INSTANCE_PROFILE (nested)
660 function_instance::read_function_instance (function_instance_stack
*stack
,
661 gcov_type head_count
)
663 unsigned name
= gcov_read_unsigned ();
664 unsigned num_pos_counts
= gcov_read_unsigned ();
665 unsigned num_callsites
= gcov_read_unsigned ();
666 function_instance
*s
= new function_instance (name
, head_count
);
667 stack
->safe_push (s
);
669 for (unsigned i
= 0; i
< num_pos_counts
; i
++)
671 unsigned offset
= gcov_read_unsigned () & 0xffff0000;
672 unsigned num_targets
= gcov_read_unsigned ();
673 gcov_type count
= gcov_read_counter ();
674 s
->pos_counts
[offset
].count
= count
;
675 for (unsigned j
= 0; j
< stack
->length (); j
++)
676 (*stack
)[j
]->total_count_
+= count
;
677 for (unsigned j
= 0; j
< num_targets
; j
++)
679 /* Only indirect call target histogram is supported now. */
680 gcov_read_unsigned ();
681 gcov_type target_idx
= gcov_read_counter ();
682 s
->pos_counts
[offset
].targets
[target_idx
] = gcov_read_counter ();
685 for (unsigned i
= 0; i
< num_callsites
; i
++)
687 unsigned offset
= gcov_read_unsigned ();
688 function_instance
*callee_function_instance
689 = read_function_instance (stack
, 0);
690 s
->callsites
[std::make_pair (offset
, callee_function_instance
->name ())]
691 = callee_function_instance
;
697 /* Sum of counts that is used during annotation. */
700 function_instance::total_annotated_count () const
703 for (callsite_map::const_iterator iter
= callsites
.begin ();
704 iter
!= callsites
.end (); ++iter
)
705 ret
+= iter
->second
->total_annotated_count ();
706 for (position_count_map::const_iterator iter
= pos_counts
.begin ();
707 iter
!= pos_counts
.end (); ++iter
)
708 if (iter
->second
.annotated
)
709 ret
+= iter
->second
.count
;
713 /* Member functions for autofdo_source_profile. */
715 autofdo_source_profile::~autofdo_source_profile ()
717 for (name_function_instance_map::const_iterator iter
= map_
.begin ();
718 iter
!= map_
.end (); ++iter
)
722 /* For a given DECL, returns the top-level function_instance. */
725 autofdo_source_profile::get_function_instance_by_decl (tree decl
) const
727 int index
= afdo_string_table
->get_index_by_decl (decl
);
730 name_function_instance_map::const_iterator ret
= map_
.find (index
);
731 return ret
== map_
.end () ? NULL
: ret
->second
;
734 /* Find count_info for a given gimple STMT. If found, store the count_info
735 in INFO and return true; otherwise return false. */
738 autofdo_source_profile::get_count_info (gimple stmt
, count_info
*info
) const
740 if (LOCATION_LOCUS (gimple_location (stmt
)) == cfun
->function_end_locus
)
744 get_inline_stack (gimple_location (stmt
), &stack
);
745 if (stack
.length () == 0)
747 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
750 return s
->get_count_info (stack
[0].second
, info
);
753 /* Mark LOC as annotated. */
756 autofdo_source_profile::mark_annotated (location_t loc
)
759 get_inline_stack (loc
, &stack
);
760 if (stack
.length () == 0)
762 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
765 s
->mark_annotated (stack
[0].second
);
768 /* Update value profile INFO for STMT from the inlined indirect callsite.
769 Return true if INFO is updated. */
772 autofdo_source_profile::update_inlined_ind_target (gimple stmt
,
775 if (LOCATION_LOCUS (gimple_location (stmt
)) == cfun
->function_end_locus
)
779 get_count_info (stmt
, &old_info
);
781 for (icall_target_map::const_iterator iter
= old_info
.targets
.begin ();
782 iter
!= old_info
.targets
.end (); ++iter
)
783 total
+= iter
->second
;
785 /* Program behavior changed, original promoted (and inlined) target is not
786 hot any more. Will avoid promote the original target.
788 To check if original promoted target is still hot, we check the total
789 count of the unpromoted targets (stored in old_info). If it is no less
790 than half of the callsite count (stored in INFO), the original promoted
791 target is considered not hot any more. */
792 if (total
>= info
->count
/ 2)
796 get_inline_stack (gimple_location (stmt
), &stack
);
797 if (stack
.length () == 0)
799 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
802 icall_target_map map
;
803 if (s
->find_icall_target_map (stmt
, &map
) == 0)
805 for (icall_target_map::const_iterator iter
= map
.begin ();
806 iter
!= map
.end (); ++iter
)
807 info
->targets
[iter
->first
] = iter
->second
;
811 /* Find total count of the callee of EDGE. */
814 autofdo_source_profile::get_callsite_total_count (
815 struct cgraph_edge
*edge
) const
818 stack
.safe_push (std::make_pair (edge
->callee
->decl
, 0));
819 get_inline_stack (gimple_location (edge
->call_stmt
), &stack
);
821 function_instance
*s
= get_function_instance_by_inline_stack (stack
);
823 || afdo_string_table
->get_index (IDENTIFIER_POINTER (
824 DECL_ASSEMBLER_NAME (edge
->callee
->decl
))) != s
->name ())
827 return s
->total_count ();
830 /* Read AutoFDO profile and returns TRUE on success. */
832 /* source profile format:
834 GCOV_TAG_AFDO_FUNCTION: 4 bytes
836 NUM_FUNCTIONS: 4 bytes
840 FUNCTION_INSTANCE_N. */
843 autofdo_source_profile::read ()
845 if (gcov_read_unsigned () != GCOV_TAG_AFDO_FUNCTION
)
847 inform (0, "Not expected TAG.");
851 /* Skip the length of the section. */
852 gcov_read_unsigned ();
854 /* Read in the function/callsite profile, and store it in local
856 unsigned function_num
= gcov_read_unsigned ();
857 for (unsigned i
= 0; i
< function_num
; i
++)
859 function_instance::function_instance_stack stack
;
860 function_instance
*s
= function_instance::read_function_instance (
861 &stack
, gcov_read_counter ());
862 afdo_profile_info
->sum_all
+= s
->total_count ();
863 map_
[s
->name ()] = s
;
868 /* Return the function_instance in the profile that correspond to the
872 autofdo_source_profile::get_function_instance_by_inline_stack (
873 const inline_stack
&stack
) const
875 name_function_instance_map::const_iterator iter
= map_
.find (
876 afdo_string_table
->get_index_by_decl (stack
[stack
.length () - 1].first
));
877 if (iter
== map_
.end())
879 function_instance
*s
= iter
->second
;
880 for (unsigned i
= stack
.length() - 1; i
> 0; i
--)
882 s
= s
->get_function_instance_by_decl (
883 stack
[i
].second
, stack
[i
- 1].first
);
890 /* Module profile is only used by LIPO. Here we simply ignore it. */
893 fake_read_autofdo_module_profile ()
895 /* Read in the module info. */
896 gcov_read_unsigned ();
898 /* Skip the length of the section. */
899 gcov_read_unsigned ();
901 /* Read in the file name table. */
902 unsigned total_module_num
= gcov_read_unsigned ();
903 gcc_assert (total_module_num
== 0);
906 /* Read data from profile data file. */
911 if (gcov_open (auto_profile_file
, 1) == 0)
912 error ("Cannot open profile file %s.", auto_profile_file
);
914 if (gcov_read_unsigned () != GCOV_DATA_MAGIC
)
915 error ("AutoFDO profile magic number does not mathch.");
917 /* Skip the version number. */
918 unsigned version
= gcov_read_unsigned ();
919 if (version
!= AUTO_PROFILE_VERSION
)
920 error ("AutoFDO profile version %u does match %u.",
921 version
, AUTO_PROFILE_VERSION
);
923 /* Skip the empty integer. */
924 gcov_read_unsigned ();
927 afdo_string_table
= new string_table ();
928 if (!afdo_string_table
->read())
929 error ("Cannot read string table from %s.", auto_profile_file
);
931 /* autofdo_source_profile. */
932 afdo_source_profile
= autofdo_source_profile::create ();
933 if (afdo_source_profile
== NULL
)
934 error ("Cannot read function profile from %s.", auto_profile_file
);
936 /* autofdo_module_profile. */
937 fake_read_autofdo_module_profile ();
939 /* Read in the working set. */
940 if (gcov_read_unsigned () != GCOV_TAG_AFDO_WORKING_SET
)
941 error ("Cannot read working set from %s.", auto_profile_file
);
943 /* Skip the length of the section. */
944 gcov_read_unsigned ();
945 gcov_working_set_t set
[128];
946 for (unsigned i
= 0; i
< 128; i
++)
948 set
[i
].num_counters
= gcov_read_unsigned ();
949 set
[i
].min_counter
= gcov_read_counter ();
951 add_working_set (set
);
954 /* From AutoFDO profiles, find values inside STMT for that we want to measure
955 histograms for indirect-call optimization.
957 This function is actually served for 2 purposes:
958 Â Â * before annotation, we need to mark histogram, promote and inline
959 Â Â * after annotation, we just need to mark, and let follow-up logic to
960 Â Â Â decide if it needs to promote and inline. */
963 afdo_indirect_call (gimple_stmt_iterator
*gsi
, const icall_target_map
&map
,
966 gimple stmt
= gsi_stmt (*gsi
);
969 if (map
.size () == 0 || gimple_code (stmt
) != GIMPLE_CALL
970 || 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 promot 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 (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1090 gimple phi
= gsi_stmt (gsi
);
1092 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
1093 afdo_source_profile
->mark_annotated (gimple_phi_arg_location (phi
, i
));
1095 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1096 afdo_source_profile
->mark_annotated (e
->goto_locus
);
1098 bb
->count
= max_count
;
1102 /* BB1 and BB2 are in an equivalent class iff:
1103 1. BB1 dominates BB2.
1104 2. BB2 post-dominates BB1.
1105 3. BB1 and BB2 are in the same loop nest.
1106 This function finds the equivalent class for each basic block, and
1107 stores a pointer to the first BB in its equivalent class. Meanwhile,
1108 set bb counts for the same equivalent class to be idenical. Update
1109 ANNOTATED_BB for the first BB in its equivalent class. */
1112 afdo_find_equiv_class (bb_set
*annotated_bb
)
1116 FOR_ALL_BB_FN (bb
, cfun
)
1119 FOR_ALL_BB_FN (bb
, cfun
)
1121 vec
<basic_block
> dom_bbs
;
1125 if (bb
->aux
!= NULL
)
1128 dom_bbs
= get_dominated_by (CDI_DOMINATORS
, bb
);
1129 FOR_EACH_VEC_ELT (dom_bbs
, i
, bb1
)
1130 if (bb1
->aux
== NULL
&& dominated_by_p (CDI_POST_DOMINATORS
, bb
, bb1
)
1131 && bb1
->loop_father
== bb
->loop_father
)
1134 if (bb1
->count
> bb
->count
&& is_bb_annotated (bb1
, *annotated_bb
))
1136 bb
->count
= MAX (bb
->count
, bb1
->count
);
1137 set_bb_annotated (bb
, annotated_bb
);
1140 dom_bbs
= get_dominated_by (CDI_POST_DOMINATORS
, bb
);
1141 FOR_EACH_VEC_ELT (dom_bbs
, i
, bb1
)
1142 if (bb1
->aux
== NULL
&& dominated_by_p (CDI_DOMINATORS
, bb
, bb1
)
1143 && bb1
->loop_father
== bb
->loop_father
)
1146 if (bb1
->count
> bb
->count
&& is_bb_annotated (bb1
, *annotated_bb
))
1148 bb
->count
= MAX (bb
->count
, bb1
->count
);
1149 set_bb_annotated (bb
, annotated_bb
);
1155 /* If a basic block's count is known, and only one of its in/out edges' count
1156 is unknown, its count can be calculated. Meanwhile, if all of the in/out
1157 edges' counts are known, then the basic block's unknown count can also be
1159 IS_SUCC is true if out edges of a basic blocks are examined.
1160 Update ANNOTATED_BB and ANNOTATED_EDGE accordingly.
1161 Return TRUE if any basic block/edge count is changed. */
1164 afdo_propagate_edge (bool is_succ
, bb_set
*annotated_bb
,
1165 edge_set
*annotated_edge
)
1168 bool changed
= false;
1170 FOR_EACH_BB_FN (bb
, cfun
)
1172 edge e
, unknown_edge
= NULL
;
1174 int num_unknown_edge
= 0;
1175 gcov_type total_known_count
= 0;
1177 FOR_EACH_EDGE (e
, ei
, is_succ
? bb
->succs
: bb
->preds
)
1178 if (!is_edge_annotated (e
, *annotated_edge
))
1179 num_unknown_edge
++, unknown_edge
= e
;
1181 total_known_count
+= e
->count
;
1183 if (num_unknown_edge
== 0)
1185 if (total_known_count
> bb
->count
)
1187 bb
->count
= total_known_count
;
1190 if (!is_bb_annotated (bb
, *annotated_bb
))
1192 set_bb_annotated (bb
, annotated_bb
);
1196 else if (num_unknown_edge
== 1 && is_bb_annotated (bb
, *annotated_bb
))
1198 if (bb
->count
>= total_known_count
)
1199 unknown_edge
->count
= bb
->count
- total_known_count
;
1201 unknown_edge
->count
= 0;
1202 set_edge_annotated (unknown_edge
, annotated_edge
);
1209 /* Special propagation for circuit expressions. Because GCC translates
1210 control flow into data flow for circuit expressions. E.g.
1217 will be translated into:
1232 tmp = PHI (0 (BB1), 0 (BB.t1), 1 (BB.t2)
1238 In this case, we need to propagate through PHI to determine the edge
1239 count of BB1->BB.t1, BB.t1->BB.t2.
1240 Update ANNOTATED_EDGE accordingly. */
1243 afdo_propagate_circuit (const bb_set
&annotated_bb
, edge_set
*annotated_edge
)
1246 FOR_ALL_BB_FN (bb
, cfun
)
1249 tree cmp_rhs
, cmp_lhs
;
1250 gimple cmp_stmt
= last_stmt (bb
);
1254 if (!cmp_stmt
|| gimple_code (cmp_stmt
) != GIMPLE_COND
)
1256 cmp_rhs
= gimple_cond_rhs (cmp_stmt
);
1257 cmp_lhs
= gimple_cond_lhs (cmp_stmt
);
1258 if (!TREE_CONSTANT (cmp_rhs
)
1259 || !(integer_zerop (cmp_rhs
) || integer_onep (cmp_rhs
)))
1261 if (TREE_CODE (cmp_lhs
) != SSA_NAME
)
1263 if (!is_bb_annotated (bb
, annotated_bb
))
1265 phi_stmt
= SSA_NAME_DEF_STMT (cmp_lhs
);
1266 while (phi_stmt
&& gimple_code (phi_stmt
) == GIMPLE_ASSIGN
1267 && gimple_assign_single_p (phi_stmt
)
1268 && TREE_CODE (gimple_assign_rhs1 (phi_stmt
)) == SSA_NAME
)
1269 phi_stmt
= SSA_NAME_DEF_STMT (gimple_assign_rhs1 (phi_stmt
));
1270 if (!phi_stmt
|| gimple_code (phi_stmt
) != GIMPLE_PHI
)
1272 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1274 unsigned i
, total
= 0;
1276 bool check_value_one
= (((integer_onep (cmp_rhs
))
1277 ^ (gimple_cond_code (cmp_stmt
) == EQ_EXPR
))
1278 ^ ((e
->flags
& EDGE_TRUE_VALUE
) != 0));
1279 if (!is_edge_annotated (e
, *annotated_edge
))
1281 for (i
= 0; i
< gimple_phi_num_args (phi_stmt
); i
++)
1283 tree val
= gimple_phi_arg_def (phi_stmt
, i
);
1284 edge ep
= gimple_phi_arg_edge (phi_stmt
, i
);
1286 if (!TREE_CONSTANT (val
)
1287 || !(integer_zerop (val
) || integer_onep (val
)))
1289 if (check_value_one
^ integer_onep (val
))
1293 if (e
->probability
== 0 && !is_edge_annotated (ep
, *annotated_edge
))
1295 ep
->probability
= 0;
1297 set_edge_annotated (ep
, annotated_edge
);
1300 if (total
== 1 && !is_edge_annotated (only_one
, *annotated_edge
))
1302 only_one
->probability
= e
->probability
;
1303 only_one
->count
= e
->count
;
1304 set_edge_annotated (only_one
, annotated_edge
);
1310 /* Propagate the basic block count and edge count on the control flow
1311 graph. We do the propagation iteratively until stablize. */
1314 afdo_propagate (bb_set
*annotated_bb
, edge_set
*annotated_edge
)
1317 bool changed
= true;
1320 FOR_ALL_BB_FN (bb
, cfun
)
1322 bb
->count
= ((basic_block
)bb
->aux
)->count
;
1323 if (is_bb_annotated ((const basic_block
)bb
->aux
, *annotated_bb
))
1324 set_bb_annotated (bb
, annotated_bb
);
1327 while (changed
&& i
++ < 10)
1331 if (afdo_propagate_edge (true, annotated_bb
, annotated_edge
))
1333 if (afdo_propagate_edge (false, annotated_bb
, annotated_edge
))
1335 afdo_propagate_circuit (*annotated_bb
, annotated_edge
);
1339 /* Propagate counts on control flow graph and calculate branch
1343 afdo_calculate_branch_prob (bb_set
*annotated_bb
, edge_set
*annotated_edge
)
1346 bool has_sample
= false;
1348 FOR_EACH_BB_FN (bb
, cfun
)
1355 calculate_dominance_info (CDI_POST_DOMINATORS
);
1356 calculate_dominance_info (CDI_DOMINATORS
);
1357 loop_optimizer_init (0);
1359 afdo_find_equiv_class (annotated_bb
);
1360 afdo_propagate (annotated_bb
, annotated_edge
);
1362 FOR_EACH_BB_FN (bb
, cfun
)
1366 int num_unknown_succ
= 0;
1367 gcov_type total_count
= 0;
1369 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1371 if (!is_edge_annotated (e
, *annotated_edge
))
1374 total_count
+= e
->count
;
1376 if (num_unknown_succ
== 0 && total_count
> 0)
1378 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1379 e
->probability
= (double)e
->count
* REG_BR_PROB_BASE
/ total_count
;
1382 FOR_ALL_BB_FN (bb
, cfun
)
1387 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1388 e
->count
= (double)bb
->count
* e
->probability
/ REG_BR_PROB_BASE
;
1392 loop_optimizer_finalize ();
1393 free_dominance_info (CDI_DOMINATORS
);
1394 free_dominance_info (CDI_POST_DOMINATORS
);
1397 /* Perform value profile transformation using AutoFDO profile. Add the
1398 promoted stmts to PROMOTED_STMTS. Return TRUE if there is any
1399 indirect call promoted. */
1402 afdo_vpt_for_early_inline (stmt_set
*promoted_stmts
)
1405 if (afdo_source_profile
->get_function_instance_by_decl (
1406 current_function_decl
) == NULL
)
1409 compute_inline_parameters (cgraph_node::get (current_function_decl
), true);
1411 bool has_vpt
= false;
1412 FOR_EACH_BB_FN (bb
, cfun
)
1414 if (!has_indirect_call (bb
))
1416 gimple_stmt_iterator gsi
;
1418 gcov_type bb_count
= 0;
1419 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1422 gimple stmt
= gsi_stmt (gsi
);
1423 if (afdo_source_profile
->get_count_info (stmt
, &info
))
1424 bb_count
= MAX (bb_count
, info
.count
);
1427 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1429 gimple stmt
= gsi_stmt (gsi
);
1430 /* IC_promotion and early_inline_2 is done in multiple iterations.
1431 No need to promoted the stmt if its in promoted_stmts (means
1432 it is already been promoted in the previous iterations). */
1433 if (gimple_code (stmt
) != GIMPLE_CALL
|| gimple_call_fn (stmt
) == NULL
1434 || TREE_CODE (gimple_call_fn (stmt
)) == FUNCTION_DECL
1435 || promoted_stmts
->find (stmt
) != promoted_stmts
->end ())
1439 afdo_source_profile
->get_count_info (stmt
, &info
);
1440 info
.count
= bb_count
;
1441 if (afdo_source_profile
->update_inlined_ind_target (stmt
, &info
))
1443 /* Promote the indirect call and update the promoted_stmts. */
1444 promoted_stmts
->insert (stmt
);
1445 afdo_vpt (&gsi
, info
.targets
, true);
1452 optimize_inline_calls (current_function_decl
);
1459 /* Annotate auto profile to the control flow graph. Do not annotate value
1460 profile for stmts in PROMOTED_STMTS. */
1463 afdo_annotate_cfg (const stmt_set
&promoted_stmts
)
1466 bb_set annotated_bb
;
1467 edge_set annotated_edge
;
1468 const function_instance
*s
1469 = afdo_source_profile
->get_function_instance_by_decl (
1470 current_function_decl
);
1474 cgraph_node::get (current_function_decl
)->count
= s
->head_count ();
1475 ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
= s
->head_count ();
1476 gcov_type max_count
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1478 FOR_EACH_BB_FN (bb
, cfun
)
1484 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1487 if (afdo_set_bb_count (bb
, promoted_stmts
))
1488 set_bb_annotated (bb
, &annotated_bb
);
1489 if (bb
->count
> max_count
)
1490 max_count
= bb
->count
;
1492 if (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
1493 > ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
->count
)
1495 ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
->count
1496 = ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1497 set_bb_annotated (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
, &annotated_bb
);
1499 if (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
1500 > EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
->count
)
1502 EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
->count
1503 = ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
1504 set_bb_annotated (EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
, &annotated_bb
);
1506 afdo_source_profile
->mark_annotated (
1507 DECL_SOURCE_LOCATION (current_function_decl
));
1508 afdo_source_profile
->mark_annotated (cfun
->function_start_locus
);
1509 afdo_source_profile
->mark_annotated (cfun
->function_end_locus
);
1512 afdo_calculate_branch_prob (&annotated_bb
, &annotated_edge
);
1514 profile_status_for_fn (cfun
) = PROFILE_READ
;
1516 if (flag_value_profile_transformations
)
1517 gimple_value_profile_transformations ();
1520 /* Wrapper function to invoke early inliner. */
1525 compute_inline_parameters (cgraph_node::get (current_function_decl
), true);
1526 unsigned todo
= early_inliner (cfun
);
1527 if (todo
& TODO_update_ssa_any
)
1528 update_ssa (TODO_update_ssa
);
1531 /* Use AutoFDO profile to annoate the control flow graph.
1532 Return the todo flag. */
1537 struct cgraph_node
*node
;
1539 if (symtab
->state
== FINISHED
)
1542 init_node_map (true);
1543 profile_info
= autofdo::afdo_profile_info
;
1545 FOR_EACH_FUNCTION (node
)
1547 if (!gimple_has_body_p (node
->decl
))
1550 /* Don't profile functions produced for builtin stuff. */
1551 if (DECL_SOURCE_LOCATION (node
->decl
) == BUILTINS_LOCATION
)
1554 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
1556 /* First do indirect call promotion and early inline to make the
1557 IR match the profiled binary before actual annotation.
1559 This is needed because an indirect call might have been promoted
1560 and inlined in the profiled binary. If we do not promote and
1561 inline these indirect calls before annotation, the profile for
1562 these promoted functions will be lost.
1564 e.g. foo() --indirect_call--> bar()
1565 In profiled binary, the callsite is promoted and inlined, making
1566 the profile look like:
1576 Before AutoFDO pass, loc_foo_2 is not promoted thus not inlined.
1577 If we perform annotation on it, the profile inside bar@loc_foo2
1580 To avoid this, we promote loc_foo_2 and inline the promoted bar
1581 function before annotation, so the profile inside bar@loc_foo2
1583 autofdo::stmt_set promoted_stmts
;
1584 for (int i
= 0; i
< PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS
); i
++)
1586 if (!flag_value_profile_transformations
1587 || !autofdo::afdo_vpt_for_early_inline (&promoted_stmts
))
1593 autofdo::afdo_annotate_cfg (promoted_stmts
);
1594 compute_function_frequency ();
1595 update_ssa (TODO_update_ssa
);
1597 /* Local pure-const may imply need to fixup the cfg. */
1598 if (execute_fixup_cfg () & TODO_cleanup_cfg
)
1599 cleanup_tree_cfg ();
1601 free_dominance_info (CDI_DOMINATORS
);
1602 free_dominance_info (CDI_POST_DOMINATORS
);
1603 cgraph_edge::rebuild_edges ();
1607 return TODO_rebuild_cgraph_edges
;
1609 } /* namespace autofdo. */
1611 /* Read the profile from the profile data file. */
1614 read_autofdo_file (void)
1616 if (auto_profile_file
== NULL
)
1617 auto_profile_file
= DEFAULT_AUTO_PROFILE_FILE
;
1619 autofdo::afdo_profile_info
= (struct gcov_ctr_summary
*)xcalloc (
1620 1, sizeof (struct gcov_ctr_summary
));
1621 autofdo::afdo_profile_info
->runs
= 1;
1622 autofdo::afdo_profile_info
->sum_max
= 0;
1623 autofdo::afdo_profile_info
->sum_all
= 0;
1625 /* Read the profile from the profile file. */
1626 autofdo::read_profile ();
1629 /* Free the resources. */
1632 end_auto_profile (void)
1634 delete autofdo::afdo_source_profile
;
1635 delete autofdo::afdo_string_table
;
1636 profile_info
= NULL
;
1639 /* Returns TRUE if EDGE is hot enough to be inlined early. */
1642 afdo_callsite_hot_enough_for_early_inline (struct cgraph_edge
*edge
)
1645 = autofdo::afdo_source_profile
->get_callsite_total_count (edge
);
1649 const struct gcov_ctr_summary
*saved_profile_info
= profile_info
;
1650 /* At earling inline stage, profile_info is not set yet. We need to
1651 temporarily set it to afdo_profile_info to calculate hotness. */
1652 profile_info
= autofdo::afdo_profile_info
;
1653 is_hot
= maybe_hot_count_p (NULL
, count
);
1654 profile_info
= saved_profile_info
;
1664 const pass_data pass_data_ipa_auto_profile
= {
1665 SIMPLE_IPA_PASS
, "afdo", /* name */
1666 OPTGROUP_NONE
, /* optinfo_flags */
1667 TV_IPA_AUTOFDO
, /* tv_id */
1668 0, /* properties_required */
1669 0, /* properties_provided */
1670 0, /* properties_destroyed */
1671 0, /* todo_flags_start */
1672 0, /* todo_flags_finish */
1675 class pass_ipa_auto_profile
: public simple_ipa_opt_pass
1678 pass_ipa_auto_profile (gcc::context
*ctxt
)
1679 : simple_ipa_opt_pass (pass_data_ipa_auto_profile
, ctxt
)
1683 /* opt_pass methods: */
1687 return flag_auto_profile
;
1689 virtual unsigned int
1690 execute (function
*)
1692 return autofdo::auto_profile ();
1694 }; // class pass_ipa_auto_profile
1698 simple_ipa_opt_pass
*
1699 make_pass_ipa_auto_profile (gcc::context
*ctxt
)
1701 return new pass_ipa_auto_profile (ctxt
);