Introduce native-generic switch
All checks were successful
CI / ci (Release, ubuntu-latest) (pull_request) Successful in 40m47s
CI / ci (Debug, ubuntu-latest) (pull_request) Successful in 1h12m15s
CI / release (ubuntu-latest) (pull_request) Successful in 1s
CI / ci (Release, ubuntu-latest) (push) Successful in 39m47s
CI / ci (Debug, ubuntu-latest) (push) Successful in 1h9m35s
CI / release (ubuntu-latest) (push) Successful in 1s

This commit is contained in:
David Gonzalez Martin 2025-06-22 09:16:57 -06:00
parent 5e8a08d5be
commit ad79740b4d
5 changed files with 174 additions and 91 deletions

View File

@ -53,7 +53,8 @@ jobs:
run: | run: |
set -eux set -eux
mkdir -p $HOME/bloat-buster-artifacts/releases/$(git rev-parse --abbrev-ref HEAD)/$(git rev-parse HEAD) 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) - name: Release (locally)
if: ${{ (github.ref == 'refs/heads/main') }} if: ${{ (github.ref == 'refs/heads/main') }}
shell: bash shell: bash
@ -61,8 +62,8 @@ jobs:
BB_CI: 1 BB_CI: 1
run: | run: |
set -eux 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) - name: Release (web)
uses: akkuman/gitea-release-action@v1 uses: akkuman/gitea-release-action@v1
if: ${{ (github.ref == 'refs/heads/main') }} if: ${{ (github.ref == 'refs/heads/main') }}
@ -70,4 +71,5 @@ jobs:
NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18 NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18
with: with:
files: |- 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

View File

