aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAstavie <astavie@protonmail.com>2022-06-15 21:30:29 +0200
committerAstavie <astavie@protonmail.com>2022-06-15 21:30:29 +0200
commitb13dad02a4de436e6dcc64af11968d07475961bc (patch)
tree6f6376ee2af9a9a8f723248102a6790e41ec2b76
parentf045f8d805ca954e3950a951bad50ff4209804f6 (diff)
fix require flag on higher optimization modes
-rw-r--r--src/llvm_backend_opt.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp
index d36bdec0b..6b80b21d6 100644
--- a/src/llvm_backend_opt.cpp
+++ b/src/llvm_backend_opt.cpp
@@ -380,6 +380,43 @@ void llvm_delete_function(LLVMValueRef func) {
LLVMDeleteFunction(func);
}
+void lb_append_to_compiler_used(lbModule *m, LLVMValueRef func) {
+ LLVMValueRef global = LLVMGetNamedGlobal(m->mod, "llvm.compiler.used");
+
+ LLVMValueRef *constants;
+ int operands = 1;
+
+ if (global != NULL) {
+ GB_ASSERT(LLVMIsAGlobalVariable(global));
+ LLVMValueRef initializer = LLVMGetInitializer(global);
+
+ GB_ASSERT(LLVMIsAConstantArray(initializer));
+ operands = LLVMGetNumOperands(initializer) + 1;
+ constants = gb_alloc_array(temporary_allocator(), LLVMValueRef, operands);
+
+ for (int i = 0; i < operands - 1; i++) {
+ LLVMValueRef operand = LLVMGetOperand(initializer, i);
+ GB_ASSERT(LLVMIsAConstant(operand));
+ constants[i] = operand;
+ }
+
+ LLVMDeleteGlobal(global);
+ } else {
+ constants = gb_alloc_array(temporary_allocator(), LLVMValueRef, 1);
+ }
+
+ LLVMTypeRef Int8PtrTy = LLVMPointerType(LLVMInt8TypeInContext(m->ctx), 0);
+ LLVMTypeRef ATy = LLVMArrayType(Int8PtrTy, operands);
+
+ constants[operands - 1] = LLVMConstBitCast(func, Int8PtrTy);
+ LLVMValueRef initializer = LLVMConstArray(Int8PtrTy, constants, operands);
+
+ global = LLVMAddGlobal(m->mod, ATy, "llvm.compiler.used");
+ LLVMSetLinkage(global, LLVMAppendingLinkage);
+ LLVMSetSection(global, "llvm.metadata");
+ LLVMSetInitializer(global, initializer);
+}
+
void lb_run_remove_unused_function_pass(lbModule *m) {
isize removal_count = 0;
isize pass_count = 0;
@@ -415,6 +452,7 @@ void lb_run_remove_unused_function_pass(lbModule *m) {
Entity *e = *found;
bool is_required = (e->flags & EntityFlag_Require) == EntityFlag_Require;
if (is_required) {
+ lb_append_to_compiler_used(m, curr_func);
continue;
}
}