From 8b1838162ec03a81c841f4127cfd20b9b398c97e Mon Sep 17 00:00:00 2001 From: rfwang07 Date: Sat, 15 Jun 2024 17:31:11 +0800 Subject: [PATCH] Sync patch from openeuler/gcc --- 0199-Support-LTO-in-AutoBOLT-mode.patch | 421 ++++++++++++++++++++++++ gcc.spec | 10 +- 2 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 0199-Support-LTO-in-AutoBOLT-mode.patch diff --git a/0199-Support-LTO-in-AutoBOLT-mode.patch b/0199-Support-LTO-in-AutoBOLT-mode.patch new file mode 100644 index 0000000..6e588cd --- /dev/null +++ b/0199-Support-LTO-in-AutoBOLT-mode.patch @@ -0,0 +1,421 @@ +From 46ee0d6975bbea6246b83db08aa105c93d5fe3ef Mon Sep 17 00:00:00 2001 +From: rfwang07 +Date: Sat, 15 Jun 2024 12:59:51 +0800 +Subject: [PATCH] Support LTO in AutoBOLT mode + +--- + bolt-plugin/bolt-plugin.cc | 35 +++++-- + gcc/common.opt | 4 +- + gcc/final.c | 191 ++++++++++++++++++++++++++++++++----- + gcc/opts.c | 7 +- + 4 files changed, 196 insertions(+), 41 deletions(-) + +diff --git a/bolt-plugin/bolt-plugin.cc b/bolt-plugin/bolt-plugin.cc +index f357b00dd..06cf1911a 100644 +--- a/bolt-plugin/bolt-plugin.cc ++++ b/bolt-plugin/bolt-plugin.cc +@@ -269,6 +269,8 @@ static string tmp_out_file_name = "a.out"; + /* Binary or dynamic file after BOLT. */ + static string bolt_opt_target; + ++static bool autobolt_with_lto = false; ++ + /* Format of bolt_optimize_options should be "reorder-functions=hfsort+ ...", + command 'llvm-bolt' has been added here. */ + static string bolt_optimize_options ("llvm-bolt "); +@@ -450,9 +452,9 @@ cleanup_handler () + fclose (bolt_file_fd); + } + +- if (file_exist (tmp_out_file_name.c_str ()) +- && file_exist (bolt_profile_name.c_str ()) +- && is_bolt_opt_target ()) ++ if (is_bolt_opt_target () ++ && file_exist (tmp_out_file_name.c_str ()) ++ && file_exist (bolt_profile_name.c_str ())) + { + do_bolt_opt (); + } +@@ -552,6 +554,10 @@ dump_func_to_bolt_profile_file (const struct func_info &func) + static enum ld_plugin_status + all_symbols_read_handler () + { ++ if (autobolt_with_lto) ++ { ++ return LDPS_OK; ++ } + for (const auto &functions: weak_functions) + { + /* More than one weak function. */ +@@ -748,7 +754,10 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed) + } + /* BOLT plugin does not need claimd number, so set *claimed to 0. */ + *claimed = 0; +- ++ if (autobolt_with_lto) ++ { ++ return LDPS_OK; ++ } + obj.file = file; + obj.objfile = simple_object_start_read (file->fd, file->offset, NULL, + &errmsg, &err); +@@ -823,9 +832,12 @@ generate_bolt_profile_name (string file_name) + { + if (!bolt_dir_path.empty ()) + { +- file_name = concat (get_current_dir_name (), +- separator, file_name.c_str (), NULL); +- file_name = mangle_path (file_name); ++ if (!autobolt_with_lto) ++ { ++ file_name = concat (get_current_dir_name (), ++ separator, file_name.c_str (), NULL); ++ file_name = mangle_path (file_name); ++ } + } + else + { +@@ -1019,7 +1031,10 @@ process_output_option (const string &flag_o) + /* bolt_profile_name may be overridden in + function process_auto_bolt_option and + process_bolt_use_option. */ +- bolt_profile_name = gcc_options[o_index + 1]; ++ if (autobolt_with_lto && bolt_opt_target.empty ()) ++ bolt_profile_name = "default"; ++ else ++ bolt_profile_name = gcc_options[o_index + 1]; + bolt_profile_name.append (DEFAULT_BOLT_OUT_NAME_SUFFIX); + } + else +@@ -1047,13 +1062,15 @@ process_gcc_option () + char *collect_gcc_option = getenv ("COLLECT_GCC_OPTIONS"); + + get_options_from_collect_gcc_options (collect_gcc, collect_gcc_option); ++ autobolt_with_lto = (match_gcc_option (flag_auto_bolt.c_str ()) != -1 ++ && match_gcc_option ("-flto") != -1); + ++ process_bolt_target_option (flag_bolt_target); + /* Function process_output_option should be processed before + process_auto_bolt_option to obtain correct bolt_profile_name. */ + process_output_option (flag_o); + process_auto_bolt_option (flag_auto_bolt); + process_bolt_use_option (flag_bolt_use); +- process_bolt_target_option (flag_bolt_target); + process_bolt_option (flag_bolt_optimize_options); + + if (match_gcc_option (flag_profile_use.c_str ()) != -1) +diff --git a/gcc/common.opt b/gcc/common.opt +index ea55355be..aad6fb281 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -2482,7 +2482,7 @@ Common Report Var(flag_auto_bolt) + Generate profile from AutoFDO or PGO and do BOLT optimization after linkage. + + fauto-bolt= +-Common Joined RejectNegative ++Common Joined RejectNegative Var(auto_bolt) + Specify the feedback data directory required by BOLT-plugin. The default is the current directory. + + fbolt-use +@@ -2494,7 +2494,7 @@ Common Joined RejectNegative Var + Do BOLT optimization after linkage with BOLT profile read from this option. + + fbolt-target= +-Common Joined RejectNegative Var ++Common Joined RejectNegative Var(bolt_target) + Specify the BOLT optimization target binary. + + fbolt-option= +diff --git a/gcc/final.c b/gcc/final.c +index da8d20958..807384514 100644 +--- a/gcc/final.c ++++ b/gcc/final.c +@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3. If not see + #include "print-rtl.h" + #include "function-abi.h" + #include "insn-codes.h" ++#include + + #ifdef XCOFF_DEBUGGING_INFO + #include "xcoffout.h" /* Needed for external data declarations. */ +@@ -4650,6 +4651,10 @@ leaf_renumber_regs_insn (rtx in_rtx) + + #define ASM_FDO_CALLEE_FLAG ".fdo.callee " + ++static bool autobolt_with_lto = false; ++static char *autobolt_curr_func_name; ++static FILE *bolt_file_fd = NULL; ++ + /* Return the relative offset address of the start instruction of BB, + return -1 if it is empty instruction. */ + +@@ -4785,6 +4790,16 @@ alias_local_functions (const char *fnname) + return concat (fnname, "/", lbasename (dump_base_name), NULL); + } + ++static char* ++add_suffix (const char *str) ++{ ++ if (strlen (str) == 0 || strstr (str, "/") == NULL) ++ { ++ return xstrdup (str); ++ } ++ return concat (str, "/1", NULL); ++} ++ + /* Return function bind type string. */ + + static const char * +@@ -4830,19 +4845,33 @@ dump_direct_callee_info_to_asm (basic_block bb, gcov_type call_count) + + if (callee) + { +- char *func_name = +- alias_local_functions (get_fnname_from_decl (callee)); +- fprintf (asm_out_file, "\t.string \"%x\"\n", +- INSN_ADDRESSES (INSN_UID (insn))); +- +- fprintf (asm_out_file, "\t.string \"%s%s\"\n", +- ASM_FDO_CALLEE_FLAG, +- func_name); +- +- fprintf (asm_out_file, +- "\t.string \"" HOST_WIDE_INT_PRINT_DEC "\"\n", +- call_count); +- ++ char *func_name; ++ if (!autobolt_with_lto) ++ { ++ func_name = alias_local_functions ( ++ get_fnname_from_decl (callee)); ++ fprintf (asm_out_file, "\t.string \"%x\"\n", ++ INSN_ADDRESSES (INSN_UID (insn))); ++ ++ fprintf (asm_out_file, "\t.string \"%s%s\"\n", ++ ASM_FDO_CALLEE_FLAG, ++ func_name); ++ ++ fprintf (asm_out_file, ++ "\t.string \"" HOST_WIDE_INT_PRINT_DEC "\"\n", ++ call_count); ++ } ++ else ++ { ++ func_name = xstrdup ( ++ get_fnname_from_decl (callee)); ++ fprintf (bolt_file_fd, ++ "1 %s %x 1 %s 0 0 " HOST_WIDE_INT_PRINT_DEC "\n", ++ autobolt_curr_func_name, ++ INSN_ADDRESSES (INSN_UID (insn)), ++ func_name, ++ call_count); ++ } + if (dump_file) + { + fprintf (dump_file, "call: %x --> %s\n", +@@ -4880,7 +4909,10 @@ dump_edge_jump_info_to_asm (basic_block bb, gcov_type bb_count) + /* This is a reserved assert for the original design. If this + assert is found, use the address of the previous instruction + as edge_start_addr. */ +- gcc_assert (edge_start_addr != edge_end_addr); ++ if (edge_start_addr == edge_end_addr) ++ { ++ continue; ++ } + + if (dump_file) + { +@@ -4890,10 +4922,24 @@ dump_edge_jump_info_to_asm (basic_block bb, gcov_type bb_count) + + if (edge_count > 0) + { +- fprintf (asm_out_file, "\t.string \"%x\"\n", edge_start_addr); +- fprintf (asm_out_file, "\t.string \"%x\"\n", edge_end_addr); +- fprintf (asm_out_file, "\t.string \"" HOST_WIDE_INT_PRINT_DEC "\"\n", +- edge_count); ++ if (!autobolt_with_lto) ++ { ++ fprintf (asm_out_file, "\t.string \"%x\"\n", edge_start_addr); ++ fprintf (asm_out_file, "\t.string \"%x\"\n", edge_end_addr); ++ fprintf (asm_out_file, ++ "\t.string \"" HOST_WIDE_INT_PRINT_DEC "\"\n", ++ edge_count); ++ } ++ else ++ { ++ fprintf (bolt_file_fd, ++ "1 %s %x 1 %s %x 0 " HOST_WIDE_INT_PRINT_DEC "\n", ++ autobolt_curr_func_name, ++ edge_start_addr, ++ autobolt_curr_func_name, ++ edge_end_addr, ++ edge_count); ++ } + } + } + +@@ -4924,12 +4970,17 @@ static void + dump_function_info_to_asm (const char *fnname) + { + char *func_name = alias_local_functions (fnname); +- fprintf (asm_out_file, "\t.string \"%s%s\"\n", +- ASM_FDO_CALLER_FLAG, func_name); +- fprintf (asm_out_file, "\t.string \"%s%d\"\n", +- ASM_FDO_CALLER_SIZE_FLAG, get_function_end_addr ()); +- fprintf (asm_out_file, "\t.string \"%s%s\"\n", +- ASM_FDO_CALLER_BIND_FLAG, simple_get_function_bind ()); ++ if (!autobolt_with_lto) ++ { ++ fprintf (asm_out_file, "\t.string \"%s%s\"\n", ++ ASM_FDO_CALLER_FLAG, func_name); ++ fprintf (asm_out_file, "\t.string \"%s%d\"\n", ++ ASM_FDO_CALLER_SIZE_FLAG, ++ get_function_end_addr ()); ++ fprintf (asm_out_file, "\t.string \"%s%s\"\n", ++ ASM_FDO_CALLER_BIND_FLAG, ++ simple_get_function_bind ()); ++ } + + if (dump_file) + { +@@ -5041,6 +5092,90 @@ dump_profile_to_elf_sections () + } + } + ++#define DEFAULT_BOLT_OUT_NAME "default.fdata" ++static char *bolt_profile_name = DEFAULT_BOLT_OUT_NAME; ++static void ++open_bolt_profile_file () ++{ ++ char *file_path; ++ ++ if (auto_bolt && strlen (auto_bolt) != 0) ++ file_path = lrealpath (auto_bolt); ++ else ++ file_path = lrealpath (dump_dir_name); ++ if (bolt_target && strlen (bolt_target) != 0) ++ bolt_profile_name = concat ( ++ file_path, "/", lbasename (bolt_target), ".fdata", NULL); ++ else ++ bolt_profile_name = concat ( ++ file_path, "/", DEFAULT_BOLT_OUT_NAME, NULL); ++ free (file_path); ++ ++ if (bolt_file_fd == NULL) ++ { ++ bolt_file_fd = fopen (bolt_profile_name, "at"); ++ if (!bolt_file_fd) ++ { ++ error ("Failed to open the file: %s." ++ " Please check whether the target path exists.", ++ bolt_profile_name); ++ } ++ if (flock (fileno (bolt_file_fd), LOCK_EX) == -1) ++ { ++ error ("Failed to lock the file: %s.", ++ bolt_profile_name); ++ } ++ } ++ free (bolt_profile_name); ++} ++ ++inline static bool ++is_bolt_opt_target () ++{ ++ bool is_target = true; ++ if (bolt_target && strlen (bolt_target) != 0) ++ { ++ char *target_name = concat (lbasename (bolt_target), ++ ".ltrans", NULL); ++ if (strncmp (target_name, ++ lbasename (dump_base_name), ++ strlen (target_name)) != 0) ++ { ++ is_target = false; ++ } ++ free (target_name); ++ } ++ return is_target; ++} ++ ++static void ++dump_profile_to_bolt_file () ++{ ++ /* Avoid empty functions. */ ++ if (TREE_CODE (cfun->decl) != FUNCTION_DECL) ++ { ++ return; ++ } ++ ++ if (!is_bolt_opt_target ()) ++ { ++ return; ++ } ++ ++ open_bolt_profile_file (); ++ const char *fnname = get_fnname_from_decl (current_function_decl); ++ autobolt_curr_func_name = add_suffix (fnname); ++ dump_fdo_info_to_asm (fnname); ++ free (autobolt_curr_func_name); ++ fflush (bolt_file_fd); ++ if (flock (fileno (bolt_file_fd), LOCK_UN) == -1) ++ { ++ error ("Failed to unlock the file: %s.", bolt_profile_name); ++ } ++ fclose (bolt_file_fd); ++ bolt_file_fd = NULL; ++} ++ + /* Turn the RTL into assembly. */ + static unsigned int + rest_of_handle_final (void) +@@ -5111,7 +5246,13 @@ rest_of_handle_final (void) + + if (flag_auto_bolt) + { +- dump_profile_to_elf_sections (); ++ if (flag_ltrans) ++ { ++ autobolt_with_lto = true; ++ dump_profile_to_bolt_file (); ++ } ++ else ++ dump_profile_to_elf_sections (); + } + + return 0; +diff --git a/gcc/opts.c b/gcc/opts.c +index 30ac57eec..c0ccd0853 100644 +--- a/gcc/opts.c ++++ b/gcc/opts.c +@@ -1166,10 +1166,6 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, + if (opts->x_flag_vtable_verify && opts->x_flag_lto) + sorry ("vtable verification is not supported with LTO"); + +- /* Currently -fauto-bolt is not supported for LTO. */ +- if (opts->x_flag_auto_bolt && opts->x_flag_lto) +- sorry ("%<-fauto-bolt%> is not supported with LTO"); +- + /* Currently -fbolt-use is not supported for LTO. */ + if (opts->x_flag_bolt_use && opts->x_flag_lto) + sorry ("-fbolt-use is not supported with LTO"); +@@ -2970,6 +2966,7 @@ common_handle_option (struct gcc_options *opts, + + case OPT_fauto_bolt_: + opts->x_flag_auto_bolt = true; ++ opts->x_auto_bolt = xstrdup (arg); + /* FALLTHRU */ + case OPT_fauto_bolt: + if (opts->x_flag_bolt_use) +@@ -2985,7 +2982,7 @@ common_handle_option (struct gcc_options *opts, + break; + + case OPT_fbolt_target_: +- /* Deferred. */ ++ opts->x_bolt_target = xstrdup (arg); + break; + + case OPT_fbolt_option_: +-- +2.33.0 + diff --git a/gcc.spec b/gcc.spec index d794101..bec92ec 100644 --- a/gcc.spec +++ b/gcc.spec @@ -61,7 +61,7 @@ Summary: Various compilers (C, C++, Objective-C, ...) Name: gcc Version: %{gcc_version} -Release: 58 +Release: 59 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD URL: https://gcc.gnu.org @@ -306,6 +306,7 @@ Patch195: 0195-add-whitelist-feature-for-OneProfile.patch Patch196: 0196-fix-bugs-in-loop-detections-add-filter-to-SSA-statem.patch Patch197: 0197-Add-hip09-machine-discribtion.patch Patch198: 0198-bugfix-Modify-the-hip09-CPU-information.patch +Patch199: 0199-Support-LTO-in-AutoBOLT-mode.patch %global gcc_target_platform %{_arch}-linux-gnu %if %{build_go} @@ -956,6 +957,7 @@ not stable, so plugins must be rebuilt any time GCC is updated. %patch196 -p1 %patch197 -p1 %patch198 -p1 +%patch199 -p1 %build @@ -2990,6 +2992,12 @@ end %doc rpm.doc/changelogs/libcc1/ChangeLog* %changelog +* Sat Jun 15 2024 rfwang07 - 10.3.1-59 +- Type:Sync +- ID:NA +- SUG:NA +- DESC: Sync patch from openeuler/gcc + * Fri Jun 14 2024 zhenyu zhao - 10.3.1-58 - Type:Sync - ID:NA -- Gitee