From: Konstantin Demin rockdrilla@gmail.com
Signed-off-by: Konstantin Demin rockdrilla@gmail.com --- tools/makedep.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 4 deletions(-)
diff --git a/tools/makedep.c b/tools/makedep.c index d7b2cfe53fe..c63e902fdfe 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -189,6 +189,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 { @@ -221,6 +222,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; @@ -4628,6 +4631,32 @@ static void load_sources( struct makefile *make )
STRARRAY_FOR_EACH( imp, &make->delayimports ) strarray_add_uniq( &delay_import_libs, get_base_name( imp )); + + if (with_lto) + { + for (arch = 0; arch < archs.count; arch++) + { + (void) memset( &make->lto_skip_src[arch], 0, sizeof(struct strarray) ); + + make->lto_skip[arch] = var_to_bool(get_expanded_arch_var( make, "LTO_SKIP", arch )); + if (make->lto_skip[arch]) + { + /* target is marked as non-LTO for all arches: + break early */ + if (!arch) break; + + /* target is marked as non-LTO for specific arch: + no need to parse source skiplist */ + continue; + } + + value = get_expanded_arch_var_array( make, "LTO_SKIP_SRC", arch ); + STRARRAY_FOR_EACH( src, &value ) + { + strarray_add( &make->lto_skip_src[arch], xstrdup( src )); + } + } + } }
@@ -4711,19 +4740,112 @@ static void output_lto_flags( int use_lto, int prefer_env ) }
+/******************************************************************* + * parse_global_lto_skip_lists + */ +static void parse_global_lto_skip_lists(void) +{ + char *buf = NULL; + FILE *file = NULL; + + for (unsigned int arch = 0; arch < archs.count; arch++) + { + (void) 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 ((buf = get_line( file ))) + { + buf = skip_spaces( buf ); + if (!(buf[0])) continue; /* empty line */ + if (buf[0] == '#') continue; /* comment */ + strarray_add( &global_lto_skip[arch], xstrdup( buf )); + } + + (void) fclose( file ); file = NULL; + 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 ) { - (void) arch; /* mark as used */ + int use_lto = 0;
if (!with_lto) return; if (!make) return; if (!source) return;
- 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 ); }
@@ -4732,12 +4854,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 ) { - (void) arch; /* mark as used */ + int use_lto = 0;
if (!with_lto) return; if (!make) return;
- output_lto_flags( with_lto, prefer_env ); + use_lto = is_lto_enabled_target( make, arch ); + output_lto_flags( use_lto, prefer_env ); }
@@ -4879,6 +5002,7 @@ int main( int argc, char *argv[] )
for (i = 0; i < subdirs.count; i++) submakes[i] = parse_makefile( subdirs.str[i] );
+ if (with_lto) parse_global_lto_skip_lists(); load_sources( top_makefile ); load_sources( include_makefile ); for (i = 0; i < subdirs.count; i++)