@ -1012,6 +1012,7 @@ CompileFile = struct
relative_file_path: []u8, relative_file_path: []u8,
build_mode: BuildMode, build_mode: BuildMode,
has_debug_info: u1, has_debug_info: u1,
host_cpu_model: u1,
silent: u1, silent: u1,
} }
@ -1031,11 +1032,16 @@ Target = struct
{ {
cpu: CPUArchitecture, cpu: CPUArchitecture,
os: OperatingSystem, 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 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 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); >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)) 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 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 create_coerced_load = fn (module: &Module, source: &LLVMValue, source_type: &Type, destination_type: &Type) &LLVMValue
{ {
>result: &LLVMValue = zero; >result: &LLVMValue = zero;
@ -17179,11 +17197,20 @@ emit = fn (module: &Module) void
>cpu_model: &u8 = zero; >cpu_model: &u8 = zero;
>cpu_features: &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; 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 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]; >base_name = relative_file_path[base_start..extension_start];
>is_compiler = string_equal(relative_file_path, "src/compiler.bbb"); >is_compiler = string_equal(relative_file_path, "src/compiler.bbb");
os_make_directory(base_cache_dir.pointer);
>base_dir = arena_join_string(arena, [ >base_dir = arena_join_string(arena, [
base_cache_dir, base_cache_dir,
"/", "/",
#enum_name(#build_mode), #select(compile_options.host_cpu_model, "native", "generic"),
"_", ][..]);
#select(#has_debug_info(), "di", "nodi"),
][..]); os_make_directory(base_dir.pointer);
>outputh_path_dir = arena_join_string(arena, [
base_dir, base_dir = arena_join_string(arena, [
#select(is_compiler, "/compiler/", "/"), base_dir,
#enum_name(compile_options.build_mode), "/",
"_", #enum_name(#build_mode),
#select(compile_options.has_debug_info, "di", "nodi"), "_",
#select(#has_debug_info(), "di", "nodi"),
][..]); ][..]);
os_make_directory(base_cache_dir.pointer);
os_make_directory(base_dir.pointer); os_make_directory(base_dir.pointer);
if (is_compiler) if (is_compiler)
{ {
>compiler_dir = arena_join_string(arena, [ base_dir, "/compiler" ][..]); base_dir = arena_join_string(arena, [
os_make_directory(compiler_dir.pointer); 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); os_make_directory(outputh_path_dir.pointer);
>outputh_path_base = arena_join_string(arena, [ outputh_path_dir, "/", base_name ][..]); >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, .content = file_content,
.path = file_path, .path = file_path,
.has_debug_info = compile_options.has_debug_info, .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, .silent = compile_options.silent,
}; };
@ -18608,6 +18650,7 @@ names: [_][]u8 =
} }
>debug_info_array: [_]u1 = [1, 0]; >debug_info_array: [_]u1 = [1, 0];
>is_host_cpu_model_array: [_]u1 = [1, 0];
>command = command_string_to_enum.enum_value; >command = command_string_to_enum.enum_value;
@ -18661,6 +18704,7 @@ names: [_][]u8 =
compile_file(arena, { compile_file(arena, {
.relative_file_path = relative_file_path, .relative_file_path = relative_file_path,
.build_mode = build_mode, .build_mode = build_mode,
.host_cpu_model = 0,
.has_debug_info = has_debug_info, .has_debug_info = has_debug_info,
.silent = 0, .silent = 0,
}, envp); }, envp);
@ -18673,6 +18717,47 @@ names: [_][]u8 =
} }
for (name: names) 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)) for (build_mode: #enum_values(BuildMode))
{ {
@ -18680,16 +18765,20 @@ names: [_][]u8 =
{ {
>position = arena.position; >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, { >executable_path = compile_file(arena, {
.relative_file_path = relative_file_path, .relative_file_path = relative_file_path,
.build_mode = build_mode, .host_cpu_model = is_host_cpu_model,
.has_debug_info = has_debug_info, .build_mode = build_mode,
.silent = 1, .has_debug_info = has_debug_info,
}, envp); .silent = 1,
}, envp);
// Test the compiler
>arguments: [_]&u8 = [ >arguments: [_]&u8 = [
executable_path.pointer, executable_path.pointer,
"test",
zero, zero,
]; ];
>args = arguments[..arguments.length - 1]; >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; return 0;

View File

@ -163,22 +163,39 @@ fn String compile_file(Arena* arena, Compile options)
auto is_compiler = relative_file_path.equal(string_literal("src/compiler.bbb")); 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), 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), build_mode_to_string(options.build_mode),
string_literal("_"), string_literal("_"),
options.has_debug_info ? string_literal("di") : string_literal("nodi"), 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)); 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)); make_directory(cstr(output_path_dir));
String output_path_base_parts[] = { String output_path_base_parts[] = {
@ -341,6 +358,7 @@ fn String compile_file(Arena* arena, Compile options)
.target = { .target = {
.cpu = CPUArchitecture::x86_64, .cpu = CPUArchitecture::x86_64,
.os = OperatingSystem::linux_, .os = OperatingSystem::linux_,
.host_cpu_model = options.host_cpu_model,
}, },
.build_mode = options.build_mode, .build_mode = options.build_mode,
.has_debug_info = options.has_debug_info, .has_debug_info = options.has_debug_info,
@ -583,6 +601,7 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
} }
bool has_debug_info_array[] = {true, false}; bool has_debug_info_array[] = {true, false};
bool is_host_cpu_model_array[] = {true, false};
for (auto name: names) for (auto name: names)
{ {
@ -596,11 +615,11 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts)); auto relative_file_path = arena_join_string(arena, array_to_slice(relative_file_path_parts));
auto executable_path = compile_file(arena, { auto executable_path = compile_file(arena, {
.relative_file_path = relative_file_path, .relative_file_path = relative_file_path,
.build_mode = build_mode, .build_mode = build_mode,
.has_debug_info = has_debug_info, .has_debug_info = has_debug_info,
.silent = true, .silent = true,
}); });
char* const arguments[] = char* const arguments[] =
{ {

View File

@ -247,6 +247,7 @@ struct Target
{ {
CPUArchitecture cpu; CPUArchitecture cpu;
OperatingSystem os; OperatingSystem os;
bool host_cpu_model;
}; };
fn Target target_get_native() fn Target target_get_native()
@ -270,6 +271,7 @@ struct Compile
String relative_file_path; String relative_file_path;
BuildMode build_mode; BuildMode build_mode;
bool has_debug_info; bool has_debug_info;
bool host_cpu_model;
bool silent; bool silent;
}; };

View File

@ -416,15 +416,23 @@ fn void llvm_initialize(Module* module)
module->scope.llvm = di_compile_unit; module->scope.llvm = di_compile_unit;
} }
char* target_triple = {}; const char* target_triple = {};
char* cpu_model = {}; const char* cpu_model = {};
char* cpu_features = {}; const char* cpu_features = {};
if (target_compare(module->target, target_get_native())) if (target_compare(module->target, target_get_native()))
{ {
target_triple = llvm_global.host_triple; target_triple = llvm_global.host_triple;
cpu_model = llvm_global.host_cpu_model; if (module->target.host_cpu_model)
cpu_features = llvm_global.host_cpu_features; {
cpu_model = llvm_global.host_cpu_model;
cpu_features = llvm_global.host_cpu_features;
}
else
{
cpu_model = "generic";
cpu_features = "";
}
} }
else else
{ {