diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 5df8b3d..5d26db2 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -53,7 +53,8 @@ jobs: run: | set -eux mkdir -p $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD) - cp $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/Release/cache/debug_none_di/compiler/aggressively_optimize_for_speed_nodi/compiler $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD) + cp $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/Release/cache/generic/debug_none_di/compiler/aggressively_optimize_for_speed_nodi/compiler $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_generic + cp $HOME/bloat-buster-artifacts/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/Release/cache/native/debug_none_di/compiler/aggressively_optimize_for_speed_nodi/compiler $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_native - name: Release (locally) if: ${{ (github.ref == 'refs/heads/main') }} shell: bash @@ -61,8 +62,8 @@ jobs: BB_CI: 1 run: | set -eux - cp $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler $HOME/bloat-buster-artifacts/releases/main/ - + cp $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_generic $HOME/bloat-buster-artifacts/releases/main/ + cp $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD)/compiler_native $HOME/bloat-buster-artifacts/releases/main/ - name: Release (web) uses: akkuman/gitea-release-action@v1 if: ${{ (github.ref == 'refs/heads/main') }} @@ -70,4 +71,5 @@ jobs: NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18 with: files: |- - /home/act_runner/bloat-buster-artifacts/releases/main/compiler + /home/act_runner/bloat-buster-artifacts/releases/main/compiler_generic + /home/act_runner/bloat-buster-artifacts/releases/main/compiler_native diff --git a/src/compiler.bbb b/src/compiler.bbb index 620797f..d31a008 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -1012,6 +1012,7 @@ CompileFile = struct relative_file_path: []u8, build_mode: BuildMode, has_debug_info: u1, + host_cpu_model: u1, silent: u1, } @@ -1031,11 +1032,16 @@ Target = struct { cpu: CPUArchitecture, os: OperatingSystem, + host_cpu_model: u1, } -target_get_native = fn () Target +target_get_native = fn (host_cpu_model: u1) Target { - return { .cpu = .x86_64, .os = .linux }; + return { + .cpu = .x86_64, + .os = .linux, + .host_cpu_model = host_cpu_model, + }; } target_compare = fn (a: Target, b: Target) u1 @@ -12704,6 +12710,16 @@ enter_struct_pointer_for_coerced_access = fn (module: &Module, source_value: &LL } } +coerce_integer_or_pointer_to_integer_or_pointer = fn (module: &Module, source: &LLVMValue, source_type: &Type, destination_type: &Type) &LLVMValue +{ + if (source_type != destination_type) + { + #trap(); + } + + return source; +} + create_coerced_store = fn (module: &Module, source_value: &LLVMValue, source_type: &Type, destination_value: &LLVMValue, destination_type: &Type, destination_size: u64, destination_volatile: u1) void { >source_size = get_byte_size(source_type); @@ -12758,7 +12774,14 @@ create_coerced_store = fn (module: &Module, source_value: &LLVMValue, source_typ } else if (type_is_integer_backing(source_type)) { - #trap(); + >int_type = integer_type(module, { .bit_count = destination_size * 8, .signed = 0 }); + >value = coerce_integer_or_pointer_to_integer_or_pointer(module, source_value, source_type, int_type); + create_store(module, { + .source = value, + .destination = destination_value, + .type = int_type, + zero, + }); } else { @@ -12786,11 +12809,6 @@ create_coerced_store = fn (module: &Module, source_value: &LLVMValue, source_typ } } -coerce_integer_or_pointer_to_integer_or_pointer = fn (module: &Module, source: &LLVMValue, source_type: &Type, destination_type: &Type) &LLVMValue -{ - #trap(); -} - create_coerced_load = fn (module: &Module, source: &LLVMValue, source_type: &Type, destination_type: &Type) &LLVMValue { >result: &LLVMValue = zero; @@ -17179,11 +17197,20 @@ emit = fn (module: &Module) void >cpu_model: &u8 = zero; >cpu_features: &u8 = zero; - if (target_compare(module.target, target_get_native())) + if (target_compare(module.target, target_get_native(module.target.host_cpu_model))) { target_triple = host_target_triple; - cpu_model = host_cpu_model; - cpu_features = host_cpu_features; + + if (module.target.host_cpu_model) + { + cpu_model = host_cpu_model; + cpu_features = host_cpu_features; + } + else + { + cpu_model = "generic"; + cpu_features = ""; + } } else { @@ -18273,30 +18300,45 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile, envp: &&u8) []u8 >base_name = relative_file_path[base_start..extension_start]; >is_compiler = string_equal(relative_file_path, "src/compiler.bbb"); + + os_make_directory(base_cache_dir.pointer); + >base_dir = arena_join_string(arena, [ base_cache_dir, "/", - #enum_name(#build_mode), - "_", - #select(#has_debug_info(), "di", "nodi"), - ][..]); - >outputh_path_dir = arena_join_string(arena, [ - base_dir, - #select(is_compiler, "/compiler/", "/"), - #enum_name(compile_options.build_mode), - "_", - #select(compile_options.has_debug_info, "di", "nodi"), + #select(compile_options.host_cpu_model, "native", "generic"), + ][..]); + + os_make_directory(base_dir.pointer); + + base_dir = arena_join_string(arena, [ + base_dir, + "/", + #enum_name(#build_mode), + "_", + #select(#has_debug_info(), "di", "nodi"), ][..]); - os_make_directory(base_cache_dir.pointer); os_make_directory(base_dir.pointer); if (is_compiler) { - >compiler_dir = arena_join_string(arena, [ base_dir, "/compiler" ][..]); - os_make_directory(compiler_dir.pointer); + base_dir = arena_join_string(arena, [ + base_dir, + "/compiler", + ][..]); + + os_make_directory(base_dir.pointer); } + >outputh_path_dir = arena_join_string(arena, [ + base_dir, + "/", + #enum_name(compile_options.build_mode), + "_", + #select(compile_options.has_debug_info, "di", "nodi"), + ][..]); + os_make_directory(outputh_path_dir.pointer); >outputh_path_base = arena_join_string(arena, [ outputh_path_dir, "/", base_name ][..]); @@ -18456,7 +18498,7 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile, envp: &&u8) []u8 .content = file_content, .path = file_path, .has_debug_info = compile_options.has_debug_info, - .target = target_get_native(), + .target = target_get_native(compile_options.host_cpu_model), .silent = compile_options.silent, }; @@ -18608,6 +18650,7 @@ names: [_][]u8 = } >debug_info_array: [_]u1 = [1, 0]; + >is_host_cpu_model_array: [_]u1 = [1, 0]; >command = command_string_to_enum.enum_value; @@ -18661,6 +18704,7 @@ names: [_][]u8 = compile_file(arena, { .relative_file_path = relative_file_path, .build_mode = build_mode, + .host_cpu_model = 0, .has_debug_info = has_debug_info, .silent = 0, }, envp); @@ -18673,6 +18717,47 @@ names: [_][]u8 = } for (name: names) + { + for (is_host_cpu_model: is_host_cpu_model_array) + { + for (build_mode: #enum_values(BuildMode)) + { + for (has_debug_info: debug_info_array) + { + >position = arena.position; + + >relative_file_path = arena_join_string(arena, [ "tests/", name, ".bbb" ][..]); + >executable_path = compile_file(arena, { + .relative_file_path = relative_file_path, + .build_mode = build_mode, + .has_debug_info = has_debug_info, + .host_cpu_model = is_host_cpu_model, + .silent = 1, + }, envp); + + >arguments: [_]&u8 = [ + executable_path.pointer, + zero, + ]; + >args = arguments[..arguments.length - 1]; + >execution = os_execute(arena, args, envp, zero); + + >success = execution.termination_kind == .exit and execution.termination_code == 0; + + if (!success) + { + #trap(); + } + + arena.position = position; + } + } + } + } + }, + .reproduce => + { + for (is_host_cpu_model: is_host_cpu_model_array) { for (build_mode: #enum_values(BuildMode)) { @@ -18680,16 +18765,20 @@ names: [_][]u8 = { >position = arena.position; - >relative_file_path = arena_join_string(arena, [ "tests/", name, ".bbb" ][..]); + // Produce the compiler + >relative_file_path = "src/compiler.bbb"; >executable_path = compile_file(arena, { - .relative_file_path = relative_file_path, - .build_mode = build_mode, - .has_debug_info = has_debug_info, - .silent = 1, - }, envp); + .relative_file_path = relative_file_path, + .host_cpu_model = is_host_cpu_model, + .build_mode = build_mode, + .has_debug_info = has_debug_info, + .silent = 1, + }, envp); + // Test the compiler >arguments: [_]&u8 = [ executable_path.pointer, + "test", zero, ]; >args = arguments[..arguments.length - 1]; @@ -18707,43 +18796,6 @@ names: [_][]u8 = } } }, - .reproduce => - { - for (build_mode: #enum_values(BuildMode)) - { - for (has_debug_info: debug_info_array) - { - >position = arena.position; - - // Produce the compiler - >relative_file_path = "src/compiler.bbb"; - >executable_path = compile_file(arena, { - .relative_file_path = relative_file_path, - .build_mode = build_mode, - .has_debug_info = has_debug_info, - .silent = 1, - }, envp); - - // Test the compiler - >arguments: [_]&u8 = [ - executable_path.pointer, - "test", - zero, - ]; - >args = arguments[..arguments.length - 1]; - >execution = os_execute(arena, args, envp, zero); - - >success = execution.termination_kind == .exit and execution.termination_code == 0; - - if (!success) - { - #trap(); - } - - arena.position = position; - } - } - }, } return 0; diff --git a/src/compiler.cpp b/src/compiler.cpp index 876235a..73076bb 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -163,22 +163,39 @@ fn String compile_file(Arena* arena, Compile options) auto is_compiler = relative_file_path.equal(string_literal("src/compiler.bbb")); - String output_path_dir_parts[] = { + make_directory(base_cache_dir); + + String cpu_dir_parts[] = { string_literal(base_cache_dir), - is_compiler ? string_literal("/compiler/") : string_literal("/"), + string_literal("/"), + options.host_cpu_model ? string_literal("native") : string_literal("generic"), + }; + + auto cpu_dir = arena_join_string(arena, array_to_slice(cpu_dir_parts)); + + make_directory(cstr(cpu_dir)); + + auto base_dir = cpu_dir; + + if (is_compiler) + { + String compiler_dir_parts[] = { + base_dir, + string_literal("/compiler"), + }; + base_dir = arena_join_string(arena, array_to_slice(compiler_dir_parts)); + make_directory(cstr(base_dir)); + } + + String output_path_dir_parts[] = { + base_dir, + string_literal("/"), build_mode_to_string(options.build_mode), string_literal("_"), options.has_debug_info ? string_literal("di") : string_literal("nodi"), }; auto output_path_dir = arena_join_string(arena, array_to_slice(output_path_dir_parts)); - make_directory(base_cache_dir); - - if (is_compiler) - { - make_directory(base_cache_dir "/compiler"); - } - make_directory(cstr(output_path_dir)); String output_path_base_parts[] = { @@ -341,6 +358,7 @@ fn String compile_file(Arena* arena, Compile options) .target = { .cpu = CPUArchitecture::x86_64, .os = OperatingSystem::linux_, + .host_cpu_model = options.host_cpu_model, }, .build_mode = options.build_mode, .has_debug_info = options.has_debug_info, @@ -583,6 +601,7 @@ void entry_point(Slice arguments, Slice envp) } bool has_debug_info_array[] = {true, false}; + bool is_host_cpu_model_array[] = {true, false}; for (auto name: names) { @@ -596,11 +615,11 @@ void entry_point(Slice arguments, Slice envp) auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts)); auto executable_path = compile_file(arena, { - .relative_file_path = relative_file_path, - .build_mode = build_mode, - .has_debug_info = has_debug_info, - .silent = true, - }); + .relative_file_path = relative_file_path, + .build_mode = build_mode, + .has_debug_info = has_debug_info, + .silent = true, + }); char* const arguments[] = { diff --git a/src/compiler.hpp b/src/compiler.hpp index 56962e0..50836dd 100644 --- a/src/compiler.hpp +++ b/src/compiler.hpp @@ -247,6 +247,7 @@ struct Target { CPUArchitecture cpu; OperatingSystem os; + bool host_cpu_model; }; fn Target target_get_native() @@ -270,6 +271,7 @@ struct Compile String relative_file_path; BuildMode build_mode; bool has_debug_info; + bool host_cpu_model; bool silent; }; diff --git a/src/emitter.cpp b/src/emitter.cpp index 48c1448..42dd043 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -416,15 +416,23 @@ fn void llvm_initialize(Module* module) module->scope.llvm = di_compile_unit; } - char* target_triple = {}; - char* cpu_model = {}; - char* cpu_features = {}; + const char* target_triple = {}; + const char* cpu_model = {}; + const char* cpu_features = {}; if (target_compare(module->target, target_get_native())) { target_triple = llvm_global.host_triple; - cpu_model = llvm_global.host_cpu_model; - cpu_features = llvm_global.host_cpu_features; + if (module->target.host_cpu_model) + { + cpu_model = llvm_global.host_cpu_model; + cpu_features = llvm_global.host_cpu_features; + } + else + { + cpu_model = "generic"; + cpu_features = ""; + } } else {