mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 01:21:38 -07:00
Speed up SSA generation and clang compilation
This commit is contained in:
@@ -51,7 +51,7 @@ pushd %build_dir%
|
||||
|
||||
cl %compiler_settings% "..\src\main.cpp" ^
|
||||
/link %linker_settings% -OUT:%exe_name% ^
|
||||
&& odin run ..\examples/demo.odin
|
||||
&& odin ..\examples/demo.odin
|
||||
rem odin run ..\examples/demo.odin
|
||||
|
||||
|
||||
|
||||
+808
-695
File diff suppressed because it is too large
Load Diff
+8
-10
@@ -6,9 +6,7 @@ TWO_HEARTS :: #rune "💕"
|
||||
|
||||
win32_perf_count_freq := GetQueryPerformanceFrequency()
|
||||
time_now :: proc() -> f64 {
|
||||
if win32_perf_count_freq == 0 {
|
||||
debug_trap()
|
||||
}
|
||||
assert(win32_perf_count_freq != 0)
|
||||
|
||||
counter: i64
|
||||
_ = QueryPerformanceCounter(^counter)
|
||||
@@ -25,10 +23,10 @@ win32_print_last_error :: proc() {
|
||||
}
|
||||
|
||||
// Yuk!
|
||||
to_c_string :: proc(s: string) -> ^u8 {
|
||||
c_str: ^u8 = alloc(len(s)+1)
|
||||
memory_copy(c_str, ^s[0], len(s))
|
||||
ptr_offset(c_str, len(s))^ = 0
|
||||
to_c_string :: proc(s: string) -> []u8 {
|
||||
c_str := new_slice(u8, len(s)+1)
|
||||
_ = copy(c_str, s as []byte)
|
||||
c_str[len(s)] = 0
|
||||
return c_str
|
||||
}
|
||||
|
||||
@@ -39,7 +37,7 @@ Window :: type struct {
|
||||
dc: HDC
|
||||
hwnd: HWND
|
||||
opengl_context, rc: HGLRC
|
||||
c_title: ^u8
|
||||
c_title: []u8
|
||||
}
|
||||
|
||||
make_window :: proc(title: string, msg, height: int, window_proc: WNDPROC) -> (Window, bool) {
|
||||
@@ -65,7 +63,7 @@ make_window :: proc(title: string, msg, height: int, window_proc: WNDPROC) -> (W
|
||||
}
|
||||
|
||||
w.hwnd = CreateWindowExA(0,
|
||||
c_class_name, w.c_title,
|
||||
c_class_name, ^w.c_title[0],
|
||||
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
w.width as i32, w.height as i32,
|
||||
@@ -114,7 +112,7 @@ make_window :: proc(title: string, msg, height: int, window_proc: WNDPROC) -> (W
|
||||
}
|
||||
|
||||
destroy_window :: proc(w: ^Window) {
|
||||
heap_free(w.c_title)
|
||||
delete(w.c_title)
|
||||
}
|
||||
|
||||
display_window :: proc(w: ^Window) {
|
||||
|
||||
+29
-15
@@ -1,15 +1,25 @@
|
||||
#load "win32.odin"
|
||||
|
||||
debug_trap :: proc() #foreign "llvm.debugtrap"
|
||||
assume :: proc(cond: bool) #foreign "llvm.assume"
|
||||
|
||||
__debug_trap :: proc() #foreign "llvm.debugtrap"
|
||||
__trap :: proc() #foreign "llvm.trap"
|
||||
read_cycle_counter :: proc() -> u64 #foreign "llvm.readcyclecounter"
|
||||
|
||||
bit_reverse16 :: proc(b: u16) -> u16 #foreign "llvm.bitreverse.i16"
|
||||
bit_reverse32 :: proc(b: u32) -> u32 #foreign "llvm.bitreverse.i32"
|
||||
bit_reverse64 :: proc(b: u64) -> u64 #foreign "llvm.bitreverse.i64"
|
||||
|
||||
byte_swap16 :: proc(b: u16) -> u16 #foreign "llvm.bswap.i16"
|
||||
byte_swap32 :: proc(b: u32) -> u32 #foreign "llvm.bswap.i32"
|
||||
byte_swap64 :: proc(b: u64) -> u64 #foreign "llvm.bswap.i64"
|
||||
|
||||
fmuladd_f32 :: proc(a, b, c: f32) -> f32 #foreign "llvm.fmuladd.f32"
|
||||
fmuladd_f64 :: proc(a, b, c: f64) -> f64 #foreign "llvm.fmuladd.f64"
|
||||
|
||||
// TODO(bill): make custom heap procedures
|
||||
heap_alloc :: proc(len: int) -> rawptr {
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len)
|
||||
}
|
||||
heap_free :: proc(ptr: rawptr) {
|
||||
_ = HeapFree(GetProcessHeap(), 0, ptr)
|
||||
}
|
||||
|
||||
heap_alloc :: proc(len: int) -> rawptr #foreign "malloc"
|
||||
heap_dealloc :: proc(ptr: rawptr) #foreign "free"
|
||||
|
||||
memory_zero :: proc(data: rawptr, len: int) {
|
||||
d := slice_ptr(data as ^byte, len)
|
||||
@@ -288,10 +298,10 @@ Allocator :: type struct {
|
||||
|
||||
|
||||
Context :: type struct {
|
||||
thread_id: int
|
||||
thread_ptr: rawptr
|
||||
|
||||
user_index: int
|
||||
user_data: rawptr
|
||||
user_index: int
|
||||
|
||||
allocator: Allocator
|
||||
}
|
||||
@@ -305,6 +315,10 @@ __check_context :: proc() {
|
||||
if context.allocator.procedure == null {
|
||||
context.allocator = __default_allocator()
|
||||
}
|
||||
if context.thread_ptr == null {
|
||||
// TODO(bill):
|
||||
// context.thread_ptr = current_thread_pointer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -368,13 +382,11 @@ __default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocation_Mode,
|
||||
using Allocation_Mode
|
||||
match mode {
|
||||
case ALLOC:
|
||||
data := heap_alloc(size)
|
||||
memory_zero(data, size)
|
||||
return data
|
||||
return heap_alloc(size)
|
||||
case RESIZE:
|
||||
return default_resize_align(old_memory, old_size, size, alignment)
|
||||
case DEALLOC:
|
||||
heap_free(old_memory)
|
||||
heap_dealloc(old_memory)
|
||||
case DEALLOC_ALL:
|
||||
// NOTE(bill): Does nothing
|
||||
}
|
||||
@@ -394,5 +406,7 @@ __default_allocator :: proc() -> Allocator {
|
||||
|
||||
__assert :: proc(msg: string) {
|
||||
file_write(file_get_standard(File_Standard.ERROR), msg as []byte)
|
||||
debug_trap()
|
||||
// TODO(bill): Which is better?
|
||||
// __trap()
|
||||
__debug_trap()
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
}
|
||||
|
||||
if (are_strings_equal(name, original_name)) {
|
||||
#if 0
|
||||
Scope *scope = *map_get(&info->scopes, hash_pointer(pd->type));
|
||||
isize count = multi_map_count(&scope->elements, hash_string(original_name));
|
||||
if (count > 1) {
|
||||
@@ -127,6 +128,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(name), e->guid);
|
||||
name = make_string(name_text, name_len-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, name);
|
||||
@@ -208,5 +210,9 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
|
||||
|
||||
void ssa_gen_ir(ssaGen *s) {
|
||||
ssa_print_llvm_ir(&s->output_file, &s->module);
|
||||
ssaFileBuffer buf = {};
|
||||
ssa_file_buffer_init(&buf, &s->output_file);
|
||||
defer (ssa_file_buffer_destroy(&buf));
|
||||
|
||||
ssa_print_llvm_ir(&buf, &s->module);
|
||||
}
|
||||
|
||||
+73
-32
@@ -1,20 +1,53 @@
|
||||
#define SSA_PRINT_TO_STDOUT 0
|
||||
struct ssaFileBuffer {
|
||||
gbVirtualMemory vm;
|
||||
isize offset;
|
||||
gbFile *output;
|
||||
};
|
||||
|
||||
void ssa_fprintf(gbFile *f, char *fmt, ...) {
|
||||
void ssa_file_buffer_init(ssaFileBuffer *f, gbFile *output) {
|
||||
isize size = 8*gb_virtual_memory_page_size(NULL);
|
||||
f->vm = gb_vm_alloc(NULL, size);
|
||||
f->offset = 0;
|
||||
f->output = output;
|
||||
}
|
||||
|
||||
void ssa_file_buffer_destroy(ssaFileBuffer *f) {
|
||||
if (f->offset > 0) {
|
||||
// NOTE(bill): finish writing buffered data
|
||||
gb_file_write(f->output, f->vm.data, f->offset);
|
||||
}
|
||||
|
||||
gb_vm_free(f->vm);
|
||||
}
|
||||
|
||||
void ssa_file_buffer_write(ssaFileBuffer *f, void *data, isize len) {
|
||||
if (len > f->vm.size) {
|
||||
gb_file_write(f->output, data, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((f->vm.size - f->offset) < len) {
|
||||
gb_file_write(f->output, f->vm.data, f->offset);
|
||||
f->offset = 0;
|
||||
}
|
||||
u8 *cursor = cast(u8 *)f->vm.data + f->offset;
|
||||
gb_memcopy(cursor, data, len);
|
||||
f->offset += len;
|
||||
}
|
||||
|
||||
|
||||
void ssa_fprintf(ssaFileBuffer *f, char *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
gb_fprintf_va(f, fmt, va);
|
||||
#if SSA_PRINT_TO_STDOUT
|
||||
gb_printf_va(fmt, va);
|
||||
#endif
|
||||
char buf[4096] = {};
|
||||
isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va);
|
||||
ssa_file_buffer_write(f, buf, len-1);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void ssa_file_write(gbFile *f, void *data, isize len) {
|
||||
gb_file_write(f, data, len);
|
||||
#if SSA_PRINT_TO_STDOUT
|
||||
gb_file_write(gb_file_get_standard(gbFileStandard_Output), data, len);
|
||||
#endif
|
||||
|
||||
void ssa_file_write(ssaFileBuffer *f, void *data, isize len) {
|
||||
ssa_file_buffer_write(f, data, len);
|
||||
}
|
||||
|
||||
b32 ssa_valid_char(u8 c) {
|
||||
@@ -35,7 +68,7 @@ b32 ssa_valid_char(u8 c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ssa_print_escape_string(gbFile *f, String name, b32 print_quotes) {
|
||||
void ssa_print_escape_string(ssaFileBuffer *f, String name, b32 print_quotes) {
|
||||
isize extra = 0;
|
||||
for (isize i = 0; i < name.len; i++) {
|
||||
u8 c = name.text[i];
|
||||
@@ -81,18 +114,21 @@ void ssa_print_escape_string(gbFile *f, String name, b32 print_quotes) {
|
||||
|
||||
|
||||
|
||||
void ssa_print_encoded_local(gbFile *f, String name) {
|
||||
void ssa_print_encoded_local(ssaFileBuffer *f, String name) {
|
||||
ssa_fprintf(f, "%%");
|
||||
ssa_print_escape_string(f, name, true);
|
||||
}
|
||||
|
||||
void ssa_print_encoded_global(gbFile *f, String name) {
|
||||
void ssa_print_encoded_global(ssaFileBuffer *f, String name, b32 global_scope = false) {
|
||||
ssa_fprintf(f, "@");
|
||||
if (!global_scope) {
|
||||
ssa_fprintf(f, ".");
|
||||
}
|
||||
ssa_print_escape_string(f, name, true);
|
||||
}
|
||||
|
||||
|
||||
void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
|
||||
void ssa_print_type(ssaFileBuffer *f, BaseTypeSizes s, Type *t) {
|
||||
i64 word_bits = 8*s.word_size;
|
||||
GB_ASSERT_NOT_NULL(t);
|
||||
t = default_type(t);
|
||||
@@ -113,8 +149,8 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
|
||||
case Basic_u128: ssa_fprintf(f, "u128"); break;
|
||||
case Basic_f32: ssa_fprintf(f, "float"); break;
|
||||
case Basic_f64: ssa_fprintf(f, "double"); break;
|
||||
case Basic_rawptr: ssa_fprintf(f, "%%.rawptr"); break;
|
||||
case Basic_string: ssa_fprintf(f, "%%.string"); break;
|
||||
case Basic_rawptr: ssa_fprintf(f, "%%..rawptr"); break;
|
||||
case Basic_string: ssa_fprintf(f, "%%..string"); break;
|
||||
case Basic_uint: ssa_fprintf(f, "i%lld", word_bits); break;
|
||||
case Basic_int: ssa_fprintf(f, "i%lld", word_bits); break;
|
||||
}
|
||||
@@ -213,7 +249,7 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) {
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type) {
|
||||
void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type) {
|
||||
type = get_base_type(type);
|
||||
if (is_type_float(type)) {
|
||||
value = exact_value_to_float(value);
|
||||
@@ -276,12 +312,12 @@ void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_print_block_name(gbFile *f, ssaBlock *b) {
|
||||
void ssa_print_block_name(ssaFileBuffer *f, ssaBlock *b) {
|
||||
ssa_print_escape_string(f, b->label, false);
|
||||
ssa_fprintf(f, "..%d", b->id);
|
||||
}
|
||||
|
||||
void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint) {
|
||||
void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type_hint) {
|
||||
if (value == NULL) {
|
||||
ssa_fprintf(f, "!!!NULL_VALUE");
|
||||
return;
|
||||
@@ -300,7 +336,7 @@ void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint)
|
||||
ssa_print_encoded_local(f, value->Param.entity->token.string);
|
||||
break;
|
||||
case ssaValue_Proc:
|
||||
ssa_print_encoded_global(f, value->Proc.name);
|
||||
ssa_print_encoded_global(f, value->Proc.name, (value->Proc.tags & ProcTag_foreign) != 0);
|
||||
break;
|
||||
case ssaValue_Instr:
|
||||
ssa_fprintf(f, "%%%d", value->id);
|
||||
@@ -308,7 +344,7 @@ void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint)
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
GB_ASSERT(value->kind == ssaValue_Instr);
|
||||
ssaInstr *instr = &value->Instr;
|
||||
|
||||
@@ -316,7 +352,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
|
||||
switch (instr->kind) {
|
||||
case ssaInstr_StartupRuntime: {
|
||||
ssa_fprintf(f, "call void @" SSA_STARTUP_RUNTIME_PROC_NAME "()\n");
|
||||
ssa_fprintf(f, "call void @." SSA_STARTUP_RUNTIME_PROC_NAME "()\n");
|
||||
} break;
|
||||
|
||||
case ssaInstr_Comment:
|
||||
@@ -471,7 +507,9 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
case Token_GtEq: runtime_proc = "__string_gt"; break;
|
||||
}
|
||||
|
||||
ssa_fprintf(f, " @%s(", runtime_proc);
|
||||
ssa_fprintf(f, " ");
|
||||
ssa_print_encoded_global(f, make_string(runtime_proc), false);
|
||||
ssa_fprintf(f, "(");
|
||||
ssa_print_type(f, m->sizes, type);
|
||||
ssa_fprintf(f, " ");
|
||||
ssa_print_value(f, m, bo->left, type);
|
||||
@@ -605,7 +643,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_MemCopy: {
|
||||
ssa_fprintf(f, "call void @memory_move");
|
||||
ssa_fprintf(f, "call void @.memory_move");
|
||||
ssa_fprintf(f, "(i8* ");
|
||||
ssa_print_value(f, m, instr->CopyMemory.dst, t_rawptr);
|
||||
ssa_fprintf(f, ", i8* ");
|
||||
@@ -689,7 +727,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
|
||||
void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||
if (proc->body == NULL) {
|
||||
ssa_fprintf(f, "\ndeclare ");
|
||||
} else {
|
||||
@@ -705,8 +743,11 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
|
||||
}
|
||||
|
||||
ssa_fprintf(f, " ");
|
||||
|
||||
ssa_print_encoded_global(f, proc->name);
|
||||
if (are_strings_equal(proc->name, make_string("main"))) {
|
||||
ssa_print_encoded_global(f, proc->name, true);
|
||||
} else {
|
||||
ssa_print_encoded_global(f, proc->name, (proc->tags & ProcTag_foreign) != 0);
|
||||
}
|
||||
ssa_fprintf(f, "(");
|
||||
|
||||
if (proc_type->param_count > 0) {
|
||||
@@ -760,7 +801,7 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_print_type_name(gbFile *f, ssaModule *m, ssaValue *v) {
|
||||
void ssa_print_type_name(ssaFileBuffer *f, ssaModule *m, ssaValue *v) {
|
||||
GB_ASSERT(v->kind == ssaValue_TypeName);
|
||||
Type *base_type = get_base_type(ssa_type(v));
|
||||
if (!is_type_struct(base_type) && !is_type_union(base_type)) {
|
||||
@@ -772,17 +813,17 @@ void ssa_print_type_name(gbFile *f, ssaModule *m, ssaValue *v) {
|
||||
ssa_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
void ssa_print_llvm_ir(gbFile *f, ssaModule *m) {
|
||||
void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) {
|
||||
if (m->layout.len > 0) {
|
||||
ssa_fprintf(f, "target datalayout = \"%.*s\"\n", LIT(m->layout));
|
||||
}
|
||||
|
||||
ssa_print_encoded_local(f, make_string(".string"));
|
||||
ssa_print_encoded_local(f, make_string("..string"));
|
||||
ssa_fprintf(f, " = type {i8*, ");
|
||||
ssa_print_type(f, m->sizes, t_int);
|
||||
ssa_fprintf(f, "} ; Basic_string\n");
|
||||
|
||||
ssa_print_encoded_local(f, make_string(".rawptr"));
|
||||
ssa_print_encoded_local(f, make_string("..rawptr"));
|
||||
ssa_fprintf(f, " = type i8* ; Basic_rawptr\n\n");
|
||||
|
||||
gb_for_array(member_index, m->members.entries) {
|
||||
|
||||
+10
-5
@@ -742,9 +742,10 @@ ssaValue *ssa_emit_call(ssaProcedure *p, ssaValue *value, ssaValue **args, isize
|
||||
return ssa_emit(p, ssa_make_instr_call(p, value, args, arg_count, results));
|
||||
}
|
||||
|
||||
ssaValue *ssa_emit_global_call(ssaProcedure *proc, char *name, ssaValue **args, isize arg_count) {
|
||||
ssaValue **found = map_get(&proc->module->members, hash_string(make_string(name)));
|
||||
GB_ASSERT_MSG(found != NULL, "%s", name);
|
||||
ssaValue *ssa_emit_global_call(ssaProcedure *proc, char *name_, ssaValue **args, isize arg_count) {
|
||||
String name = make_string(name_);
|
||||
ssaValue **found = map_get(&proc->module->members, hash_string(name));
|
||||
GB_ASSERT_MSG(found != NULL, "%.*s", LIT(name));
|
||||
ssaValue *gp = *found;
|
||||
return ssa_emit_call(proc, gp, args, arg_count);
|
||||
}
|
||||
@@ -1229,7 +1230,7 @@ ssaValue *ssa_add_global_string_array(ssaProcedure *proc, ExactValue value) {
|
||||
|
||||
isize max_len = 4+8+1;
|
||||
u8 *str = cast(u8 *)gb_alloc_array(a, u8, max_len);
|
||||
isize len = gb_snprintf(cast(char *)str, max_len, ".str%x", proc->module->global_string_index);
|
||||
isize len = gb_snprintf(cast(char *)str, max_len, "__str$%x", proc->module->global_string_index);
|
||||
proc->module->global_string_index++;
|
||||
|
||||
String name = make_string(str, len-1);
|
||||
@@ -1238,7 +1239,8 @@ ssaValue *ssa_add_global_string_array(ssaProcedure *proc, ExactValue value) {
|
||||
Type *type = make_type_array(a, t_u8, value.value_string.len);
|
||||
Entity *entity = make_entity_constant(a, NULL, token, type, value);
|
||||
ssaValue *g = ssa_make_value_global(a, entity, ssa_make_value_constant(a, type, value));
|
||||
g->Global.is_private = true;
|
||||
g->Global.is_private = true;
|
||||
g->Global.is_constant = true;
|
||||
|
||||
map_set(&proc->module->values, hash_pointer(entity), g);
|
||||
map_set(&proc->module->members, hash_string(name), g);
|
||||
@@ -2780,6 +2782,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
|
||||
Entity *f = *map_get(&info->foreign_procs, hash_string(name));
|
||||
ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
|
||||
proc->module, e->type, pd->type, pd->body, name);
|
||||
|
||||
value->Proc.tags = pd->tags;
|
||||
|
||||
ssa_module_add_value(proc->module, e, value);
|
||||
ssa_build_proc(value, proc);
|
||||
if (e == f) {
|
||||
|
||||
+40
-27
@@ -40,14 +40,29 @@ i32 win32_exec_command_line_app(char *fmt, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define INIT_TIMER() u64 start_time, end_time = 0, total_time = 0; start_time = gb_utc_time_now()
|
||||
#define PRINT_TIMER(section) do { \
|
||||
u64 diff; \
|
||||
end_time = gb_utc_time_now(); \
|
||||
diff = end_time - start_time; \
|
||||
total_time += diff; \
|
||||
gb_printf_err("%s: %lld ms\n", section, diff/1000); \
|
||||
start_time = gb_utc_time_now(); \
|
||||
} while (0)
|
||||
|
||||
#define PRINT_ACCUMULATION() do { \
|
||||
gb_printf_err("Total compilation time: %lld ms\n", total_time/1000); \
|
||||
} while (0)
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
gb_printf_err("Please specify a .odin file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
u64 start_time, end_time;
|
||||
start_time = gb_utc_time_now();
|
||||
INIT_TIMER();
|
||||
|
||||
init_universal_scope();
|
||||
|
||||
@@ -67,9 +82,7 @@ int main(int argc, char **argv) {
|
||||
if (parse_files(&parser, init_filename) != ParseFile_None)
|
||||
return 1;
|
||||
|
||||
end_time = gb_utc_time_now();
|
||||
gb_printf_err("Parser: %lld ms\n", (end_time - start_time)/1000);
|
||||
start_time = gb_utc_time_now();
|
||||
PRINT_TIMER("Syntax Parser");
|
||||
|
||||
// print_ast(parser.files[0].decls, 0);
|
||||
|
||||
@@ -81,9 +94,7 @@ int main(int argc, char **argv) {
|
||||
check_parsed_files(&checker);
|
||||
|
||||
|
||||
// end_time = gb_utc_time_now();
|
||||
// gb_printf_err("Checker: %lld ms\n", (end_time - start_time)/1000);
|
||||
// start_time = gb_utc_time_now();
|
||||
PRINT_TIMER("Semantic Checker");
|
||||
|
||||
#if 1
|
||||
ssaGen ssa = {};
|
||||
@@ -93,17 +104,12 @@ int main(int argc, char **argv) {
|
||||
|
||||
ssa_gen_tree(&ssa);
|
||||
|
||||
// end_time = gb_utc_time_now();
|
||||
// gb_printf_err("ssa tree: %lld ms\n", (end_time - start_time)/1000);
|
||||
// start_time = gb_utc_time_now();
|
||||
PRINT_TIMER("SSA Tree");
|
||||
|
||||
// TODO(bill): Speedup writing to file for IR code
|
||||
ssa_gen_ir(&ssa);
|
||||
|
||||
// end_time = gb_utc_time_now();
|
||||
// gb_printf_err("ssa ir: %lld ms\n", (end_time - start_time)/1000);
|
||||
// start_time = gb_utc_time_now();
|
||||
|
||||
PRINT_TIMER("SSA IR");
|
||||
|
||||
char const *output_name = ssa.output_file.filename;
|
||||
isize base_name_len = gb_path_extension(output_name)-1 - output_name;
|
||||
@@ -112,16 +118,23 @@ int main(int argc, char **argv) {
|
||||
|
||||
i32 exit_code = 0;
|
||||
exit_code = win32_exec_command_line_app(
|
||||
"../misc/llvm-bin/opt -mem2reg %s -o %.*s.bc",
|
||||
"../misc/llvm-bin/opt %s -o %.*s.bc "
|
||||
"-memcpyopt "
|
||||
"-mem2reg "
|
||||
"-die -dse "
|
||||
"-dce "
|
||||
// "-S "
|
||||
// "-debug-pass=Arguments "
|
||||
"",
|
||||
output_name, cast(int)base_name_len, output_name);
|
||||
if (exit_code != 0)
|
||||
return exit_code;
|
||||
|
||||
// end_time = gb_utc_time_now();
|
||||
// gb_printf_err("llvm-opt: %lld ms\n", (end_time - start_time)/1000);
|
||||
// start_time = gb_utc_time_now();
|
||||
PRINT_TIMER("llvm-opt");
|
||||
|
||||
#if 1
|
||||
gbString lib_str = gb_string_make(gb_heap_allocator(), "-lKernel32.lib");
|
||||
defer (gb_string_free(lib_str));
|
||||
char lib_str_buf[1024] = {};
|
||||
gb_for_array(i, parser.system_libraries) {
|
||||
String lib = parser.system_libraries[i];
|
||||
@@ -130,26 +143,26 @@ int main(int argc, char **argv) {
|
||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||
}
|
||||
|
||||
|
||||
exit_code = win32_exec_command_line_app(
|
||||
"clang -o %.*s.exe %.*s.bc "
|
||||
"clang %.*s.bc -o %.*s.o "
|
||||
"-O0 "
|
||||
"-Wno-override-module "
|
||||
// "-nostartfiles "
|
||||
"%s "
|
||||
,
|
||||
"%s",
|
||||
cast(int)base_name_len, output_name,
|
||||
cast(int)base_name_len, output_name,
|
||||
lib_str);
|
||||
gb_string_free(lib_str);
|
||||
|
||||
if (exit_code != 0)
|
||||
return exit_code;
|
||||
|
||||
// end_time = gb_utc_time_now();
|
||||
// gb_printf_err("clang: %lld ms\n\n\n", (end_time - start_time)/1000);
|
||||
PRINT_TIMER("clang-compiler");
|
||||
|
||||
PRINT_ACCUMULATION();
|
||||
|
||||
if (run_output) {
|
||||
win32_exec_command_line_app("%.*s.exe", cast(int)base_name_len, output_name);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -33,6 +33,7 @@ struct AstFile {
|
||||
|
||||
ErrorCollector error_collector;
|
||||
|
||||
// TODO(bill): Error recovery
|
||||
// NOTE(bill): Error recovery
|
||||
#define PARSER_MAX_FIX_COUNT 6
|
||||
isize fix_count;
|
||||
|
||||
Reference in New Issue
Block a user