Add --print-large-functions for checking which functions likely dominate the compile time.

This commit is contained in:
Christoffer Lerno
2026-02-16 00:13:19 +01:00
parent d7cf8fa9ab
commit a7309b217e
9 changed files with 30 additions and 5 deletions

View File

@@ -15,6 +15,7 @@
- Change typedef and const enums to not convert from literals by default. - Change typedef and const enums to not convert from literals by default.
- Add `@constinit` to allow old typedef behaviour. - Add `@constinit` to allow old typedef behaviour.
- Include actual element count in the error message when the array initializer size does not match the expected size. - Include actual element count in the error message when the array initializer size does not match the expected size.
- Add `--print-large-functions` for checking which functions likely dominate the compile time.
### Stdlib changes ### Stdlib changes
- Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831 - Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831

View File

@@ -210,6 +210,7 @@ typedef struct BuildOptions_
bool test_nosort; bool test_nosort;
bool test_noleak; bool test_noleak;
bool test_show_output; bool test_show_output;
bool print_large_functions;
const char *custom_linker_path; const char *custom_linker_path;
uint32_t symtab_size; uint32_t symtab_size;
unsigned version; unsigned version;
@@ -416,6 +417,7 @@ typedef struct
bool old_enums; bool old_enums;
bool old_compact_eq; bool old_compact_eq;
bool single_threaded; bool single_threaded;
bool print_large_functions;
int build_threads; int build_threads;
TrustLevel trust_level; TrustLevel trust_level;
OptimizationSetting optsetting; OptimizationSetting optsetting;

View File

@@ -140,6 +140,7 @@ static void usage(bool full)
print_opt("--use-old-slice-copy", "Use the old slice copy semantics."); print_opt("--use-old-slice-copy", "Use the old slice copy semantics.");
print_opt("--use-old-enums", "Use the old enum syntax and semantics."); print_opt("--use-old-enums", "Use the old enum syntax and semantics.");
print_opt("--use-old-compact-eq", "Enable the old ability to use '@compact' to make a struct comparable."); print_opt("--use-old-compact-eq", "Enable the old ability to use '@compact' to make a struct comparable.");
print_opt("--print-large-functions", "Print functions with large compile size.");
print_opt("--warn-deadcode=<yes|no|error>", "Print warning on dead-code: yes, no, error."); print_opt("--warn-deadcode=<yes|no|error>", "Print warning on dead-code: yes, no, error.");
print_opt("--warn-methodsnotresolved=<yes|no|error>", "Print warning on methods not resolved when accessed: yes, no, error."); print_opt("--warn-methodsnotresolved=<yes|no|error>", "Print warning on methods not resolved when accessed: yes, no, error.");
print_opt("--warn-deprecation=<yes|no|error>", "Print warning when using deprecated code and constructs: yes, no, error."); print_opt("--warn-deprecation=<yes|no|error>", "Print warning when using deprecated code and constructs: yes, no, error.");
@@ -895,6 +896,11 @@ static void parse_option(BuildOptions *options)
options->test_nosort = true; options->test_nosort = true;
return; return;
} }
if (match_longopt("print-large-functions"))
{
options->print_large_functions = true;
return;
}
if ((argopt = match_argopt("warn-deadcode"))) if ((argopt = match_argopt("warn-deadcode")))
{ {
options->warnings.dead_code = parse_opt_select(WarningLevel, argopt, warnings); options->warnings.dead_code = parse_opt_select(WarningLevel, argopt, warnings);

View File

@@ -429,6 +429,8 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
target->old_slice_copy = options->old_slice_copy; target->old_slice_copy = options->old_slice_copy;
target->old_enums = options->old_enums; target->old_enums = options->old_enums;
target->old_compact_eq = options->old_compact_eq; target->old_compact_eq = options->old_compact_eq;
target->print_large_functions = options->print_large_functions;
// Remove feature flags // Remove feature flags
FOREACH(const char *, remove_feature, options->removed_feature_names) FOREACH(const char *, remove_feature, options->removed_feature_names)
{ {

View File

@@ -609,7 +609,15 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, FunctionPrototype *pro
c->debug.block_stack = NULL; c->debug.block_stack = NULL;
LLVMDIBuilderFinalizeSubprogram(c->debug.builder, c->debug.function); LLVMDIBuilderFinalizeSubprogram(c->debug.builder, c->debug.function);
} }
if (compiler.build.print_large_functions)
{
unsigned instruction_count = LLVMGetFunctionInstructionCount(function);
if (instruction_count > 5000)
{
eprintf("%8u instructions found in %s:%s (%s) - function is very long.\n", instruction_count, decl->unit->module->name->module,
decl->name, decl->unit->file->full_path);
}
}
c->builder = prev_builder; c->builder = prev_builder;
c->cur_func.ref = prev_function; c->cur_func.ref = prev_function;
} }

