aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm_backend.cpp')
-rw-r--r--src/llvm_backend.cpp107
1 files changed, 51 insertions, 56 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index f61c297bd..003424e0a 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -1497,8 +1497,6 @@ gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
auto passes = array_make<char const *>(heap_allocator(), 0, 64);
defer (array_free(&passes));
-
-
LLVMPassBuilderOptionsRef pb_options = LLVMCreatePassBuilderOptions();
defer (LLVMDisposePassBuilderOptions(pb_options));
@@ -2505,7 +2503,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMCodeModel code_mode = LLVMCodeModelDefault;
if (is_arch_wasm()) {
code_mode = LLVMCodeModelJITDefault;
- } else if (build_context.metrics.os == TargetOs_freestanding) {
+ } else if (is_arch_x86() && build_context.metrics.os == TargetOs_freestanding) {
code_mode = LLVMCodeModelKernel;
}
@@ -2531,7 +2529,46 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
*/
if (build_context.target_features_set.entries.count != 0) {
- llvm_features = target_features_set_to_cstring(permanent_allocator(), false);
+ // Prefix all of the features with a `+`, because we are
+ // enabling additional features.
+ char const *additional_features = target_features_set_to_cstring(permanent_allocator(), false, true);
+
+ String f_string = make_string_c(llvm_features);
+ String a_string = make_string_c(additional_features);
+ isize f_len = f_string.len;
+
+ if (f_len == 0) {
+ // The common case is that llvm_features is empty, so
+ // the target_features_set additions can be used as is.
+ llvm_features = additional_features;
+ } else {
+ // The user probably specified `-microarch:native`, so
+ // llvm_features is populated by LLVM's idea of what
+ // the host CPU supports.
+ //
+ // As far as I can tell, (which is barely better than
+ // wild guessing), a bitset is formed by parsing the
+ // string left to right.
+ //
+ // So, llvm_features + ',' + additonal_features, will
+ // makes the target_features_set override llvm_features.
+
+ char *tmp = gb_alloc_array(permanent_allocator(), char, f_len + 1 + a_string.len + 1);
+ isize len = 0;
+
+ // tmp = f_string
+ gb_memmove(tmp, f_string.text, f_string.len);
+ len += f_string.len;
+ // tmp += ','
+ tmp[len++] = ',';
+ // tmp += a_string
+ gb_memmove(tmp + len, a_string.text, a_string.len);
+ len += a_string.len;
+ // tmp += NUL
+ tmp[len++] = 0;
+
+ llvm_features = tmp;
+ }
}
// GB_ASSERT_MSG(LLVMTargetHasAsmBackend(target));
@@ -2697,64 +2734,22 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
}
}
- {
- char const *name = LB_TYPE_INFO_TYPES_NAME;
- Type *t = alloc_type_array(t_type_info_ptr, count);
- LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
- LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
- if (LB_USE_GIANT_PACKED_STRUCT) {
- lb_make_global_private_const(g);
- }
- lb_global_type_info_member_types = lb_addr({g, alloc_type_pointer(t)});
-
- }
- {
- char const *name = LB_TYPE_INFO_NAMES_NAME;
- Type *t = alloc_type_array(t_string, count);
- LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
- LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
- if (LB_USE_GIANT_PACKED_STRUCT) {
- lb_make_global_private_const(g);
- }
- lb_global_type_info_member_names = lb_addr({g, alloc_type_pointer(t)});
- }
- {
- char const *name = LB_TYPE_INFO_OFFSETS_NAME;
- Type *t = alloc_type_array(t_uintptr, count);
- LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
- LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
- if (LB_USE_GIANT_PACKED_STRUCT) {
- lb_make_global_private_const(g);
- }
- lb_global_type_info_member_offsets = lb_addr({g, alloc_type_pointer(t)});
- }
-
- {
- char const *name = LB_TYPE_INFO_USINGS_NAME;
- Type *t = alloc_type_array(t_bool, count);
+ auto const global_type_info_make = [](lbModule *m, char const *name, Type *elem_type, i64 count) -> lbAddr {
+ Type *t = alloc_type_array(elem_type, count);
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g, LLVMInternalLinkage);
if (LB_USE_GIANT_PACKED_STRUCT) {
lb_make_global_private_const(g);
}
- lb_global_type_info_member_usings = lb_addr({g, alloc_type_pointer(t)});
- }
-
- {
- char const *name = LB_TYPE_INFO_TAGS_NAME;
- Type *t = alloc_type_array(t_string, count);
- LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
- LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
- if (LB_USE_GIANT_PACKED_STRUCT) {
- lb_make_global_private_const(g);
- }
- lb_global_type_info_member_tags = lb_addr({g, alloc_type_pointer(t)});
- }
+ return lb_addr({g, alloc_type_pointer(t)});
+ };
+
+ lb_global_type_info_member_types = global_type_info_make(m, LB_TYPE_INFO_TYPES_NAME, t_type_info_ptr, count);
+ lb_global_type_info_member_names = global_type_info_make(m, LB_TYPE_INFO_NAMES_NAME, t_string, count);
+ lb_global_type_info_member_offsets = global_type_info_make(m, LB_TYPE_INFO_OFFSETS_NAME, t_uintptr, count);
+ lb_global_type_info_member_usings = global_type_info_make(m, LB_TYPE_INFO_USINGS_NAME, t_bool, count);
+ lb_global_type_info_member_tags = global_type_info_make(m, LB_TYPE_INFO_TAGS_NAME, t_string, count);
}
}