diff --git a/core/os/file_windows.odin b/core/os/file_windows.odin index deddc40d4..54f1a9526 100644 --- a/core/os/file_windows.odin +++ b/core/os/file_windows.odin @@ -64,6 +64,13 @@ close :: proc(fd: Handle) -> Errno { return ERROR_NONE; } +flush :: proc(fd: Handle) -> (err: Errno) { + if !win32.FlushFileBuffers(win32.HANDLE(fd)) { + err = Errno(win32.GetLastError()); + } + return; +} + write :: proc(fd: Handle, data: []byte) -> (int, Errno) { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0429ca307..2f425fe71 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -137,6 +137,7 @@ struct BuildContext { String llc_flags; String link_flags; String extra_linker_flags; + String microarch; BuildModeKind build_mode; bool generate_docs; i32 optimization_level; @@ -706,7 +707,9 @@ void init_build_context(TargetMetrics *cross_target) { // across OSs. It doesn't make sense to allocate extra data on the heap // here, so I just #defined the linker flags to keep things concise. if (bc->metrics.arch == TargetArch_amd64) { - llc_flags = gb_string_appendc(llc_flags, "-march=x86-64 "); + if (bc->microarch.len == 0) { + llc_flags = gb_string_appendc(llc_flags, "-march=x86-64 "); + } switch (bc->metrics.os) { case TargetOs_windows: @@ -718,11 +721,13 @@ void init_build_context(TargetMetrics *cross_target) { bc->link_flags = str_lit("-arch x86-64 "); break; case TargetOs_freebsd: - bc->link_flags = str_lit("-arch x86-64"); + bc->link_flags = str_lit("-arch x86-64 "); break; } } else if (bc->metrics.arch == TargetArch_386) { - llc_flags = gb_string_appendc(llc_flags, "-march=x86 "); + if (bc->microarch.len == 0) { + llc_flags = gb_string_appendc(llc_flags, "-march=x86 "); + } switch (bc->metrics.os) { case TargetOs_windows: @@ -736,7 +741,7 @@ void init_build_context(TargetMetrics *cross_target) { bc->link_flags = str_lit("-arch x86 "); break; case TargetOs_freebsd: - bc->link_flags = str_lit("-arch x86"); + bc->link_flags = str_lit("-arch x86 "); break; } } else if (bc->metrics.arch == TargetArch_wasm32) { @@ -745,11 +750,25 @@ void init_build_context(TargetMetrics *cross_target) { gb_printf_err("Compiler Error: Unsupported architecture\n");; gb_exit(1); } + llc_flags = gb_string_appendc(llc_flags, " "); bc->optimization_level = gb_clamp(bc->optimization_level, 0, 3); gbString opt_flags = gb_string_make_reserve(heap_allocator(), 64); + + + if (bc->microarch.len != 0) { + opt_flags = gb_string_appendc(opt_flags, "-march="); + opt_flags = gb_string_append_length(opt_flags, bc->microarch.text, bc->microarch.len); + opt_flags = gb_string_appendc(opt_flags, " "); + + // llc_flags = gb_string_appendc(opt_flags, "-march="); + // llc_flags = gb_string_append_length(llc_flags, bc->microarch.text, bc->microarch.len); + // llc_flags = gb_string_appendc(llc_flags, " "); + } + + if (bc->optimization_level != 0) { opt_flags = gb_string_append_fmt(opt_flags, "-O%d ", bc->optimization_level); // NOTE(lachsinc): The following options were previously passed during call @@ -761,7 +780,9 @@ void init_build_context(TargetMetrics *cross_target) { opt_flags = gb_string_appendc(opt_flags, "-mem2reg -memcpyopt -die "); } - bc->llc_flags = make_string_c(llc_flags); + + + // NOTE(lachsinc): This optimization option was previously required to get @@ -772,6 +793,7 @@ void init_build_context(TargetMetrics *cross_target) { // } bc->opt_flags = make_string_c(opt_flags); + bc->llc_flags = make_string_c(llc_flags); #undef LINK_FLAG_X64 diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index e2259cefb..921f996f6 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -11858,7 +11858,21 @@ void lb_generate_code(lbGenerator *gen) { code_mode = LLVMCodeModelJITDefault; } - LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(target, target_triple, "generic", "", LLVMCodeGenLevelNone, LLVMRelocDefault, code_mode); + char const *host_cpu_name = LLVMGetHostCPUName(); + char const *llvm_cpu = "generic"; + char const *llvm_features = ""; + if (build_context.microarch.len != 0) { + if (build_context.microarch == "native") { + llvm_cpu = host_cpu_name; + } else { + llvm_cpu = alloc_cstring(heap_allocator(), build_context.microarch); + } + if (gb_strcmp(llvm_cpu, host_cpu_name) == 0) { + llvm_features = LLVMGetHostCPUFeatures(); + } + } + + LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(target, target_triple, llvm_cpu, llvm_features, LLVMCodeGenLevelNone, LLVMRelocDefault, code_mode); defer (LLVMDisposeTargetMachine(target_machine)); LLVMSetModuleDataLayout(mod, LLVMCreateTargetDataLayout(target_machine)); @@ -12424,6 +12438,7 @@ void lb_generate_code(lbGenerator *gen) { defer (LLVMDisposePassManager(module_pass_manager)); LLVMAddAlwaysInlinerPass(module_pass_manager); LLVMAddStripDeadPrototypesPass(module_pass_manager); + LLVMAddAnalysisPasses(target_machine, module_pass_manager); // if (build_context.optimization_level >= 2) { // LLVMAddArgumentPromotionPass(module_pass_manager); // LLVMAddConstantMergePass(module_pass_manager); diff --git a/src/main.cpp b/src/main.cpp index b15518d6e..64da5b5b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -583,8 +583,9 @@ enum BuildFlagKind { BuildFlag_UseLLVMApi, BuildFlag_IgnoreUnknownAttributes, BuildFlag_ExtraLinkerFlags, - BuildFlag_DisallowDo, + BuildFlag_Microarch, + BuildFlag_DisallowDo, BuildFlag_DefaultToNilAllocator, BuildFlag_Compact, @@ -681,9 +682,10 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String); + add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String); + add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_Compact, str_lit("compact"), BuildFlagParam_None); @@ -1109,6 +1111,12 @@ bool parse_build_flags(Array args) { build_context.extra_linker_flags = value.value_string; break; + case BuildFlag_Microarch: + GB_ASSERT(value.kind == ExactValue_String); + build_context.microarch = value.value_string; + string_to_lower(&build_context.microarch); + break; + case BuildFlag_DisallowDo: build_context.disallow_do = true; break; diff --git a/src/string.cpp b/src/string.cpp index fcf271d67..6a0192507 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -125,6 +125,12 @@ gb_inline bool str_eq_ignore_case(String const &a, String const &b) { return false; } +void string_to_lower(String *s) { + for (isize i = 0; i < s->len; i++) { + s->text[i] = gb_char_to_lower(s->text[i]); + } +} + int string_compare(String const &x, String const &y) { if (x.len != y.len || x.text != y.text) { isize n, fast, offset, curr_block;