Add some timers

This commit is contained in:
David Gonzalez Martin 2025-06-21 15:45:35 -06:00
parent df41463fb3
commit b4c19031a5
3 changed files with 90 additions and 4 deletions

View File

@ -5,6 +5,8 @@ global_variable Slice<char* const> environment;
fn void compile(Arena* arena, Options options)
{
Module module;
save_time(TimeId::start, &module, CounterId::initialization);
auto start_time = module.counters[(u64)CounterId::initialization].start;
auto base_allocation_type_count = i128_offset + // 64 * 2 for basic integer types
2 + // u128, s128
2; // void, noreturn
@ -132,7 +134,12 @@ fn void compile(Arena* arena, Options options)
};
}
module.counters[(u64)CounterId::initialization].start = start_time;
save_time(TimeId::end, &module, CounterId::initialization);
save_time(TimeId::start, &module, CounterId::parsing);
parse(&module);
save_time(TimeId::end, &module, CounterId::parsing);
emit(&module);
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <lib.hpp>
#include <time.h>
#include <llvm-c/TargetMachine.h>
#define report_error() trap()
@ -1302,6 +1303,26 @@ struct Definition
String value;
};
struct Counter
{
struct timespec start;
struct timespec end;
};
enum class CounterId
{
initialization,
parsing,
llvm_initialization_global,
llvm_initialization_local,
semantic_analysis,
verification,
optimization,
emit_object,
link,
count,
};
struct Module
{
Arena* arena;
@ -1343,12 +1364,25 @@ struct Module
bool link_libc = true;
bool link_libcpp = false;
Counter counters[(u64)CounterId::count];
Target target;
BuildMode build_mode;
bool has_debug_info;
bool silent;
};
enum class TimeId
{
start,
end,
};
fn void save_time(TimeId time_id, Module* module, CounterId counter_id)
{
clock_gettime(CLOCK_MONOTONIC, &module->counters[(u64)counter_id].start + (s64)time_id);
}
constexpr u64 i128_offset = 64 * 2;
constexpr u64 void_offset = i128_offset + 2;

View File

@ -384,7 +384,10 @@ fn LLVMCallConv llvm_calling_convention(CallingConvention calling_convention)
fn void llvm_initialize(Module* module)
{
save_time(TimeId::start, module, CounterId::llvm_initialization_global);
llvm_initialize_all();
save_time(TimeId::end, module, CounterId::llvm_initialization_global);
save_time(TimeId::start, module, CounterId::llvm_initialization_local);
auto context = LLVMContextCreate();
auto m = LLVMModuleCreateWithNameInContext((char*)module->name.pointer, context);
@ -502,6 +505,7 @@ fn void llvm_initialize(Module* module)
assert(attribute_id != 0);
module->llvm.attribute_table[i].n = attribute_id;
}
save_time(TimeId::end, module, CounterId::llvm_initialization_local);
}
enum class AbiSystemVClass
@ -9168,10 +9172,11 @@ struct ObjectGenerate
bool has_debug_info;
};
fn BBLLVMCodeGenerationPipelineResult generate_object(LLVMModuleRef module, LLVMTargetMachineRef target_machine, ObjectGenerate options)
fn BBLLVMCodeGenerationPipelineResult generate_object(Module* module, LLVMTargetMachineRef target_machine, ObjectGenerate options)
{
if (options.run_optimization_passes)
{
save_time(TimeId::start, module, CounterId::optimization);
// BBLLVM
bool prefer_speed = options.optimization_level == BBLLVMOptimizationLevel::O2 || options.optimization_level == BBLLVMOptimizationLevel::O3;
BBLLVMOptimizationPipelineOptions optimization_options = {
@ -9187,16 +9192,20 @@ fn BBLLVMCodeGenerationPipelineResult generate_object(LLVMModuleRef module, LLVM
.assignment_tracking = options.has_debug_info,
.verify_module = true,
};
llvm_module_run_optimization_pipeline(module, target_machine, optimization_options);
llvm_module_run_optimization_pipeline(module->llvm.module, target_machine, optimization_options);
save_time(TimeId::end, module, CounterId::optimization);
// BBLLVM
}
save_time(TimeId::start, module, CounterId::emit_object);
BBLLVMCodeGenerationPipelineOptions code_generation_options = {
.output_file_path = options.path,
.file_type = BBLLVMCodeGenerationFileType::object_file,
.optimize_when_possible = options.optimization_level > BBLLVMOptimizationLevel::O0,
.verify_module = true,
};
auto result = llvm_module_run_code_generation_pipeline(module, target_machine, &code_generation_options);
auto result = llvm_module_run_code_generation_pipeline(module->llvm.module, target_machine, &code_generation_options);
save_time(TimeId::end, module, CounterId::emit_object);
return result;
}
@ -9325,8 +9334,11 @@ void emit(Module* module)
assert(!module->current_function);
assert(!module->current_macro_instantiation);
assert(!module->current_macro_declaration);
llvm_initialize(module);
save_time(TimeId::start, module, CounterId::semantic_analysis);
for (auto* global = module->first_global; global; global = global->next)
{
assert(!module->current_function);
@ -10003,6 +10015,9 @@ void emit(Module* module)
LLVMDIBuilderFinalize(module->llvm.di_builder);
}
save_time(TimeId::end, module, CounterId::semantic_analysis);
save_time(TimeId::start, module, CounterId::verification);
char* verification_error_message = 0;
auto result = LLVMVerifyModule(module->llvm.module, LLVMReturnStatusAction, &verification_error_message) == 0;
if (!result)
@ -10012,6 +10027,7 @@ void emit(Module* module)
print(c_string_to_slice(verification_error_message));
bb_fail();
}
save_time(TimeId::end, module, CounterId::verification);
if (!module->silent)
{
@ -10043,7 +10059,7 @@ void emit(Module* module)
case BuildMode::count:
unreachable();
}
auto object_generation_result = generate_object(module->llvm.module, module->llvm.target_machine, {
auto object_generation_result = generate_object(module, module->llvm.target_machine, {
.path = module->objects[0],
.optimization_level = optimization_level,
.run_optimization_passes = module->build_mode != BuildMode::debug_none,
@ -10054,5 +10070,34 @@ void emit(Module* module)
report_error();
}
save_time(TimeId::start, module, CounterId::link);
link(module);
save_time(TimeId::end, module, CounterId::link);
struct timespec res_ts;
clock_getres(CLOCK_MONOTONIC, &res_ts);
auto res_ns = res_ts.tv_nsec + (res_ts.tv_sec * 1000 * 1000 * 1000);
u64 times[(u64)CounterId::count];
for (u64 i = 0; i < (u64)CounterId::count; i += 1)
{
auto& start = module->counters[i].start;
auto& end = module->counters[i].end;
auto ns = end.tv_nsec - start.tv_nsec;
auto s = end.tv_sec - start.tv_sec;
if (ns < 0)
{
s -= 1;
ns += 1000 * 1000 * 1000;
}
ns = ns + (s * 1000 * 1000 * 1000);
times[i] = ns;
}
trap();
}