mirror of
https://github.com/odin-lang/Odin.git
synced 2026-10-09 06:12:05 -04:00
Merge pull request #7729 from odin-lang/bill/llvm-backend-improvements
LLVM Backend Performance Improvements to Reduce Compile Times Part 2
This commit is contained in:
28 files changed
+1266
-941
No files matched your search
+129
-62
@@ -2383,6 +2383,132 @@ gb_internal void show_import_graph(Checker *c) {
|
||||
gb_printf("}\n\n");
|
||||
}
|
||||
|
||||
gb_internal void add_time_to_tokenize_only(AstFile *f, f64 *time, u64 *cpu_time) {
|
||||
isize size = f->tokenizer.end - f->tokenizer.start;
|
||||
if (size <= 0) {
|
||||
return;
|
||||
}
|
||||
Tokenizer t = {};
|
||||
t.curr_file_id = f->id;
|
||||
init_tokenizer_with_data(&t, f->fullpath, f->tokenizer.start, size);
|
||||
|
||||
u64 start = time_stamp_time_now();
|
||||
u64 cpu_start = thread_cpu_time_now();
|
||||
Token token = {};
|
||||
do {
|
||||
tokenizer_get_token(&t, &token);
|
||||
} while (token.kind != Token_EOF && token.kind != Token_Invalid);
|
||||
*cpu_time += thread_cpu_time_now()-cpu_start;
|
||||
*time += cast(f64)(time_stamp_time_now()-start)/cast(f64)time_stamp__freq();
|
||||
}
|
||||
|
||||
gb_internal GB_COMPARE_PROC(file_cpu_time_to_parse_cmp) {
|
||||
AstFile *x = *(AstFile **)a;
|
||||
AstFile *y = *(AstFile **)b;
|
||||
if (x->cpu_time_to_parse != y->cpu_time_to_parse) {
|
||||
return x->cpu_time_to_parse > y->cpu_time_to_parse ? -1 : +1;
|
||||
}
|
||||
return string_compare(x->fullpath, y->fullpath);
|
||||
}
|
||||
|
||||
gb_internal void show_parse_timings(Parser *p, Timings *t) {
|
||||
auto all_files = array_make<AstFile *>(heap_allocator(), 0, p->packages.count*8);
|
||||
defer (array_free(&all_files));
|
||||
for (AstPackage *pkg : p->packages) {
|
||||
for (AstFile *file : pkg->files) {
|
||||
array_add(&all_files, file);
|
||||
}
|
||||
}
|
||||
|
||||
f64 cpu_freq = thread_cpu_time_freq();
|
||||
|
||||
isize tokens = p->total_token_count;
|
||||
isize lines = p->total_line_count;
|
||||
isize total_file_size = 0;
|
||||
|
||||
f64 load_time = 0;
|
||||
f64 load_cpu_time = 0;
|
||||
f64 parse_time = 0;
|
||||
f64 parse_cpu_time = 0;
|
||||
f64 setup_time = 0;
|
||||
f64 setup_cpu_time = 0;
|
||||
f64 tokenize_time = 0;
|
||||
u64 tokenize_cpu_ticks = 0;
|
||||
|
||||
for (AstFile *file : all_files) {
|
||||
total_file_size += file->tokenizer.end - file->tokenizer.start;
|
||||
load_time += file->time_to_load;
|
||||
parse_time += file->time_to_parse;
|
||||
setup_time += file->time_to_setup_decls;
|
||||
load_cpu_time += cast(f64)file->cpu_time_to_load/cpu_freq;
|
||||
parse_cpu_time += cast(f64)file->cpu_time_to_parse/cpu_freq;
|
||||
setup_cpu_time += cast(f64)file->cpu_time_to_setup_decls/cpu_freq;
|
||||
|
||||
add_time_to_tokenize_only(file, &tokenize_time, &tokenize_cpu_ticks);
|
||||
}
|
||||
|
||||
f64 tokenize_cpu_time = cast(f64)tokenize_cpu_ticks/cpu_freq;
|
||||
|
||||
f64 wall_time = 0;
|
||||
for (TimeStamp const &s : t->sections) {
|
||||
if (s.label == "parse files") {
|
||||
wall_time = time_stamp_as_s(s, t->freq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
isize thread_count = gb_max(global_thread_pool.threads.count, 1);
|
||||
f64 task_time = load_time + parse_time + setup_time;
|
||||
f64 task_cpu_time = load_cpu_time + parse_cpu_time + setup_cpu_time;
|
||||
f64 mib = cast(f64)total_file_size/(1024.0*1024.0);
|
||||
|
||||
auto const &row = [&](char const *label, f64 time, f64 cpu_time, bool rates) {
|
||||
gb_printf_err(" %s - %9.3f ms %9.3f ms", label, 1.0e3*time, 1.0e3*cpu_time);
|
||||
if (rates) {
|
||||
f64 lines_per_second = cast(f64)lines/cpu_time;
|
||||
char const *loc = " LOC/s";
|
||||
if (lines_per_second >= 1.0e6) {
|
||||
lines_per_second /= 1.0e6;
|
||||
loc = " MLOC/s";
|
||||
} else if (lines_per_second >= 1.0e3) {
|
||||
lines_per_second /= 1.0e3;
|
||||
loc = " kLOC/s";
|
||||
}
|
||||
gb_printf_err(" %7.3f us/token %7.3f us/line %8.2f MiB/s %7.2f%s",
|
||||
1.0e6*cpu_time/cast(f64)tokens, 1.0e6*cpu_time/cast(f64)lines, mib/cpu_time, lines_per_second, loc);
|
||||
}
|
||||
gb_printf_err("\n");
|
||||
};
|
||||
|
||||
gb_printf_err("Parsing (%td files, %td lines, %td tokens, %.2f MiB, %td threads)\n", all_files.count, lines, tokens, mib, thread_count);
|
||||
gb_printf_err(" parse files - %9.3f ms (wall time)\n", 1.0e3*wall_time);
|
||||
gb_printf_err(" wall time CPU time (rates from the CPU time)\n");
|
||||
row( "file tasks ", task_time, task_cpu_time, false);
|
||||
row( " loading files ", load_time, load_cpu_time, false);
|
||||
row( " tokenizing and parsing ", parse_time, parse_cpu_time, true);
|
||||
row( " setting up decls and imports ", setup_time, setup_cpu_time, false);
|
||||
row( "tokenizing alone, 1 thread ", tokenize_time, tokenize_cpu_time, true);
|
||||
if (build_context.thread_count == 1) {
|
||||
row( "parsing alone (estimated) ", parse_time-tokenize_time, parse_cpu_time-tokenize_cpu_time, true);
|
||||
} else {
|
||||
gb_printf_err(" parsing alone - estimated with -thread-count:1\n");
|
||||
}
|
||||
gb_printf_err(" the file tasks kept the threads %.0f%% busy and %.0f%% of their time was spent running\n",
|
||||
100.0*task_time/(wall_time*cast(f64)thread_count), 100.0*task_cpu_time/task_time);
|
||||
gb_printf_err("\n");
|
||||
|
||||
array_sort(all_files, file_cpu_time_to_parse_cmp);
|
||||
gb_printf_err("Slowest files to tokenize and parse, by CPU time\n");
|
||||
for (isize i = 0; i < gb_min(all_files.count, 8); i++) {
|
||||
AstFile *file = all_files[i];
|
||||
f64 cpu_time = cast(f64)file->cpu_time_to_parse/cpu_freq;
|
||||
gb_printf_err(" %9.3f ms %9.3f ms (wall) %8td tokens %7.3f us/token %.*s\n",
|
||||
1.0e3*cpu_time, 1.0e3*file->time_to_parse, file->token_count,
|
||||
1.0e6*cpu_time/cast(f64)gb_max(file->token_count, 1), LIT(file->fullpath));
|
||||
}
|
||||
gb_printf_err("\n");
|
||||
}
|
||||
|
||||
gb_internal void show_timings(Checker *c, Timings *t) {
|
||||
Parser *p = c->parser;
|
||||
isize lines = p->total_line_count;
|
||||
@@ -2390,13 +2516,9 @@ gb_internal void show_timings(Checker *c, Timings *t) {
|
||||
isize files = 0;
|
||||
isize packages = p->packages.count;
|
||||
isize total_file_size = 0;
|
||||
f64 total_tokenizing_time = 0;
|
||||
f64 total_parsing_time = 0;
|
||||
for (AstPackage *pkg : p->packages) {
|
||||
files += pkg->files.count;
|
||||
for (AstFile *file : pkg->files) {
|
||||
total_tokenizing_time += file->time_to_tokenize;
|
||||
total_parsing_time += file->time_to_parse;
|
||||
total_file_size += file->tokenizer.end - file->tokenizer.start;
|
||||
}
|
||||
}
|
||||
@@ -2419,54 +2541,7 @@ gb_internal void show_timings(Checker *c, Timings *t) {
|
||||
gb_printf_err("Total File Size - %td\n", total_file_size);
|
||||
gb_printf_err("\n");
|
||||
}
|
||||
{
|
||||
f64 time = total_tokenizing_time;
|
||||
gb_printf_err("Tokenization Only\n");
|
||||
gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/time);
|
||||
gb_printf_err("us/LOC - %.3f\n", 1.0e6*time/cast(f64)lines);
|
||||
gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/time);
|
||||
gb_printf_err("us/Token - %.3f\n", 1.0e6*time/cast(f64)tokens);
|
||||
gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/time);
|
||||
gb_printf_err("MiB/s - %.3f\n", cast(f64)(total_file_size/time)/(1024*1024));
|
||||
gb_printf_err("us/bytes - %.3f\n", 1.0e6*time/cast(f64)total_file_size);
|
||||
|
||||
gb_printf_err("\n");
|
||||
}
|
||||
{
|
||||
f64 time = total_parsing_time;
|
||||
gb_printf_err("Parsing Only\n");
|
||||
gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/time);
|
||||
gb_printf_err("us/LOC - %.3f\n", 1.0e6*time/cast(f64)lines);
|
||||
gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/time);
|
||||
gb_printf_err("us/Token - %.3f\n", 1.0e6*time/cast(f64)tokens);
|
||||
gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/time);
|
||||
gb_printf_err("MiB/s - %.3f\n", cast(f64)(total_file_size/time)/(1024*1024));
|
||||
gb_printf_err("us/bytes - %.3f\n", 1.0e6*time/cast(f64)total_file_size);
|
||||
|
||||
gb_printf_err("\n");
|
||||
}
|
||||
{
|
||||
TimeStamp ts = {};
|
||||
for (TimeStamp const &s : t->sections) {
|
||||
if (s.label == "parse files") {
|
||||
ts = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
GB_ASSERT(ts.label == "parse files");
|
||||
|
||||
f64 parse_time = time_stamp_as_s(ts, t->freq);
|
||||
gb_printf_err("Parse pass\n");
|
||||
gb_printf_err("LOC/s - %.3f\n", cast(f64)lines/parse_time);
|
||||
gb_printf_err("us/LOC - %.3f\n", 1.0e6*parse_time/cast(f64)lines);
|
||||
gb_printf_err("Tokens/s - %.3f\n", cast(f64)tokens/parse_time);
|
||||
gb_printf_err("us/Token - %.3f\n", 1.0e6*parse_time/cast(f64)tokens);
|
||||
gb_printf_err("bytes/s - %.3f\n", cast(f64)total_file_size/parse_time);
|
||||
gb_printf_err("MiB/s - %.3f\n", cast(f64)(total_file_size/parse_time)/(1024*1024));
|
||||
gb_printf_err("us/bytes - %.3f\n", 1.0e6*parse_time/cast(f64)total_file_size);
|
||||
|
||||
gb_printf_err("\n");
|
||||
}
|
||||
show_parse_timings(p, t);
|
||||
{
|
||||
TimeStamp ts = {};
|
||||
TimeStamp ts_end = {};
|
||||
@@ -3634,7 +3709,7 @@ gb_internal gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file
|
||||
u8 const *file_data = file->tokenizer.start;
|
||||
i32 prev_offset = 0;
|
||||
i32 const end_offset = cast(i32)(file->tokenizer.end - file->tokenizer.start);
|
||||
for (Token const &token : file->tokens) {
|
||||
for (Token const &token : file->token_edits) {
|
||||
if (token.flags & (TokenFlag_Remove|TokenFlag_Replace)) {
|
||||
i32 offset = token.pos.offset;
|
||||
i32 to_write = offset-prev_offset;
|
||||
@@ -3677,15 +3752,7 @@ gb_internal int strip_semicolons(Parser *parser) {
|
||||
|
||||
for (AstPackage *pkg : parser->packages) {
|
||||
for (AstFile *file : pkg->files) {
|
||||
bool nothing_to_change = true;
|
||||
for (Token const &token : file->tokens) {
|
||||
if (token.flags) {
|
||||
nothing_to_change = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nothing_to_change) {
|
||||
if (file->token_edits.count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user