work is still in progress.
todo: - ensure that all affected sources (i.e. C sources with any kind of assembly) are listed in either way for all architectures - test Wine built with LTO
relevant bug reports: - https://bugs.winehq.org/show_bug.cgi?id=41712 - https://bugs.winehq.org/show_bug.cgi?id=51051
-- v5: LTO quirks makedep: support skipping/disabling LTO configure: enable building Wine with LTO makedep: support LTO builds winegcc: support LTO builds winebuild: support LTO builds tools: helper functions for LTO builds
From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- tools/lto.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 tools/lto.h
diff --git a/tools/lto.h b/tools/lto.h new file mode 100644 index 00000000000..ef4e9f65b8c --- /dev/null +++ b/tools/lto.h @@ -0,0 +1,132 @@ +/* + * LTO helper functions for the Wine tools + * + * Copyright 2025 Konstantin Demin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_LTO_H +#define __WINE_LTO_H + +#ifndef __WINE_TOOLS_H +# error You must include tools.h to use this header +#endif + + +__attribute__((used)) +static void append_lto_flags( struct strarray *args, int with_lto, int prefer_env ) +{ + if (with_lto < 0) return; + + while (prefer_env > 0) + { + const char *flags; + + if (with_lto > 0) + { + static int init_lto = 0; + static const char* flags_lto; + + if (!init_lto) + { + flags_lto = getenv( "WINE_LTO_FLAGS" ); + if (flags_lto) flags_lto = xstrdup( flags_lto ); + init_lto = 1; + } + flags = flags_lto; + } + else + { + static int init_lto_skip = 0; + static const char* flags_lto_skip; + + if (!init_lto_skip) + { + flags_lto_skip = getenv( "WINE_LTO_SKIP_FLAGS" ); + if (flags_lto_skip) flags_lto_skip = xstrdup( flags_lto_skip ); + init_lto_skip = 1; + } + flags = flags_lto_skip; + } + + if (!flags) break; + + strarray_addall( args, strarray_fromstring( flags, " " ) ); + return; + } + + strarray_add( args, (with_lto > 0) ? "-flto" : "-fno-lto" ); +} + + +static int var_to_bool( const char *var ) +{ + if (!var) return 0; + if (!( var[0] )) return 0; + + switch (var[0]) + { + /* "1" */ + case '1': + if (!var[1]) return 1; + break; + + /* "[Tt]", "[Tt][Rr][Uu][Ee]" */ + case 'T': /* -fallthrough */ + case 't': + if (!var[1]) return 1; + + if (strlen( var ) != 4) break; + if ((var[1] != 'R') && (var[1] != 'r')) break; + if ((var[2] != 'U') && (var[2] != 'u')) break; + if ((var[3] != 'E') && (var[3] != 'e')) break; + return 1; + + break; + + /* "[Yy]", "[Yy][Ee][Ss]" */ + case 'Y': /* -fallthrough */ + case 'y': + if (!var[1]) return 1; + + if (strlen( var ) != 3) break; + if ((var[1] != 'E') && (var[1] != 'e')) break; + if ((var[2] != 'S') && (var[2] != 's')) break; + return 1; + + break; + } + + return 0; +} + + +__attribute__((used)) +static int adjust_verbose_lto( int with_lto, int verbose ) +{ + const char* lto_debug; + + if (with_lto < 1) return verbose; + if (verbose > 0) return verbose; + + lto_debug = getenv( "WINE_LTO_DEBUG" ); + if (!lto_debug) return verbose; + + return var_to_bool( lto_debug ); +} + + +#endif /* __WINE_LTO_H */
From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- tools/winebuild/build.h | 2 ++ tools/winebuild/import.c | 55 +++++++++++++++++++++++++++++++++++++--- tools/winebuild/main.c | 6 ++++- tools/winebuild/utils.c | 31 ++++++++++++++++++++-- 4 files changed, 88 insertions(+), 6 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index e5ede93425b..e329ce4a9cc 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -26,6 +26,7 @@ #include <stdio.h> #include <stdlib.h> #include "../tools.h" +#include "../lto.h"
typedef enum { @@ -363,6 +364,7 @@ extern void put_pword( unsigned int val );
extern int current_line; extern int UsePIC; +extern int UseLTO; extern int nb_errors; extern int display_warnings; extern int kill_at; diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index eba74bb9660..8252245732f 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1241,11 +1241,35 @@ static const char *get_target_machine(void) /* build a library from the current asm files and any additional object files in argv */ void output_static_lib( const char *output_name, struct strarray files, int create ) { - struct strarray args; + struct strarray args = empty_strarray;
if (!create || target.platform != PLATFORM_WINDOWS) { - args = find_tool( "ar", NULL ); + while (UseLTO > 0) + { + static int init_env_ar = 0; + static const char * env_ar; + const char * _cmd[2] = { 0 }; + + if (!init_env_ar) + { + if ((env_ar = getenv( "WINE_AR" ))) + { + /* duplicate string if non-empty; otherwise set to NULL */ + env_ar = (env_ar[0]) ? xstrdup( env_ar ) : NULL; + } + init_env_ar = 1; + } + if (!env_ar) break; + + _cmd[0] = env_ar; + args = find_tool( "ar", _cmd ); + break; + } + if (!args.count) + { + args = find_tool( "ar", NULL ); + } strarray_add( &args, create ? "rc" : "r" ); strarray_add( &args, output_name ); } @@ -1263,7 +1287,32 @@ void output_static_lib( const char *output_name, struct strarray files, int crea
if (target.platform != PLATFORM_WINDOWS) { - struct strarray ranlib = find_tool( "ranlib", NULL ); + struct strarray ranlib = empty_strarray; + while (UseLTO > 0) + { + static int init_env_ranlib = 0; + static const char * env_ranlib; + const char * _cmd[2] = { 0 }; + + if (!init_env_ranlib) + { + if ((env_ranlib = getenv( "WINE_RANLIB" ))) + { + /* duplicate string if non-empty; otherwise set to NULL */ + env_ranlib = (env_ranlib[0]) ? xstrdup( env_ranlib ) : NULL; + } + init_env_ranlib = 1; + } + if (!env_ranlib) break; + + _cmd[0] = env_ranlib; + args = find_tool( "ranlib", _cmd ); + break; + } + if (!ranlib.count) + { + ranlib = find_tool( "ranlib", NULL ); + } strarray_add( &ranlib, output_name ); spawn( ranlib ); } diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 63d65e7bcd0..e48c5afb194 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -34,6 +34,7 @@ #include "build.h"
int UsePIC = 0; +int UseLTO = -1; int nb_errors = 0; int display_warnings = 0; int native_arch = -1; @@ -185,7 +186,7 @@ static const char usage_str[] = " -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n" " -E, --export=FILE Export the symbols defined in the .spec or .def file\n" " --external-symbols Allow linking to external symbols\n" -" -f FLAGS Compiler flags (-fPIC and -fasynchronous-unwind-tables are supported)\n" +" -f FLAGS Compiler flags (-fPIC, -fasynchronous-unwind-tables and -flto are supported)\n" " -F, --filename=DLLFILE Set the DLL filename (default: from input file name)\n" " --fake-module Create a fake binary module\n" " -h, --help Display this help message\n" @@ -405,6 +406,8 @@ static void option_callback( int optc, char *optarg ) if (!strcmp( optarg, "PIC") || !strcmp( optarg, "pic")) UsePIC = 1; else if (!strcmp( optarg, "asynchronous-unwind-tables")) unwind_tables = 1; else if (!strcmp( optarg, "no-asynchronous-unwind-tables")) unwind_tables = 0; + else if (!strcmp( optarg, "lto" )) UseLTO = 1; + else if (!strcmp( optarg, "no-lto" )) UseLTO = 0; /* ignore all other flags */ break; case 'h': @@ -569,6 +572,7 @@ int main(int argc, char **argv) if (is_pe()) unwind_tables = 1;
files = parse_options( argc, argv, short_options, long_options, 0, option_callback ); + verbose = adjust_verbose_lto( UseLTO, verbose );
atexit( cleanup ); /* make sure we remove the output file on exit */
diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c index 05595f86d37..25b96dddd20 100644 --- a/tools/winebuild/utils.c +++ b/tools/winebuild/utils.c @@ -303,6 +303,8 @@ struct strarray get_as_command(void)
if (using_cc) { + /* disable LTO for assembly */ + append_lto_flags( &args, (UseLTO >= 0) ? 0 : -1, 1 /* prefer flags from env */ ); strarray_add( &args, "-xassembler" ); strarray_add( &args, "-c" ); if (force_pointer_size) @@ -345,6 +347,7 @@ struct strarray get_ld_command(void) }
strarray_addall( &args, ld_command ); + append_lto_flags( &args, UseLTO, 1 /* prefer flags from env */ );
if (force_pointer_size) { @@ -380,8 +383,32 @@ const char *get_nm_command(void) { if (!nm_command.count) { - static const char * const commands[] = { "nm", "gnm", NULL }; - nm_command = find_tool( "nm", commands ); + while (UseLTO > 0) + { + static int init_env_nm = 0; + static const char * env_nm; + const char * _cmd[2] = { 0 }; + + if (!init_env_nm) + { + if ((env_nm = getenv( "WINE_NM" ))) + { + /* duplicate string if non-empty; otherwise set to NULL */ + env_nm = (env_nm[0]) ? xstrdup( env_nm ) : NULL; + } + init_env_nm = 1; + } + if (!env_nm) break; + + _cmd[0] = env_nm; + nm_command = find_tool( "nm", _cmd ); + break; + } + if (!nm_command.count) + { + static const char * const commands[] = { "nm", "gnm", NULL }; + nm_command = find_tool( "nm", commands ); + } } if (nm_command.count > 1) fatal_error( "multiple arguments in nm command not supported yet\n" );
From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- tools/winegcc/utils.h | 1 + tools/winegcc/winegcc.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/tools/winegcc/utils.h b/tools/winegcc/utils.h index 05b29b426cf..b3908f28883 100644 --- a/tools/winegcc/utils.h +++ b/tools/winegcc/utils.h @@ -21,6 +21,7 @@ */
#include "../tools.h" +#include "../lto.h"
#ifndef DECLSPEC_NORETURN # if defined(_MSC_VER) && (_MSC_VER >= 1200) && !defined(MIDL_PASS) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 600bd171b89..978b3f2b4a7 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -177,6 +177,7 @@ struct options int unwind_tables; int strip; int pic; + int lto; int no_default_config; int build_id; const char* wine_objdir; @@ -364,6 +365,7 @@ static struct strarray get_link_args( struct options *opts, const char *output_n struct strarray flags = empty_strarray;
strarray_addall( &link_args, opts->linker_args ); + append_lto_flags( &link_args, opts->lto, 1 /* prefer flags from env */ );
if (verbose > 1) strarray_add( &flags, "-v" );
@@ -653,6 +655,11 @@ static void compile(struct options* opts, const char* lang) break; }
+ if ((opts->processor == proc_cc) || (opts->processor == proc_cxx)) + { + append_lto_flags( &comp_args, opts->lto, 1 /* prefer flags from env */ ); + } + if (opts->target.platform == PLATFORM_WINDOWS || opts->target.platform == PLATFORM_CYGWIN || opts->target.platform == PLATFORM_MINGW) @@ -835,6 +842,7 @@ static struct strarray get_winebuild_args( struct options *opts, const char *tar strarray_add( &spec_args, binary ); if (verbose) strarray_add( &spec_args, "-v" ); if (keep_generated) strarray_add( &spec_args, "--save-temps" ); + append_lto_flags( &spec_args, opts->lto, 0 /* generic LTO flags */ ); if (target) { strarray_add( &spec_args, "--target" ); @@ -1507,6 +1515,7 @@ int main(int argc, char **argv) memset(&opts, 0, sizeof(opts)); opts.target = init_argv0_target( argv[0] ); opts.pic = 1; + opts.lto = -1;
/* determine the processor type */ if (strendswith(argv[0], "winecpp")) opts.processor = proc_cpp; @@ -1658,6 +1667,10 @@ int main(int argc, char **argv) opts.pic = 1; else if (!strcmp("-fno-PIC", opts.args.str[i]) || !strcmp("-fno-pic", opts.args.str[i])) opts.pic = 0; + else if (!strcmp( "-flto", opts.args.str[i] )) + opts.lto = 1; + else if (!strcmp( "-fno-lto", opts.args.str[i] )) + opts.lto = 0; break; case 'i': if (!strcmp( "-isysroot", opts.args.str[i] )) opts.isysroot = opts.args.str[i + 1]; @@ -1947,6 +1960,7 @@ int main(int argc, char **argv) strarray_add( &opts.files, opts.args.str[i] ); } } + verbose = adjust_verbose_lto( opts.lto, verbose );
if (opts.force_pointer_size) set_target_ptr_size( &opts.target, opts.force_pointer_size ); if (opts.processor == proc_cpp) linking = 0;
From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- tools/makedep.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
diff --git a/tools/makedep.c b/tools/makedep.c index 3fe2d254fdf..05360bdda91 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -32,6 +32,7 @@ #include <sys/stat.h>
#include "tools.h" +#include "lto.h" #include "wine/list.h"
enum incl_type @@ -245,6 +246,7 @@ static const char *temp_file_name; static char cwd[PATH_MAX]; static int compile_commands_mode; static int silent_rules; +static int with_lto = 0; static int input_line; static int output_column; static FILE *output_file; @@ -273,6 +275,10 @@ static void fatal_perror( const char *msg, ... ) __attribute__ ((__format__ (__p static void output( const char *format, ... ) __attribute__ ((__format__ (__printf__, 1, 2))); static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
+static void output_lto_flags_source( struct makefile *make, struct incl_file *source, unsigned int arch, + int prefer_env ); +static void output_lto_flags_target( struct makefile *make, unsigned int arch, int prefer_env ); + /******************************************************************* * fatal_error */ @@ -2478,6 +2484,7 @@ static void output_winegcc_command( struct makefile *make, unsigned int arch ) output_filename( "--winebuild" ); output_filename( tools_path( make, "winebuild" )); } + output_lto_flags_target( make, arch, 0 /* generic LTO flags */ ); output_filenames( target_flags[arch] ); if (native_archs[arch] && !make->disabled[native_archs[arch]]) output_filenames( hybrid_target_flags[arch] ); @@ -3299,6 +3306,7 @@ static void output_source_one_arch( struct makefile *make, struct incl_file *sou output_filenames( defines ); output_filenames( cflags ); output_filename( var_cflags ); + output_lto_flags_source( make, source, arch, 1 /* prefer flags from env */ ); output( "\n" );
if (make->testdll && strendswith( source->name, ".c" ) && @@ -3573,6 +3581,7 @@ static void output_import_lib( struct makefile *make, unsigned int arch ) if (hybrid_arch) output_filenames_obj_dir( make, make->implib_files[hybrid_arch] ); output( "\n" ); output( "\t%s%s -w --implib -o $@", cmd_prefix( "BUILD" ), tools_path( make, "winebuild" ) ); + output_lto_flags_target( make, arch, 0 /* generic LTO flags */ ); if (!delay_load_flags[arch]) output_filename( "--without-dlltool" ); output_filenames( target_flags[hybrid_arch ? hybrid_arch : arch] ); if (make->is_win16) output_filename( "-m16" ); @@ -3608,6 +3617,7 @@ static void output_unix_lib( struct makefile *make ) output( "\n" ); output( "\t%s$(CC) -o $@", cmd_prefix( "CCLD" )); output_filenames( get_expanded_make_var_array( make, "UNIXLDFLAGS" )); + output_lto_flags_target( make, arch, 1 /* prefer flags from env */ ); output_filenames_obj_dir( make, make->unixobj_files ); output_filenames( unix_libs ); output_filename( "$(LDFLAGS)" ); @@ -3634,6 +3644,7 @@ static void output_static_lib( struct makefile *make, unsigned int arch ) output( "\n" ); output( "\t%s%s -w --staticlib -o $@", cmd_prefix( "BUILD" ), tools_path( make, "winebuild" )); output_filenames( target_flags[hybrid_arch ? hybrid_arch : arch] ); + output_lto_flags_target( make, arch, 0 /* generic LTO flags */ ); output_filenames_obj_dir( make, make->object_files[arch] ); if (hybrid_arch) output_filenames_obj_dir( make, make->object_files[hybrid_arch] ); if (!arch) output_filenames_obj_dir( make, make->unixobj_files ); @@ -3758,6 +3769,7 @@ static void output_programs( struct makefile *make ) output_filenames( deps ); output( "\n" ); output( "\t%s$(CC) -o $@", cmd_prefix( "CCLD" )); + output_lto_flags_target( make, arch, 1 /* prefer flags from env */ ); output_filenames_obj_dir( make, objs ); output_filenames( all_libs ); output_filename( "$(LDFLAGS)" ); @@ -4596,6 +4608,9 @@ static int parse_option( const char *opt ) case 'S': silent_rules = 1; break; + case 'L': + with_lto = 1; + break; default: fprintf( stderr, "Unknown option '%s'\n%s", opt, Usage ); exit(1); @@ -4615,6 +4630,47 @@ static unsigned int find_pe_arch( const char *arch ) }
+/******************************************************************* + * output_lto_flags + */ +static void output_lto_flags( int use_lto, int prefer_env ) +{ + struct strarray lto_flags = empty_strarray; + append_lto_flags( <o_flags, use_lto, prefer_env ); + output_filenames( lto_flags ); +} + + +/******************************************************************* + * output_lto_flags_source + */ +static void output_lto_flags_source( struct makefile *make, struct incl_file *source, unsigned int arch, + int prefer_env ) +{ + if (!with_lto) return; + if (!make) return; + if (!source) return; + + (void) arch; /* mark as used */ + + output_lto_flags( with_lto, prefer_env ); +} + + +/******************************************************************* + * output_lto_flags_target + */ +static void output_lto_flags_target( struct makefile *make, unsigned int arch, int prefer_env ) +{ + if (!with_lto) return; + if (!make) return; + + (void) arch; /* mark as used */ + + output_lto_flags( with_lto, prefer_env ); +} + + /******************************************************************* * main */
From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- configure | 19 +++++++++++++++++++ configure.ac | 12 ++++++++++++ 2 files changed, 31 insertions(+)
diff --git a/configure b/configure index 532b8d8a30e..83ed054686d 100755 --- a/configure +++ b/configure @@ -922,6 +922,7 @@ enable_maintainer_mode enable_sast enable_silent_rules enable_werror +enable_lto with_alsa with_capi with_coreaudio @@ -2521,6 +2522,7 @@ Optional Features: Clang --enable-silent-rules use silent build rules (override: "make V=1") --enable-werror treat compilation warnings as errors + --enable-lto build with LTO (EXPERIMENTAL) --disable-largefile omit support for large files --disable-year2038 don't support timestamps after 2038
@@ -4339,6 +4341,12 @@ then : enableval=$enable_werror; fi
+# Check whether --enable-lto was given. +if test ${enable_lto+y} +then : + enableval=$enable_lto; +fi +
# Check whether --with-alsa was given. @@ -10110,6 +10118,11 @@ do esac done
+if test "x$enable_lto" = xyes +then + as_fn_append EXTRACFLAGS " -D__WINE_LTO_BUILD" +fi + for wine_arch in $cross_archs $extra_arch do case "x$with_mingw" in @@ -10398,6 +10411,11 @@ fi eval LDFLAGS=$${wine_arch}_LDFLAGS eval "${wine_arch}_EXTRACFLAGS="-D__WINE_PE_BUILD -Wall""
+ if test "x$enable_lto" = xyes + then + as_fn_append ${wine_arch}_EXTRACFLAGS " -D__WINE_LTO_BUILD" + fi + target="" set x $CC shift @@ -22092,6 +22110,7 @@ printf %s "creating Makefile rules..." >&6
makedep_flags=" -C" test "x$enable_silent_rules" = xyes && makedep_flags="$makedep_flags -S" +test "x$enable_lto" = xyes && makedep_flags="$makedep_flags -L"
wine_srcdir= test "$srcdir" = . || wine_srcdir="$srcdir/" diff --git a/configure.ac b/configure.ac index cf698988a7b..4a03a47c010 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,7 @@ AC_ARG_ENABLE(maintainer-mode, AS_HELP_STRING([--enable-maintainer-mode],[enable AC_ARG_ENABLE(sast, AS_HELP_STRING([--enable-sast],[enable static application security testing using Clang])) AC_ARG_ENABLE(silent-rules, AS_HELP_STRING([--enable-silent-rules],[use silent build rules (override: "make V=1")])) AC_ARG_ENABLE(werror, AS_HELP_STRING([--enable-werror],[treat compilation warnings as errors])) +AC_ARG_ENABLE(lto, AS_HELP_STRING([--enable-lto],[build with LTO (EXPERIMENTAL)]))
AC_ARG_WITH(alsa, AS_HELP_STRING([--without-alsa],[do not use the Alsa sound support])) AC_ARG_WITH(capi, AS_HELP_STRING([--without-capi],[do not use CAPI (ISDN support)])) @@ -810,6 +811,11 @@ do esac done
+if test "x$enable_lto" = xyes +then + AS_VAR_APPEND([EXTRACFLAGS],[" -D__WINE_LTO_BUILD"]) +fi + for wine_arch in $cross_archs $extra_arch do case "x$with_mingw" in @@ -844,6 +850,11 @@ do AS_VAR_COPY([LDFLAGS],[${wine_arch}_LDFLAGS]) AS_VAR_SET([${wine_arch}_EXTRACFLAGS],["-D__WINE_PE_BUILD -Wall"])
+ if test "x$enable_lto" = xyes + then + AS_VAR_APPEND([${wine_arch}_EXTRACFLAGS],[" -D__WINE_LTO_BUILD"]) + fi + target="" set x $CC shift @@ -2386,6 +2397,7 @@ AS_ECHO_N("creating Makefile rules...") >&AS_MESSAGE_FD
makedep_flags=" -C" test "x$enable_silent_rules" = xyes && makedep_flags="$makedep_flags -S" +test "x$enable_lto" = xyes && makedep_flags="$makedep_flags -L"
wine_srcdir= test "$srcdir" = . || wine_srcdir="$srcdir/"
From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- tools/makedep.c | 126 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 6 deletions(-)
diff --git a/tools/makedep.c b/tools/makedep.c index 05360bdda91..3dfd8c69e2b 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -178,6 +178,7 @@ static struct strarray disabled_dirs[MAX_ARCHS]; static unsigned int native_archs[MAX_ARCHS]; static unsigned int hybrid_archs[MAX_ARCHS]; static struct strarray hybrid_target_flags[MAX_ARCHS]; +static struct strarray global_lto_skip[MAX_ARCHS];
struct makefile { @@ -210,6 +211,8 @@ struct makefile int is_win16; int is_exe; int disabled[MAX_ARCHS]; + int lto_skip[MAX_ARCHS]; + struct strarray lto_skip_src[MAX_ARCHS];
/* values generated at output time */ struct strarray in_files; @@ -4561,6 +4564,25 @@ static void load_sources( struct makefile *make )
for (i = 0; i < make->delayimports.count; i++) strarray_add_uniq( &delay_import_libs, get_base_name( make->delayimports.str[i] )); + + if (with_lto) + { + for (arch = 0; arch < archs.count; arch++) + { + const char * lto_skip; + + memset( &make->lto_skip_src[arch], 0, sizeof(struct strarray) ); + + lto_skip = get_expanded_arch_var( make, "LTO_SKIP", arch ); + make->lto_skip[arch] = var_to_bool( lto_skip ); + /* no need to parse source skiplist if target is marked as non-LTO */ + if (make->lto_skip[arch]) continue; + + value = get_expanded_arch_var_array( make, "LTO_SKIP_SRC", arch ); + for (i = 0; i < value.count; i++) + strarray_add( &make->lto_skip_src[arch], xstrdup( value.str[i] )); + } + } }
@@ -4641,19 +4663,109 @@ static void output_lto_flags( int use_lto, int prefer_env ) }
+/******************************************************************* + * parse_global_lto_skip_lists + */ +static void parse_global_lto_skip_lists( void ) +{ + unsigned int arch; + char *buffer; + FILE *file; + + for (arch = 0; arch < archs.count; arch++) + { + memset( &global_lto_skip[arch], 0, sizeof(struct strarray) ); + + if (arch) + input_file_name = root_src_dir_path(strmake( "tools/lto-skip.%s.list", archs.str[arch] )); + else + input_file_name = root_src_dir_path( "tools/lto-skip.list" ); + /* skip nonexistent files */ + if (!(file = fopen( input_file_name, "r" ))) + { + input_file_name = NULL; + continue; + } + input_line = 0; + + while ((buffer = get_line( file ))) + { + if (*buffer == '#') continue; /* comment */ + buffer = skip_spaces( buffer ); + strarray_add( &global_lto_skip[arch], xstrdup( buffer )); + } + (void) fclose( file ); + input_file_name = NULL; + input_line = 0; + } +} + + +/******************************************************************* + * is_lto_enabled_source + */ +static int is_lto_enabled_source( struct makefile *make, struct incl_file *source, unsigned int arch ) +{ + if (!with_lto) return 0; + if (!make) return 0; + if (!source) return 0; + + /* target config: any arch */ + if (strarray_exists( make->lto_skip_src[0], source->name )) + return 0; + + if (arch) + { + /* target config: specific arch */ + if (strarray_exists( make->lto_skip_src[arch], source->name )) + return 0; + + /* global config: specific arch */ + if (strarray_exists( global_lto_skip[arch], source->filename )) + return 0; + } + + /* global config: any arch */ + if (strarray_exists( global_lto_skip[0], source->filename )) + return 0; + + return 1; +} + + +/******************************************************************* + * is_lto_enabled_target + */ +static int is_lto_enabled_target( struct makefile *make, unsigned int arch ) +{ + if (!with_lto) return 0; + if (!make) return 0; + + /* any arch */ + if (make->lto_skip[0]) return 0; + + /* specific arch */ + if (arch && make->lto_skip[arch]) + return 0; + + return 1; +} + + /******************************************************************* * output_lto_flags_source */ static void output_lto_flags_source( struct makefile *make, struct incl_file *source, unsigned int arch, int prefer_env ) { + int use_lto = 0; + if (!with_lto) return; if (!make) return; if (!source) return;
- (void) arch; /* mark as used */ - - output_lto_flags( with_lto, prefer_env ); + use_lto = is_lto_enabled_target( make, arch ) && is_lto_enabled_source( make, source, arch ); + output_lto_flags( use_lto, prefer_env ); }
@@ -4662,12 +4774,13 @@ static void output_lto_flags_source( struct makefile *make, struct incl_file *so */ static void output_lto_flags_target( struct makefile *make, unsigned int arch, int prefer_env ) { + int use_lto = 0; + if (!with_lto) return; if (!make) return;
- (void) arch; /* mark as used */ - - output_lto_flags( with_lto, prefer_env ); + use_lto = is_lto_enabled_target( make, arch ); + output_lto_flags( use_lto, prefer_env ); }
@@ -4797,6 +4910,7 @@ int main( int argc, char *argv[] )
for (i = 0; i < subdirs.count; i++) submakes[i] = parse_makefile( subdirs.str[i] );
+ parse_global_lto_skip_lists(); load_sources( top_makefile ); load_sources( include_makefile ); for (i = 0; i < subdirs.count; i++)
From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- dlls/d3d8/Makefile.in | 3 +++ dlls/d3d9/Makefile.in | 3 +++ dlls/dbghelp/Makefile.in | 2 ++ dlls/ddraw/Makefile.in | 3 +++ dlls/hal/Makefile.in | 2 ++ dlls/hidclass.sys/Makefile.in | 2 ++ dlls/kernel32/Makefile.in | 4 ++++ dlls/kernelbase/Makefile.in | 5 +++++ dlls/krnl386.exe16/Makefile.in | 2 ++ dlls/mmsystem.dll16/Makefile.in | 2 ++ dlls/mshtml/Makefile.in | 3 +++ dlls/msi/Makefile.in | 2 ++ dlls/msvcirt/Makefile.in | 2 ++ dlls/msvcp60/Makefile.in | 2 ++ dlls/msvcp90/Makefile.in | 2 ++ dlls/ntoskrnl.exe/Makefile.in | 2 ++ dlls/ole32/Makefile.in | 2 ++ dlls/oleaut32/Makefile.in | 4 ++++ dlls/riched20/Makefile.in | 2 ++ dlls/rpcrt4/Makefile.in | 2 ++ dlls/system.drv16/Makefile.in | 2 ++ dlls/user32/Makefile.in | 2 ++ dlls/vcomp/Makefile.in | 4 ++++ dlls/win32u/Makefile.in | 4 ++++ dlls/win87em.dll16/Makefile.in | 2 ++ dlls/winebus.sys/Makefile.in | 2 ++ dlls/winecrt0/Makefile.in | 5 +++++ dlls/wineusb.sys/Makefile.in | 2 ++ dlls/winex11.drv/Makefile.in | 2 ++ dlls/winexinput.sys/Makefile.in | 2 ++ dlls/wow64/Makefile.in | 2 ++ dlls/wow64cpu/Makefile.in | 2 ++ dlls/xaudio2_7/Makefile.in | 2 ++ loader/Makefile.in | 2 ++ programs/rundll32/Makefile.in | 2 ++ programs/wineboot/Makefile.in | 3 +++ tools/lto-skip.i386.list | 11 +++++++++++ tools/lto-skip.list | 17 +++++++++++++++++ tools/lto-skip.x86_64.list | 3 +++ 39 files changed, 122 insertions(+) create mode 100644 tools/lto-skip.i386.list create mode 100644 tools/lto-skip.list create mode 100644 tools/lto-skip.x86_64.list
diff --git a/dlls/d3d8/Makefile.in b/dlls/d3d8/Makefile.in index 5a718b2d22d..1a2ec0c3357 100644 --- a/dlls/d3d8/Makefile.in +++ b/dlls/d3d8/Makefile.in @@ -14,3 +14,6 @@ SOURCES = \ version.rc \ vertexdeclaration.c \ volume.c + +i386_LTO_SKIP_SRC = device.c +x86_64_LTO_SKIP_SRC = device.c diff --git a/dlls/d3d9/Makefile.in b/dlls/d3d9/Makefile.in index 5a717b11863..d200933e3d1 100644 --- a/dlls/d3d9/Makefile.in +++ b/dlls/d3d9/Makefile.in @@ -16,3 +16,6 @@ SOURCES = \ version.rc \ vertexdeclaration.c \ volume.c + +i386_LTO_SKIP_SRC = device.c +x86_64_LTO_SKIP_SRC = device.c diff --git a/dlls/dbghelp/Makefile.in b/dlls/dbghelp/Makefile.in index 152ef80611a..1d3b1b163da 100644 --- a/dlls/dbghelp/Makefile.in +++ b/dlls/dbghelp/Makefile.in @@ -27,3 +27,5 @@ SOURCES = \ symbol.c \ type.c \ version.rc + +i386_LTO_SKIP_SRC = minidump.c diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in index e6d6dddddef..c919424f588 100644 --- a/dlls/ddraw/Makefile.in +++ b/dlls/ddraw/Makefile.in @@ -17,3 +17,6 @@ SOURCES = \ version.rc \ vertexbuffer.c \ viewport.c + +i386_LTO_SKIP_SRC = device.c +x86_64_LTO_SKIP_SRC = device.c diff --git a/dlls/hal/Makefile.in b/dlls/hal/Makefile.in index 7e9928f0e57..12ead12f877 100644 --- a/dlls/hal/Makefile.in +++ b/dlls/hal/Makefile.in @@ -5,3 +5,5 @@ IMPORTS = ntoskrnl SOURCES = \ hal.c \ version.rc + +i386_LTO_SKIP = yes diff --git a/dlls/hidclass.sys/Makefile.in b/dlls/hidclass.sys/Makefile.in index 57a8fd79297..5179cc13193 100644 --- a/dlls/hidclass.sys/Makefile.in +++ b/dlls/hidclass.sys/Makefile.in @@ -6,3 +6,5 @@ SOURCES = \ device.c \ hidclass.rc \ pnp.c + +i386_LTO_SKIP_SRC = pnp.c diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in index 66cd9916673..1244ebfd3ed 100644 --- a/dlls/kernel32/Makefile.in +++ b/dlls/kernel32/Makefile.in @@ -32,3 +32,7 @@ SOURCES = \ version.rc \ virtual.c \ volume.c + +i386_LTO_SKIP_SRC = process.c sync.c thread.c +x86_64_LTO_SKIP_SRC = module.c +arm64ec_LTO_SKIP_SRC = module.c diff --git a/dlls/kernelbase/Makefile.in b/dlls/kernelbase/Makefile.in index 2e33b6b5801..1a3512bee40 100644 --- a/dlls/kernelbase/Makefile.in +++ b/dlls/kernelbase/Makefile.in @@ -26,3 +26,8 @@ SOURCES = \ version.c \ volume.c \ winerror.mc + +LTO_SKIP_SRC = debug.c thread.c +i386_LTO_SKIP_SRC = sync.c +x86_64_LTO_SKIP_SRC = loader.c +arm64ec_LTO_SKIP_SRC = loader.c diff --git a/dlls/krnl386.exe16/Makefile.in b/dlls/krnl386.exe16/Makefile.in index 4251c83e158..38cf42bd9ce 100644 --- a/dlls/krnl386.exe16/Makefile.in +++ b/dlls/krnl386.exe16/Makefile.in @@ -35,3 +35,5 @@ SOURCES = \ version.rc \ vxd.c \ wowthunk.c + +LTO_SKIP_SRC = instr.c ne_module.c relay.c selector.c thunk.c wowthunk.c diff --git a/dlls/mmsystem.dll16/Makefile.in b/dlls/mmsystem.dll16/Makefile.in index 08334cb8f83..7638a7bbca7 100644 --- a/dlls/mmsystem.dll16/Makefile.in +++ b/dlls/mmsystem.dll16/Makefile.in @@ -9,3 +9,5 @@ SOURCES = \ message16.c \ mmio16.c \ mmsystem.c + +LTO_SKIP_SRC = mmsystem.c diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in index bc712a202c5..957c60b5190 100644 --- a/dlls/mshtml/Makefile.in +++ b/dlls/mshtml/Makefile.in @@ -67,3 +67,6 @@ SOURCES = \ xmlhttprequest.c
nsembed_EXTRADEFS = -DINSTALL_DATADIR=""${datadir}"" + +i386_LTO_SKIP_SRC = ifacewrap.c nsembed.c +x86_64_LTO_SKIP_SRC = ifacewrap.c diff --git a/dlls/msi/Makefile.in b/dlls/msi/Makefile.in index 21420909a92..1c5c0cc9627 100644 --- a/dlls/msi/Makefile.in +++ b/dlls/msi/Makefile.in @@ -49,3 +49,5 @@ SOURCES = \ upgrade.c \ where.c \ winemsi.idl + +i386_LTO_SKIP_SRC = custom.c diff --git a/dlls/msvcirt/Makefile.in b/dlls/msvcirt/Makefile.in index 4f60ea36b3e..c0483368e50 100644 --- a/dlls/msvcirt/Makefile.in +++ b/dlls/msvcirt/Makefile.in @@ -6,3 +6,5 @@ IMPORTS = msvcrt SOURCES = \ exception.c \ msvcirt.c + +i386_LTO_SKIP_SRC = msvcirt.c diff --git a/dlls/msvcp60/Makefile.in b/dlls/msvcp60/Makefile.in index d7beeb0f989..cb4b828dd84 100644 --- a/dlls/msvcp60/Makefile.in +++ b/dlls/msvcp60/Makefile.in @@ -14,3 +14,5 @@ SOURCES = \ memory.c \ misc.c \ string.c + +i386_LTO_SKIP_SRC = main.c diff --git a/dlls/msvcp90/Makefile.in b/dlls/msvcp90/Makefile.in index 5438b518260..63281c4739f 100644 --- a/dlls/msvcp90/Makefile.in +++ b/dlls/msvcp90/Makefile.in @@ -12,3 +12,5 @@ SOURCES = \ misc.c \ msvcp_main.c \ string.c + +i386_LTO_SKIP_SRC = exception.c msvcp_main.c diff --git a/dlls/ntoskrnl.exe/Makefile.in b/dlls/ntoskrnl.exe/Makefile.in index a04a75e7f52..b69f8d49528 100644 --- a/dlls/ntoskrnl.exe/Makefile.in +++ b/dlls/ntoskrnl.exe/Makefile.in @@ -10,3 +10,5 @@ SOURCES = \ plugplay.idl \ pnp.c \ sync.c + +LTO_SKIP_SRC = instr.c ntoskrnl.c diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index ee0fcc41f7d..0132d1f8e9f 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -44,3 +44,5 @@ SOURCES = \ usrmarshal.c
dlldata_EXTRADEFS = -DENTRY_PREFIX=OLE32_ -DPROXY_CLSID=CLSID_PSFactoryBuffer -DWINE_REGISTER_DLL + +i386_LTO_SKIP_SRC = stg_prop.c diff --git a/dlls/oleaut32/Makefile.in b/dlls/oleaut32/Makefile.in index 1e85c4bd299..badaa07b559 100644 --- a/dlls/oleaut32/Makefile.in +++ b/dlls/oleaut32/Makefile.in @@ -25,3 +25,7 @@ SOURCES = \ vartype.c
dlldata_EXTRADEFS = -DENTRY_PREFIX=OLEAUTPS_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL -DPROXY_CLSID=CLSID_PSFactoryBuffer + +LTO_SKIP_SRC = thunks.c +i386_LTO_SKIP_SRC = vartype.c +x86_64_LTO_SKIP_SRC = vartype.c diff --git a/dlls/riched20/Makefile.in b/dlls/riched20/Makefile.in index cd9d5ff63b1..808934144cc 100644 --- a/dlls/riched20/Makefile.in +++ b/dlls/riched20/Makefile.in @@ -27,3 +27,5 @@ SOURCES = \ version.rc \ wrap.c \ writer.c + +i386_LTO_SKIP_SRC = txthost.c txtsrv.c diff --git a/dlls/rpcrt4/Makefile.in b/dlls/rpcrt4/Makefile.in index 69f6961eff3..f0ebbc7b162 100644 --- a/dlls/rpcrt4/Makefile.in +++ b/dlls/rpcrt4/Makefile.in @@ -28,3 +28,5 @@ SOURCES = \ rpcrt4_main.c \ thunks.c \ version.rc + +LTO_SKIP_SRC = ndr_stubless.c thunks.c diff --git a/dlls/system.drv16/Makefile.in b/dlls/system.drv16/Makefile.in index 260bf957f10..26346994bb6 100644 --- a/dlls/system.drv16/Makefile.in +++ b/dlls/system.drv16/Makefile.in @@ -3,3 +3,5 @@ EXTRADLLFLAGS = -m16
SOURCES = \ system.c + +LTO_SKIP = yes diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index 69e1fa24e15..6006ef28825 100644 --- a/dlls/user32/Makefile.in +++ b/dlls/user32/Makefile.in @@ -68,3 +68,5 @@ SOURCES = \ winproc.c \ winstation.c \ wsprintf.c + +i386_LTO_SKIP_SRC = hook.c sysparams.c win.c winproc.c diff --git a/dlls/vcomp/Makefile.in b/dlls/vcomp/Makefile.in index ec1f82cc33b..d3dfb6e984c 100644 --- a/dlls/vcomp/Makefile.in +++ b/dlls/vcomp/Makefile.in @@ -3,3 +3,7 @@ MODULE = vcomp.dll SOURCES = \ fork.c \ main.c + +LTO_SKIP_SRC = fork.c +i386_LTO_SKIP = yes +x86_64_LTO_SKIP = yes diff --git a/dlls/win32u/Makefile.in b/dlls/win32u/Makefile.in index c64f6bc6fb9..171aef0f858 100644 --- a/dlls/win32u/Makefile.in +++ b/dlls/win32u/Makefile.in @@ -56,3 +56,7 @@ SOURCES = \ vulkan.c \ window.c \ winstation.c + +LTO_SKIP_SRC = main.c +i386_LTO_SKIP_SRC = dibdrv/primitives.c winstation.c +x86_64_LTO_SKIP_SRC = dibdrv/primitives.c winstation.c diff --git a/dlls/win87em.dll16/Makefile.in b/dlls/win87em.dll16/Makefile.in index 03bf1b5853b..2636f3e1205 100644 --- a/dlls/win87em.dll16/Makefile.in +++ b/dlls/win87em.dll16/Makefile.in @@ -3,3 +3,5 @@ EXTRADLLFLAGS = -m16
SOURCES = \ win87em.c + +LTO_SKIP = yes diff --git a/dlls/winebus.sys/Makefile.in b/dlls/winebus.sys/Makefile.in index db32faee5b3..a24aa9ba97e 100644 --- a/dlls/winebus.sys/Makefile.in +++ b/dlls/winebus.sys/Makefile.in @@ -14,3 +14,5 @@ SOURCES = \ main.c \ unixlib.c \ winebus.rc + +i386_LTO_SKIP_SRC = main.c diff --git a/dlls/winecrt0/Makefile.in b/dlls/winecrt0/Makefile.in index 863e5ed4190..df8818a31d5 100644 --- a/dlls/winecrt0/Makefile.in +++ b/dlls/winecrt0/Makefile.in @@ -21,3 +21,8 @@ SOURCES = \ setjmp.c \ stub.c \ unix_lib.c + +LTO_SKIP_SRC = setjmp.c +i386_LTO_SKIP_SRC = exception.c +x86_64_LTO_SKIP_SRC = exception.c +arm64ec_LTO_SKIP_SRC = arm64ec.c unix_lib.c diff --git a/dlls/wineusb.sys/Makefile.in b/dlls/wineusb.sys/Makefile.in index 0c6bb77f143..d4d58d5554b 100644 --- a/dlls/wineusb.sys/Makefile.in +++ b/dlls/wineusb.sys/Makefile.in @@ -10,3 +10,5 @@ SOURCES = \ unixlib.c \ wineusb.c \ wineusb.rc + +i386_LTO_SKIP_SRC = wineusb.c diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in index 9806dd350e9..1e814929d37 100644 --- a/dlls/winex11.drv/Makefile.in +++ b/dlls/winex11.drv/Makefile.in @@ -29,3 +29,5 @@ SOURCES = \ xrandr.c \ xrender.c \ xvidmode.c + +i386_LTO_SKIP_SRC = opengl.c diff --git a/dlls/winexinput.sys/Makefile.in b/dlls/winexinput.sys/Makefile.in index 64241631552..c07b7b8bd9f 100644 --- a/dlls/winexinput.sys/Makefile.in +++ b/dlls/winexinput.sys/Makefile.in @@ -5,3 +5,5 @@ EXTRADLLFLAGS = -Wl,--subsystem,native SOURCES = \ main.c \ winexinput.rc + +i386_LTO_SKIP = yes diff --git a/dlls/wow64/Makefile.in b/dlls/wow64/Makefile.in index 8453e8708c5..f014fd4efdd 100644 --- a/dlls/wow64/Makefile.in +++ b/dlls/wow64/Makefile.in @@ -13,3 +13,5 @@ SOURCES = \ syscall.c \ system.c \ virtual.c + +LTO_SKIP_SRC = syscall.c diff --git a/dlls/wow64cpu/Makefile.in b/dlls/wow64cpu/Makefile.in index b0bb8893d29..3bc68b63951 100644 --- a/dlls/wow64cpu/Makefile.in +++ b/dlls/wow64cpu/Makefile.in @@ -5,3 +5,5 @@ EXTRADLLFLAGS = -nodefaultlibs -Wl,--image-base,0x7a400000
SOURCES = \ cpu.c + +LTO_SKIP = yes diff --git a/dlls/xaudio2_7/Makefile.in b/dlls/xaudio2_7/Makefile.in index 0d88bfe6dd3..6ae757c9c47 100644 --- a/dlls/xaudio2_7/Makefile.in +++ b/dlls/xaudio2_7/Makefile.in @@ -10,3 +10,5 @@ SOURCES = \ xaudio_allocator.c \ xaudio_classes.idl \ xaudio_dll.c + +i386_LTO_SKIP_SRC = xaudio_dll.c diff --git a/loader/Makefile.in b/loader/Makefile.in index a9ca82f3321..61228e0fdb5 100644 --- a/loader/Makefile.in +++ b/loader/Makefile.in @@ -19,3 +19,5 @@ wine_LDFLAGS = $(WINELOADER_LDFLAGS) $(LDEXECFLAGS) $(PTHREAD_LIBS) wine_preloader_OBJS = preloader.o preloader_mac.o wine_preloader_DEPS = $(WINELOADER_DEPENDS) wine_preloader_LDFLAGS = $(WINEPRELOADER_LDFLAGS) + +LTO_SKIP_SRC = preloader.c preloader_mac.c diff --git a/programs/rundll32/Makefile.in b/programs/rundll32/Makefile.in index f2aa9742e36..d2ddc87cc02 100644 --- a/programs/rundll32/Makefile.in +++ b/programs/rundll32/Makefile.in @@ -5,3 +5,5 @@ EXTRADLLFLAGS = -mwindows -municode
SOURCES = \ rundll32.c + +i386_LTO_SKIP = yes diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in index 0983420a91f..81f31dc945d 100644 --- a/programs/wineboot/Makefile.in +++ b/programs/wineboot/Makefile.in @@ -9,3 +9,6 @@ SOURCES = \ wineboot.c \ wineboot.man.in \ wineboot.rc + +i386_LTO_SKIP_SRC = wineboot.c +x86_64_LTO_SKIP_SRC = wineboot.c diff --git a/tools/lto-skip.i386.list b/tools/lto-skip.i386.list new file mode 100644 index 00000000000..2147073a594 --- /dev/null +++ b/tools/lto-skip.i386.list @@ -0,0 +1,11 @@ +dlls/dinput/dinput.c +dlls/msvcrt/exception_ptr.c +dlls/msvcrt/file.c +dlls/msvcrt/misc.c +dlls/msvcrt/string.c +dlls/ntdll/large_int.c +dlls/ntdll/loader.c +dlls/ntdll/math.c +dlls/ntdll/resource.c +dlls/ntdll/rtl.c +dlls/ntdll/unix/loader.c diff --git a/tools/lto-skip.list b/tools/lto-skip.list new file mode 100644 index 00000000000..e24fec819e0 --- /dev/null +++ b/tools/lto-skip.list @@ -0,0 +1,17 @@ +dlls/msvcrt/except_arm.c +dlls/msvcrt/except_arm64.c +dlls/msvcrt/except_arm64ec.c +dlls/msvcrt/except_i386.c +dlls/msvcrt/except_x86_64.c +dlls/msvcrt/math.c +dlls/ntdll/relay.c +dlls/ntdll/signal_arm.c +dlls/ntdll/signal_arm64.c +dlls/ntdll/signal_arm64ec.c +dlls/ntdll/signal_i386.c +dlls/ntdll/signal_x86_64.c +dlls/ntdll/unix/signal_arm.c +dlls/ntdll/unix/signal_arm64.c +dlls/ntdll/unix/signal_i386.c +dlls/ntdll/unix/signal_x86_64.c +dlls/ntdll/unix/system.c diff --git a/tools/lto-skip.x86_64.list b/tools/lto-skip.x86_64.list new file mode 100644 index 00000000000..2edd78cfab4 --- /dev/null +++ b/tools/lto-skip.x86_64.list @@ -0,0 +1,3 @@ +dlls/msvcrt/string.c +dlls/ntdll/loader.c +dlls/ntdll/process.c
@insn, I've done some refactoring so code should be more sane and clear. All commits except "configure: enable building Wine with LTO" and "LTO quirks" are safe to merge.
On Mon Mar 3 21:32:42 2025 +0000, Konstantin Demin wrote:
@insn, I've done some refactoring so code should be more sane and clear. All commits except "configure: enable building Wine with LTO" and "LTO quirks" are safe to merge - I'll remove them in favour of next/upcoming MR if you wish.
Thanks. I'm still not a fan of the environment variables like `WINE_AR`, is there a reason you aren't just unconditionally using `gcc-ar` if available? It is a superset of `ar` anyway.
I think you should split the last patch, yeah. In particular, you disable too many files. For example, why are you disabling `d3d9/device.c` from having LTO?
A lot of those files can also be "fixed" by fixing just the actual cause of the issue (for example, marking functions with `used` attribute) instead of disabling LTO completely. The only problematic ones are those **exporting** asm functions.
I think it would be great for Wine to have LTO. But well, it's not really up to me. Alexandre hasn't really commented on any of the LTO MRs. :/
Gabriel Ivăncescu (@insn) commented about tools/lto.h:
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
+#ifndef __WINE_LTO_H +#define __WINE_LTO_H
+#ifndef __WINE_TOOLS_H +# error You must include tools.h to use this header +#endif
+__attribute__((used)) +static void append_lto_flags( struct strarray *args, int with_lto, int prefer_env )
Wait, what is the point of this? `static` and unused is completely useless.
On Mon Mar 3 22:10:48 2025 +0000, Gabriel Ivăncescu wrote:
Wait, what is the point of this? `static` and unused is completely useless.
That's `used` (emit into binary even if unused from C code), not `unused` (suppress warning if unused, but do optimize it out). Latter would be reasonable (as would `static inline`), but former is indeed silly.
But in this case, I'd rather move it to some suitable .c file.
Alfred Agrell (@Alcaro) commented about tools/lto.h:
- */
+#ifndef __WINE_LTO_H +#define __WINE_LTO_H
+#ifndef __WINE_TOOLS_H +# error You must include tools.h to use this header +#endif
+__attribute__((used)) +static void append_lto_flags( struct strarray *args, int with_lto, int prefer_env ) +{
- if (with_lto < 0) return;
- while (prefer_env > 0)
I'm sure there's a better way to structure this than a `while` that always ends with break or return.
On Mon Mar 3 22:25:34 2025 +0000, Alfred Agrell wrote:
That's `used` (emit into binary even if unused from C code), not `unused` (suppress warning if unused, but do optimize it out). Latter would be reasonable (as would `static inline` (at least usually, not sure how it interacts with those statics)), but former is indeed silly. But in this case, I'd rather move it to some suitable .c file.
This is second variant of common LTO functions (they were in `tools/tools.h` before). If I remove "used" attribute from function definition then compiler emits warning (`-Wunused-function`) and with `-Werror` it produces build error - that's because not all of them are used in affected tools. Both variants - "used" attribute or "inline" - are looking not so good as it should be but I've chosen first one. However I'll apply your suggestions if there're any.
On Mon Mar 3 22:27:06 2025 +0000, Alfred Agrell wrote:
I'm sure there's a better way to structure this than a `while` that always ends with break or return.
You're right. This "while-break" pattern is not required here and may be replace with simple "if".