View File

@@ -51,14 +51,14 @@ const char *context_filename(SemaContext *context);
AstId context_get_defers(SemaContext *context, AstId defer_bottom, bool is_success); AstId context_get_defers(SemaContext *context, AstId defer_bottom, bool is_success);
void context_pop_defers(SemaContext *context, AstId *next); void context_pop_defers(SemaContext *context, AstId *next);
void context_pop_defers_and_replace_ast(SemaContext *context, Ast *ast); void context_pop_defers_and_replace_ast(SemaContext *context, Ast *ast);
void context_change_scope_for_label(SemaContext *context, DeclId label, SourceSpan span); void context_change_scope_for_label(SemaContext *context, DeclId label_id, SourceSpan span);
void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags, SourceSpan span); void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags, SourceSpan span);
SemaContext *context_transform_for_eval(SemaContext *context, SemaContext *temp_context, CompilationUnit *eval_unit); SemaContext *context_transform_for_eval(SemaContext *context, SemaContext *temp_context, CompilationUnit *eval_unit);
TokenType sema_splitpathref(const char *string, ArraySize len, Path **path_ref, const char **ident_ref); TokenType sema_splitpathref(const char *string, ArraySize len, Path **path_ref, const char **ident_ref);
void sema_print_inline(SemaContext *context, SourceSpan span_original); void sema_print_inline(SemaContext *context, SourceSpan original);
void sema_error_at(SemaContext *context, SourceSpan span, const char *message, ...); void sema_error_at(SemaContext *context, SourceSpan span, const char *message, ...);
bool sema_warn_at(SemaContext *context, SourceSpan span, WarningLevel warning, const char *message, ...); bool sema_warn_at(SemaContext *context, SourceSpan span, WarningLevel level, const char *message, ...);
void sema_context_init(SemaContext *context, CompilationUnit *unit); void sema_context_init(SemaContext *context, CompilationUnit *unit);
void sema_context_destroy(SemaContext *context); void sema_context_destroy(SemaContext *context);

View File

@@ -225,7 +225,7 @@ macro test_hash_vector_macro_bool()
} }
$endforeach $endforeach
} }
fn void test_hash_vector() fn void test_hash_vector() @if($feature(SLOW_TESTS))
{ {
test_hash_vector_macro(char, ichar, short, ushort, int, uint, long, ulong, int128, uint128); test_hash_vector_macro(char, ichar, short, ushort, int, uint, long, ulong, int128, uint128);
test_hash_vector_macro_bool(); test_hash_vector_macro_bool();

View File

@@ -81,6 +81,7 @@ void LLVMSetDSOLocal(LLVMValueRef Global, bool value);
void LLVMSetTargetMachineUseInitArray(LLVMTargetMachineRef ref, bool use_init_array); void LLVMSetTargetMachineUseInitArray(LLVMTargetMachineRef ref, bool use_init_array);
void LLVMSetTargetMachineEmulatedTLS(LLVMTargetMachineRef ref, bool emulated_tls); void LLVMSetTargetMachineEmulatedTLS(LLVMTargetMachineRef ref, bool emulated_tls);
void LLVMSetNoSanitizeAddress(LLVMValueRef Global); void LLVMSetNoSanitizeAddress(LLVMValueRef Global);
unsigned LLVMGetFunctionInstructionCount(LLVMValueRef function);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -341,6 +341,11 @@ void LLVMSetNoSanitizeAddress(LLVMValueRef Global)
global->setSanitizerMetadata(data); global->setSanitizerMetadata(data);
} }
unsigned LLVMGetFunctionInstructionCount(LLVMValueRef function)
{
auto func = llvm::unwrap<llvm::Function>(function);
return func->getInstructionCount();
}
void LLVMBuilderSetFastMathFlags(LLVMBuilderRef Builder, FastMathOption option) void LLVMBuilderSetFastMathFlags(LLVMBuilderRef Builder, FastMathOption option)
{ {
llvm::FastMathFlags math_flags {}; llvm::FastMathFlags math_flags {};