diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-09-05 18:42:42 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-09-05 18:42:42 +0100 |
| commit | 455820fc8438ab72c963ef354b9e32f6e5af1e65 (patch) | |
| tree | 60a98086357c125e6193037d24f3a4254f27af41 /src/codegen | |
| parent | ae72b3c5bd80fad917a7e2d78d9945b9f19adb52 (diff) | |
Speed up SSA generation and clang compilation
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.cpp | 8 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 105 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 15 |
3 files changed, 90 insertions, 38 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index a583af2c8..7ad1d56e2 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -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); } diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index e4e804aa1..fffdee805 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -1,20 +1,53 @@ -#define SSA_PRINT_TO_STDOUT 0 +struct ssaFileBuffer { + gbVirtualMemory vm; + isize offset; + gbFile *output; +}; + +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(gbFile *f, char *fmt, ...) { +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) { diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 50d33c366..e7d4aaf4b 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -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) { |