mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Add --print-large-functions for checking which functions likely dominate the compile time.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {};
|
||||||
|
|||||||
Reference in New Issue
Block a user