This commit is contained in:
David Gonzalez Martin 2025-05-06 08:34:42 -06:00
parent c07849aa79
commit 07ca538670
5 changed files with 567 additions and 216 deletions

View File

@ -1,6 +1,20 @@
#pragma once #pragma once
#include <lib.h> #include <lib.h>
namespace llvm
{
class Type;
class Value;
class Module;
class Builder;
class LLVMContext;
class Function;
class DIBuilder;
class DICompileUnit;
class DIFile;
class DIScope;
}
#define report_error() trap_raw() #define report_error() trap_raw()
@ -38,6 +52,23 @@ fn String build_mode_to_string(BuildMode build_mode)
} }
} }
fn bool build_mode_is_optimized(BuildMode build_mode)
{
switch (build_mode)
{
case BuildMode::debug_none:
case BuildMode::debug:
return false;
case BuildMode::soft_optimize:
case BuildMode::optimize_for_speed:
case BuildMode::optimize_for_size:
case BuildMode::aggressively_optimize_for_speed:
case BuildMode::aggressively_optimize_for_size:
return true;
case BuildMode::count: unreachable();
}
}
enum class ValueKind enum class ValueKind
{ {
right, right,
@ -65,6 +96,65 @@ struct Argument;
struct Scope; struct Scope;
struct MacroDeclaration; struct MacroDeclaration;
struct DirectAttributes
{
u32 offset;
u32 alignment;
};
struct IndirectAttributes
{
u32 alignment;
u32 address_space;
};
enum class AbiKind : u8
{
ignore,
direct,
extend,
indirect,
indirect_aliased,
expand,
coerce_and_expand,
in_alloca,
};
struct AbiFlags
{
AbiKind kind;
bool padding_in_reg;
bool in_alloca_sret;
bool in_alloca_indirect;
bool indirect_by_value;
bool indirect_realign;
bool sret_after_this;
bool in_reg;
bool can_be_flattened;
bool sign_extension;
};
struct AbiInformation
{
Type* semantic_type;
Type* coerce_to_type;
union
{
Type* type;
Type* unpadded_coerce_and_expand_type;
} padding;
u16 padding_argument_index;
union
{
DirectAttributes direct;
IndirectAttributes indirect;
u32 alloca_field_index;
} attributes;
AbiFlags flags;
u16 abi_start;
u16 abi_count;
};
struct Target struct Target
{ {
CPUArchitecture cpu; CPUArchitecture cpu;
@ -87,6 +177,24 @@ enum class CallingConvention
count, count,
}; };
enum class ResolvedCallingConvention
{
system_v,
win64,
count,
};
fn ResolvedCallingConvention resolve_calling_convention(CallingConvention cc)
{
switch (cc)
{
case CallingConvention::c:
// TODO:
return ResolvedCallingConvention::system_v;
case CallingConvention::count: unreachable();
}
}
enum class InlineBehavior enum class InlineBehavior
{ {
normal, normal,
@ -124,12 +232,29 @@ struct TypeInteger
bool is_signed; bool is_signed;
}; };
struct AbiRegisterCountSystemV
{
u32 gpr;
u32 sse;
};
union AbiRegisterCount
{
AbiRegisterCountSystemV system_v;
};
struct TypeFunction struct TypeFunction
{ {
Type* semantic_return_type; Type* semantic_return_type;
Slice<Type*> semantic_argument_types; Slice<Type*> semantic_argument_types;
CallingConvention calling_convention; CallingConvention calling_convention;
bool is_variable_arguments; bool is_variable_arguments;
// ABI
Slice<Type*> abi_argument_types;
Type* abi_return_type;
AbiRegisterCount available_registers;
Slice<AbiInformation> argument_abis;
AbiInformation return_abi;
}; };
struct TypePointer struct TypePointer
@ -340,6 +465,7 @@ struct Scope
u32 line; u32 line;
u32 column; u32 column;
ScopeKind kind; ScopeKind kind;
llvm::DIScope* llvm;
}; };
enum class StatementId enum class StatementId
@ -742,6 +868,35 @@ struct Argument
u32 index; u32 index;
}; };
struct LLVMIntrinsicId
{
u32 n;
};
struct LLVMIntrinsicTable
{
LLVMIntrinsicId
trap,
va_start,
va_end,
va_copy;
};
struct ModuleLLVM
{
llvm::LLVMContext* context;
llvm::Module* module;
llvm::Builder* builder;
llvm::DIBuilder* di_builder;
llvm::DIFile* file;
llvm::DICompileUnit* compile_unit;
llvm::Type* pointer_type;
llvm::Type* void_type;
LLVMIntrinsicTable intrinsic_table;
llvm::Function* memcmp;
u32 debug_tag;
};
struct Module struct Module
{ {
Arena* arena; Arena* arena;
@ -768,6 +923,7 @@ struct Module
MacroDeclaration* current_macro_declaration; MacroDeclaration* current_macro_declaration;
MacroInstantiation* current_macro_instantiation; MacroInstantiation* current_macro_instantiation;
ModuleLLVM llvm;
Scope scope; Scope scope;
String name; String name;

View File

@ -1,5 +1,106 @@
#include <compiler.h> #include <compiler.h>
#include <llvm.h>
fn void llvm_initialize(Module* module)
{
llvm_initialize_all();
auto context = LLVMContextCreate();
auto m = llvm_context_create_module(context, module->name);
auto builder = LLVMCreateBuilderInContext(context);
llvm::DIBuilder* di_builder = 0;
llvm::DICompileUnit* di_compile_unit = 0;
llvm::DIFile* di_file = 0;
if (module->has_debug_info)
{
di_builder = LLVMCreateDIBuilder(m);
auto last_slash = string_last_character(module->path, '/');
if (last_slash == string_no_match)
{
report_error();
}
auto directory = module->path(0, last_slash);
auto file_name = module->path(last_slash + 1);
auto file = LLVMDIBuilderCreateFile(di_builder, file_name.pointer, file_name.length, directory.pointer, directory.length);
auto producer_name = string_literal("bloat buster");
auto is_optimized = build_mode_is_optimized(module->build_mode);
auto flags = string_literal("");
u32 runtime_version = 0;
auto split_name = string_literal("");
auto sysroot = string_literal("");
auto sdk = string_literal("");
di_compile_unit = LLVMDIBuilderCreateCompileUnit(di_builder, DwarfSourceLanguage::C17, file, producer_name.pointer, producer_name.length, is_optimized, flags.pointer, flags.length, runtime_version, split_name.pointer, split_name.length, DwarfEmissionKind::full, 0, 0, is_optimized, sysroot.pointer, sysroot.length, sdk.pointer, sdk.length);
module->scope.llvm = (llvm::DIScope*)di_compile_unit;
}
module->llvm = {
.context = context,
.module = m,
.builder = builder,
.di_builder = di_builder,
.file = di_file,
.compile_unit = di_compile_unit,
.pointer_type = LLVMPointerTypeInContext(context),
.void_type = LLVMVoidTypeInContext(context),
.intrinsic_table = {
.trap = LLVMLookupIntrinsicID(split_string_literal("llvm.trap")),
.va_start = LLVMLookupIntrinsicID(split_string_literal("llvm.va_start")),
.va_end = LLVMLookupIntrinsicID(split_string_literal("llvm.va_end")),
.va_copy = LLVMLookupIntrinsicID(split_string_literal("llvm.va_copy")),
},
};
}
fn AbiInformation abi_system_classify_return_type(Module* module, Type* semantic_return_type)
{
trap_raw();
}
void emit(Module* module) void emit(Module* module)
{ {
llvm_initialize(module);
for (auto* global = module->first_global; global; global = global->next)
{
switch (global->variable.storage->id)
{
case ValueId::function:
case ValueId::external_function:
{
auto function_type = &global->variable.storage->type->pointer.element_type->function;
function_type->argument_abis = arena_allocate<AbiInformation>(module->arena, function_type->semantic_argument_types.length);
auto resolved_calling_convention = resolve_calling_convention(function_type->calling_convention);
auto is_reg_call = resolved_calling_convention == ResolvedCallingConvention::system_v && false; // TODO: regcall calling convention
switch (resolved_calling_convention)
{
case ResolvedCallingConvention::system_v:
{
function_type->available_registers = {
.system_v = {
.gpr = (u32)(is_reg_call ? 11 : 6),
.sse = (u32)(is_reg_call ? 16 : 8),
},
};
function_type->return_abi = abi_system_classify_return_type(module, function_type->semantic_return_type);
trap_raw();
} break;
case ResolvedCallingConvention::win64:
{
report_error();
} break;
case ResolvedCallingConvention::count: unreachable();
}
trap_raw();
} break;
case ValueId::global:
{
trap_raw();
} break;
default: report_error();
}
}
trap_raw();
} }

View File

@ -8,6 +8,7 @@
#define breakpoint() __builtin_debugtrap() #define breakpoint() __builtin_debugtrap()
#define string_literal_length(s) (sizeof(s) - 1) #define string_literal_length(s) (sizeof(s) - 1)
#define string_literal(s) ((String){ .pointer = (u8*)(s), .length = string_literal_length(s), }) #define string_literal(s) ((String){ .pointer = (u8*)(s), .length = string_literal_length(s), })
#define split_string_literal(s) (u8*)s, string_literal_length(s)
#define offsetof(S, f) __builtin_offsetof(S, f) #define offsetof(S, f) __builtin_offsetof(S, f)
#define array_length(arr) sizeof(arr) / sizeof((arr)[0]) #define array_length(arr) sizeof(arr) / sizeof((arr)[0])

View File

@ -26,97 +26,95 @@
#include "lld/Common/CommonLinkerContext.h" #include "lld/Common/CommonLinkerContext.h"
using namespace llvm; fn llvm::StringRef string_ref(String string)
fn StringRef string_ref(String string)
{ {
return StringRef((char*)string.pointer, string.length); return llvm::StringRef((char*)string.pointer, string.length);
} }
EXPORT Module* llvm_context_create_module(LLVMContext& context, String name) EXPORT llvm::Module* llvm_context_create_module(llvm::LLVMContext* context, String name)
{ {
return new Module(string_ref(name), context); return new llvm::Module(string_ref(name), *context);
} }
EXPORT unsigned llvm_integer_type_get_bit_count(const IntegerType& integer_type) EXPORT unsigned llvm_integer_type_get_bit_count(const llvm::IntegerType& integer_type)
{ {
auto result = integer_type.getBitWidth(); auto result = integer_type.getBitWidth();
return result; return result;
} }
EXPORT GlobalVariable* llvm_module_create_global_variable(Module& module, Type* type, bool is_constant, GlobalValue::LinkageTypes linkage_type, Constant* initial_value, String name, GlobalVariable* before, GlobalValue::ThreadLocalMode thread_local_mode, unsigned address_space, bool externally_initialized) EXPORT llvm::GlobalVariable* llvm_module_create_global_variable(llvm::Module& module, llvm::Type* type, bool is_constant, llvm::GlobalValue::LinkageTypes linkage_type, llvm::Constant* initial_value, String name, llvm::GlobalVariable* before, llvm::GlobalValue::ThreadLocalMode thread_local_mode, unsigned address_space, bool externally_initialized)
{ {
auto* global = new GlobalVariable(module, type, is_constant, linkage_type, initial_value, string_ref(name), before, thread_local_mode, address_space, externally_initialized); auto* global = new llvm::GlobalVariable(module, type, is_constant, linkage_type, initial_value, string_ref(name), before, thread_local_mode, address_space, externally_initialized);
return global; return global;
} }
EXPORT void llvm_global_variable_add_debug_info(GlobalVariable& global, DIGlobalVariableExpression* debug_global_variable) EXPORT void llvm_global_variable_add_debug_info(llvm::GlobalVariable& global, llvm::DIGlobalVariableExpression* debug_global_variable)
{ {
global.addDebugInfo(debug_global_variable); global.addDebugInfo(debug_global_variable);
} }
EXPORT void llvm_global_variable_delete(GlobalVariable* global) EXPORT void llvm_global_variable_delete(llvm::GlobalVariable* global)
{ {
delete global; delete global;
} }
EXPORT void llvm_subprogram_replace_type(DISubprogram& subprogram, DISubroutineType* subroutine_type) EXPORT void llvm_subprogram_replace_type(llvm::DISubprogram& subprogram, llvm::DISubroutineType* subroutine_type)
{ {
subprogram.replaceType(subroutine_type); subprogram.replaceType(subroutine_type);
} }
EXPORT Function* llvm_module_create_function(Module* module, FunctionType* function_type, GlobalValue::LinkageTypes linkage_type, unsigned address_space, String name) EXPORT llvm::Function* llvm_module_create_function(llvm::Module* module, llvm::FunctionType* function_type, llvm::GlobalValue::LinkageTypes linkage_type, unsigned address_space, String name)
{ {
auto* function = Function::Create(function_type, linkage_type, address_space, string_ref(name), module); auto* function = llvm::Function::Create(function_type, linkage_type, address_space, string_ref(name), module);
return function; return function;
} }
EXPORT StructType* llvm_context_create_forward_declared_struct_type(LLVMContext& context, String name) EXPORT llvm::StructType* llvm_context_create_forward_declared_struct_type(llvm::LLVMContext& context, String name)
{ {
auto* struct_type = StructType::create(context, string_ref(name)); auto* struct_type = llvm::StructType::create(context, string_ref(name));
return struct_type; return struct_type;
} }
EXPORT StructType* llvm_context_create_struct_type(LLVMContext& context, Type** type_pointer, size_t type_count, String name, bool is_packed) EXPORT llvm::StructType* llvm_context_create_struct_type(llvm::LLVMContext& context, llvm::Type** type_pointer, size_t type_count, String name, bool is_packed)
{ {
auto types = ArrayRef<Type*>(type_pointer, type_count); auto types = llvm::ArrayRef<llvm::Type*>(type_pointer, type_count);
auto* struct_type = StructType::create(context, types, string_ref(name), is_packed); auto* struct_type = llvm::StructType::create(context, types, string_ref(name), is_packed);
return struct_type; return struct_type;
} }
EXPORT StructType* llvm_context_get_struct_type(LLVMContext& context, Type** type_pointer, size_t type_count, bool is_packed) EXPORT llvm::StructType* llvm_context_get_struct_type(llvm::LLVMContext& context, llvm::Type** type_pointer, size_t type_count, bool is_packed)
{ {
auto types = ArrayRef<Type*>(type_pointer, type_count); auto types = llvm::ArrayRef<llvm::Type*>(type_pointer, type_count);
auto* struct_type = StructType::get(context, types, is_packed); auto* struct_type = llvm::StructType::get(context, types, is_packed);
return struct_type; return struct_type;
} }
EXPORT BasicBlock* llvm_context_create_basic_block(LLVMContext& context, String name, Function* parent) EXPORT llvm::BasicBlock* llvm_context_create_basic_block(llvm::LLVMContext& context, String name, llvm::Function* parent)
{ {
auto* basic_block = BasicBlock::Create(context, string_ref(name), parent); auto* basic_block = llvm::BasicBlock::Create(context, string_ref(name), parent);
return basic_block; return basic_block;
} }
EXPORT bool llvm_value_has_one_use(Value& value) EXPORT bool llvm_value_has_one_use(llvm::Value& value)
{ {
auto result = value.hasOneUse(); auto result = value.hasOneUse();
return result; return result;
} }
EXPORT Value* llvm_basic_block_user_begin(BasicBlock* basic_block) EXPORT llvm::Value* llvm_basic_block_user_begin(llvm::BasicBlock* basic_block)
{ {
Value* value = *basic_block->user_begin(); llvm::Value* value = *basic_block->user_begin();
return value; return value;
} }
EXPORT void llvm_basic_block_delete(BasicBlock* basic_block) EXPORT void llvm_basic_block_delete(llvm::BasicBlock* basic_block)
{ {
delete basic_block; delete basic_block;
} }
EXPORT BranchInst* llvm_value_to_branch(Value* value) EXPORT llvm::BranchInst* llvm_value_to_branch(llvm::Value* value)
{ {
auto* result = dyn_cast<BranchInst>(value); auto* result = dyn_cast<llvm::BranchInst>(value);
return result; return result;
} }
@ -124,7 +122,7 @@ EXPORT BranchInst* llvm_value_to_branch(Value* value)
// for something immediately preceding the IP. Sometimes this can // for something immediately preceding the IP. Sometimes this can
// happen with how we generate implicit-returns; it can also happen // happen with how we generate implicit-returns; it can also happen
// with noreturn cleanups. // with noreturn cleanups.
fn StoreInst* get_store_if_valid(User* user, Value* return_alloca, Type* element_type) fn llvm::StoreInst* get_store_if_valid(llvm::User* user, llvm::Value* return_alloca, llvm::Type* element_type)
{ {
auto *SI = dyn_cast<llvm::StoreInst>(user); auto *SI = dyn_cast<llvm::StoreInst>(user);
if (!SI || SI->getPointerOperand() != return_alloca || if (!SI || SI->getPointerOperand() != return_alloca ||
@ -142,7 +140,7 @@ fn StoreInst* get_store_if_valid(User* user, Value* return_alloca, Type* element
// copy of static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { // copy of static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
// in clang/lib/CodeGen/CGCall.cpp:3526 in LLVM 19 // in clang/lib/CodeGen/CGCall.cpp:3526 in LLVM 19
EXPORT StoreInst* llvm_find_return_value_dominating_store(IRBuilder<>& builder, Value* return_alloca, Type* element_type) EXPORT llvm::StoreInst* llvm_find_return_value_dominating_store(llvm::IRBuilder<>& builder, llvm::Value* return_alloca, llvm::Type* element_type)
{ {
// Check if a User is a store which pointerOperand is the ReturnValue. // Check if a User is a store which pointerOperand is the ReturnValue.
// We are looking for stores to the ReturnValue, not for stores of the // We are looking for stores to the ReturnValue, not for stores of the
@ -183,21 +181,21 @@ EXPORT StoreInst* llvm_find_return_value_dominating_store(IRBuilder<>& builder,
return store; return store;
} }
EXPORT bool llvm_value_use_empty(Value& value) EXPORT bool llvm_value_use_empty(llvm::Value& value)
{ {
return value.use_empty(); return value.use_empty();
} }
EXPORT bool llvm_basic_block_is_empty(BasicBlock& basic_block) EXPORT bool llvm_basic_block_is_empty(llvm::BasicBlock& basic_block)
{ {
return basic_block.empty(); return basic_block.empty();
} }
EXPORT AllocaInst* llvm_builder_create_alloca(IRBuilder<>& builder, Type* type, unsigned address_space, String name) EXPORT llvm::AllocaInst* llvm_builder_create_alloca(llvm::IRBuilder<>& builder, llvm::Type* type, unsigned address_space, String name)
{ {
const DataLayout &data_layout = builder.GetInsertBlock()->getDataLayout(); const llvm::DataLayout &data_layout = builder.GetInsertBlock()->getDataLayout();
Align alignment = data_layout.getABITypeAlign(type); llvm::Align alignment = data_layout.getABITypeAlign(type);
return builder.Insert(new AllocaInst(type, address_space, 0, alignment), string_ref(name)); return builder.Insert(new llvm::AllocaInst(type, address_space, 0, alignment), string_ref(name));
} }
enum class BBLLVMAttributeFramePointerKind : u8 enum class BBLLVMAttributeFramePointerKind : u8
@ -273,8 +271,8 @@ enum class BBLLVMUWTableKind
struct BBLLVMArgumentAttributes struct BBLLVMArgumentAttributes
{ {
Type* semantic_type; llvm::Type* semantic_type;
Type* abi_type; llvm::Type* abi_type;
u64 dereferenceable_bytes; u64 dereferenceable_bytes;
u32 alignment; u32 alignment;
u32 no_alias:1; u32 no_alias:1;
@ -299,9 +297,9 @@ struct BBLLVMArgumentAttributes
static_assert(sizeof(BBLLVMArgumentAttributes) == 2 * sizeof(Type*) + 2 * sizeof(u64)); static_assert(sizeof(BBLLVMArgumentAttributes) == 2 * sizeof(Type*) + 2 * sizeof(u64));
fn AttributeSet build_argument_attributes(LLVMContext& context, const BBLLVMArgumentAttributes& attributes) fn llvm::AttributeSet build_argument_attributes(llvm::LLVMContext& context, const BBLLVMArgumentAttributes& attributes)
{ {
AttrBuilder builder(context); llvm::AttrBuilder builder(context);
if (attributes.alignment) if (attributes.alignment)
{ {
@ -310,32 +308,32 @@ fn AttributeSet build_argument_attributes(LLVMContext& context, const BBLLVMArgu
if (attributes.no_alias) if (attributes.no_alias)
{ {
builder.addAttribute(Attribute::NoAlias); builder.addAttribute(llvm::Attribute::NoAlias);
} }
if (attributes.non_null) if (attributes.non_null)
{ {
builder.addAttribute(Attribute::NonNull); builder.addAttribute(llvm::Attribute::NonNull);
} }
if (attributes.no_undef) if (attributes.no_undef)
{ {
builder.addAttribute(Attribute::NoUndef); builder.addAttribute(llvm::Attribute::NoUndef);
} }
if (attributes.sign_extend) if (attributes.sign_extend)
{ {
builder.addAttribute(Attribute::SExt); builder.addAttribute(llvm::Attribute::SExt);
} }
if (attributes.zero_extend) if (attributes.zero_extend)
{ {
builder.addAttribute(Attribute::ZExt); builder.addAttribute(llvm::Attribute::ZExt);
} }
if (attributes.in_reg) if (attributes.in_reg)
{ {
builder.addAttribute(Attribute::InReg); builder.addAttribute(llvm::Attribute::InReg);
} }
if (attributes.no_fp_class) if (attributes.no_fp_class)
@ -350,12 +348,12 @@ fn AttributeSet build_argument_attributes(LLVMContext& context, const BBLLVMArgu
if (attributes.writable) if (attributes.writable)
{ {
builder.addAttribute(Attribute::Writable); builder.addAttribute(llvm::Attribute::Writable);
} }
if (attributes.dead_on_unwind) if (attributes.dead_on_unwind)
{ {
builder.addAttribute(Attribute::DeadOnUnwind); builder.addAttribute(llvm::Attribute::DeadOnUnwind);
} }
if (attributes.in_alloca) if (attributes.in_alloca)
@ -375,7 +373,7 @@ fn AttributeSet build_argument_attributes(LLVMContext& context, const BBLLVMArgu
if (attributes.nest) if (attributes.nest)
{ {
builder.addAttribute(Attribute::Nest); builder.addAttribute(llvm::Attribute::Nest);
} }
if (attributes.by_value) if (attributes.by_value)
@ -390,10 +388,10 @@ fn AttributeSet build_argument_attributes(LLVMContext& context, const BBLLVMArgu
if (attributes.no_capture) if (attributes.no_capture)
{ {
builder.addAttribute(Attribute::NoCapture); builder.addAttribute(llvm::Attribute::NoCapture);
} }
auto attribute_set = AttributeSet::get(context, builder); auto attribute_set = llvm::AttributeSet::get(context, builder);
return attribute_set; return attribute_set;
} }
@ -510,9 +508,9 @@ static_assert(sizeof(BBLLVMAttributeList) == sizeof(BBLLVMFunctionAttributes) +
typedef void* BBLLVMAttributeListHandle; typedef void* BBLLVMAttributeListHandle;
EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context, const BBLLVMAttributeList& attributes, bool call_site) EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(llvm::LLVMContext& context, const BBLLVMAttributeList& attributes, bool call_site)
{ {
AttrBuilder function_attribute_builder(context); llvm::AttrBuilder function_attribute_builder(context);
if (attributes.function.prefer_vector_width.length) if (attributes.function.prefer_vector_width.length)
{ {
@ -526,7 +524,7 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.noreturn) if (attributes.function.flags0.noreturn)
{ {
function_attribute_builder.addAttribute(Attribute::NoReturn); function_attribute_builder.addAttribute(llvm::Attribute::NoReturn);
} }
if (attributes.function.flags0.cmse_ns_call) if (attributes.function.flags0.cmse_ns_call)
@ -536,42 +534,42 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.nounwind) if (attributes.function.flags0.nounwind)
{ {
function_attribute_builder.addAttribute(Attribute::NoUnwind); function_attribute_builder.addAttribute(llvm::Attribute::NoUnwind);
} }
if (attributes.function.flags0.returns_twice) if (attributes.function.flags0.returns_twice)
{ {
function_attribute_builder.addAttribute(Attribute::ReturnsTwice); function_attribute_builder.addAttribute(llvm::Attribute::ReturnsTwice);
} }
if (attributes.function.flags0.cold) if (attributes.function.flags0.cold)
{ {
function_attribute_builder.addAttribute(Attribute::Cold); function_attribute_builder.addAttribute(llvm::Attribute::Cold);
} }
if (attributes.function.flags0.hot) if (attributes.function.flags0.hot)
{ {
function_attribute_builder.addAttribute(Attribute::Hot); function_attribute_builder.addAttribute(llvm::Attribute::Hot);
} }
if (attributes.function.flags0.no_duplicate) if (attributes.function.flags0.no_duplicate)
{ {
function_attribute_builder.addAttribute(Attribute::NoDuplicate); function_attribute_builder.addAttribute(llvm::Attribute::NoDuplicate);
} }
if (attributes.function.flags0.convergent) if (attributes.function.flags0.convergent)
{ {
function_attribute_builder.addAttribute(Attribute::Convergent); function_attribute_builder.addAttribute(llvm::Attribute::Convergent);
} }
if (attributes.function.flags0.no_merge) if (attributes.function.flags0.no_merge)
{ {
function_attribute_builder.addAttribute(Attribute::NoMerge); function_attribute_builder.addAttribute(llvm::Attribute::NoMerge);
} }
if (attributes.function.flags0.will_return) if (attributes.function.flags0.will_return)
{ {
function_attribute_builder.addAttribute(Attribute::WillReturn); function_attribute_builder.addAttribute(llvm::Attribute::WillReturn);
} }
if (attributes.function.flags0.no_caller_saved_registers) if (attributes.function.flags0.no_caller_saved_registers)
@ -581,12 +579,12 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.no_cf_check) if (attributes.function.flags0.no_cf_check)
{ {
function_attribute_builder.addAttribute(Attribute::NoCfCheck); function_attribute_builder.addAttribute(llvm::Attribute::NoCfCheck);
} }
if (attributes.function.flags0.no_callback) if (attributes.function.flags0.no_callback)
{ {
function_attribute_builder.addAttribute(Attribute::NoCallback); function_attribute_builder.addAttribute(llvm::Attribute::NoCallback);
} }
if (attributes.function.flags0.alloc_size) if (attributes.function.flags0.alloc_size)
@ -656,17 +654,17 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.optimize_for_size) if (attributes.function.flags0.optimize_for_size)
{ {
function_attribute_builder.addAttribute(Attribute::OptimizeForSize); function_attribute_builder.addAttribute(llvm::Attribute::OptimizeForSize);
} }
if (attributes.function.flags0.min_size) if (attributes.function.flags0.min_size)
{ {
function_attribute_builder.addAttribute(Attribute::MinSize); function_attribute_builder.addAttribute(llvm::Attribute::MinSize);
} }
if (attributes.function.flags0.no_red_zone) if (attributes.function.flags0.no_red_zone)
{ {
function_attribute_builder.addAttribute(Attribute::NoRedZone); function_attribute_builder.addAttribute(llvm::Attribute::NoRedZone);
} }
if (attributes.function.flags0.indirect_tls_seg_refs) if (attributes.function.flags0.indirect_tls_seg_refs)
@ -676,7 +674,7 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.no_implicit_floats) if (attributes.function.flags0.no_implicit_floats)
{ {
function_attribute_builder.addAttribute(Attribute::NoImplicitFloat); function_attribute_builder.addAttribute(llvm::Attribute::NoImplicitFloat);
} }
if (attributes.function.flags0.sample_profile_suffix_elision_policy) if (attributes.function.flags0.sample_profile_suffix_elision_policy)
@ -701,7 +699,7 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.memory_arg_memory_only) if (attributes.function.flags0.memory_arg_memory_only)
{ {
Attribute attribute = function_attribute_builder.getAttribute(Attribute::Memory); llvm::Attribute attribute = function_attribute_builder.getAttribute(llvm::Attribute::Memory);
function_attribute_builder.addMemoryAttr(attribute.getMemoryEffects() | llvm::MemoryEffects::argMemOnly()); function_attribute_builder.addMemoryAttr(attribute.getMemoryEffects() | llvm::MemoryEffects::argMemOnly());
} }
@ -713,7 +711,7 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
{ {
if (attributes.function.flags0.call_no_builtins) if (attributes.function.flags0.call_no_builtins)
{ {
function_attribute_builder.addAttribute(Attribute::NoBuiltin); function_attribute_builder.addAttribute(llvm::Attribute::NoBuiltin);
} }
} }
else else
@ -728,7 +726,7 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
function_attribute_builder.addAttribute("stack-probe-size", string_ref(attributes.function.definition_stack_probe_size)); function_attribute_builder.addAttribute("stack-probe-size", string_ref(attributes.function.definition_stack_probe_size));
} }
StringRef frame_pointer_kind_name; llvm::StringRef frame_pointer_kind_name;
switch ((BBLLVMAttributeFramePointerKind) attributes.function.flags0.definition_frame_pointer_kind) switch ((BBLLVMAttributeFramePointerKind) attributes.function.flags0.definition_frame_pointer_kind)
{ {
case BBLLVMAttributeFramePointerKind::None: frame_pointer_kind_name = "none"; break; case BBLLVMAttributeFramePointerKind::None: frame_pointer_kind_name = "none"; break;
@ -745,7 +743,7 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.definition_null_pointer_is_valid) if (attributes.function.flags0.definition_null_pointer_is_valid)
{ {
function_attribute_builder.addAttribute(Attribute::NullPointerIsValid); function_attribute_builder.addAttribute(llvm::Attribute::NullPointerIsValid);
} }
if (attributes.function.flags0.definition_no_trapping_fp_math) if (attributes.function.flags0.definition_no_trapping_fp_math)
@ -812,7 +810,7 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags0.definition_non_lazy_bind) if (attributes.function.flags0.definition_non_lazy_bind)
{ {
function_attribute_builder.addAttribute(Attribute::NonLazyBind); function_attribute_builder.addAttribute(llvm::Attribute::NonLazyBind);
} }
if (attributes.function.flags0.definition_cmse_nonsecure_entry) if (attributes.function.flags0.definition_cmse_nonsecure_entry)
@ -820,12 +818,12 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
function_attribute_builder.addAttribute("cmse_nonsecure_entry"); function_attribute_builder.addAttribute("cmse_nonsecure_entry");
} }
UWTableKind unwind_table_kind; llvm::UWTableKind unwind_table_kind;
switch ((BBLLVMUWTableKind)attributes.function.flags0.definition_unwind_table_kind) switch ((BBLLVMUWTableKind)attributes.function.flags0.definition_unwind_table_kind)
{ {
case BBLLVMUWTableKind::None: unwind_table_kind = UWTableKind::None; break; case BBLLVMUWTableKind::None: unwind_table_kind = llvm::UWTableKind::None; break;
case BBLLVMUWTableKind::Sync: unwind_table_kind = UWTableKind::Sync; break; case BBLLVMUWTableKind::Sync: unwind_table_kind = llvm::UWTableKind::Sync; break;
case BBLLVMUWTableKind::Async: unwind_table_kind = UWTableKind::Async; break; case BBLLVMUWTableKind::Async: unwind_table_kind = llvm::UWTableKind::Async; break;
} }
function_attribute_builder.addUWTableAttr(unwind_table_kind); function_attribute_builder.addUWTableAttr(unwind_table_kind);
@ -837,17 +835,17 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags1.definition_stack_protect_strong) if (attributes.function.flags1.definition_stack_protect_strong)
{ {
function_attribute_builder.addAttribute(Attribute::StackProtectStrong); function_attribute_builder.addAttribute(llvm::Attribute::StackProtectStrong);
} }
if (attributes.function.flags1.definition_stack_protect) if (attributes.function.flags1.definition_stack_protect)
{ {
function_attribute_builder.addAttribute(Attribute::StackProtect); function_attribute_builder.addAttribute(llvm::Attribute::StackProtect);
} }
if (attributes.function.flags1.definition_stack_protect_req) if (attributes.function.flags1.definition_stack_protect_req)
{ {
function_attribute_builder.addAttribute(Attribute::StackProtectReq); function_attribute_builder.addAttribute(llvm::Attribute::StackProtectReq);
} }
if (attributes.function.flags1.definition_aarch64_new_za) if (attributes.function.flags1.definition_aarch64_new_za)
@ -862,25 +860,25 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
if (attributes.function.flags1.definition_optimize_none) if (attributes.function.flags1.definition_optimize_none)
{ {
function_attribute_builder.addAttribute(Attribute::OptimizeNone); function_attribute_builder.addAttribute(llvm::Attribute::OptimizeNone);
} }
if (attributes.function.flags1.definition_naked) if (attributes.function.flags1.definition_naked)
{ {
function_attribute_builder.addAttribute(Attribute::Naked); function_attribute_builder.addAttribute(llvm::Attribute::Naked);
} }
if (attributes.function.flags1.definition_inline_hint) if (attributes.function.flags1.definition_inline_hint)
{ {
function_attribute_builder.addAttribute(Attribute::InlineHint); function_attribute_builder.addAttribute(llvm::Attribute::InlineHint);
} }
} }
auto function_attributes = AttributeSet::get(context, function_attribute_builder); auto function_attributes = llvm::AttributeSet::get(context, function_attribute_builder);
auto return_attributes = build_argument_attributes(context, attributes.return_); auto return_attributes = build_argument_attributes(context, attributes.return_);
AttributeSet argument_attribute_buffer[128]; llvm::AttributeSet argument_attribute_buffer[128];
assert(attributes.argument_count < array_length(argument_attribute_buffer)); assert(attributes.argument_count < array_length(argument_attribute_buffer));
for (u64 i = 0; i < attributes.argument_count; i += 1) for (u64 i = 0; i < attributes.argument_count; i += 1)
@ -889,33 +887,33 @@ EXPORT BBLLVMAttributeListHandle llvm_attribute_list_build(LLVMContext& context,
argument_attribute_buffer[i] = attribute_set; argument_attribute_buffer[i] = attribute_set;
} }
ArrayRef<AttributeSet> argument_attributes = ArrayRef(argument_attribute_buffer, attributes.argument_count); llvm::ArrayRef<llvm::AttributeSet> argument_attributes = llvm::ArrayRef(argument_attribute_buffer, attributes.argument_count);
auto attribute_list = AttributeList::get(context, function_attributes, return_attributes, argument_attributes); auto attribute_list = llvm::AttributeList::get(context, function_attributes, return_attributes, argument_attributes);
static_assert(sizeof(AttributeList) == sizeof(uintptr_t)); static_assert(sizeof(llvm::AttributeList) == sizeof(uintptr_t));
return *(BBLLVMAttributeListHandle*)&attribute_list; return *(BBLLVMAttributeListHandle*)&attribute_list;
} }
EXPORT bool llvm_instruction_is_call_base(Instruction* instruction) EXPORT bool llvm_instruction_is_call_base(llvm::Instruction* instruction)
{ {
return isa<CallBase>(instruction); return isa<llvm::CallBase>(instruction);
} }
EXPORT void llvm_function_set_attributes(Function& function, BBLLVMAttributeListHandle attribute_list_handle) EXPORT void llvm_function_set_attributes(llvm::Function& function, BBLLVMAttributeListHandle attribute_list_handle)
{ {
auto attribute_list = *(AttributeList*)&attribute_list_handle; auto attribute_list = *(llvm::AttributeList*)&attribute_list_handle;
function.setAttributes(attribute_list); function.setAttributes(attribute_list);
} }
EXPORT void llvm_call_base_set_attributes(CallBase& call, BBLLVMAttributeListHandle attribute_list_handle) EXPORT void llvm_call_base_set_attributes(llvm::CallBase& call, BBLLVMAttributeListHandle attribute_list_handle)
{ {
auto attribute_list = *(AttributeList*)&attribute_list_handle; auto attribute_list = *(llvm::AttributeList*)&attribute_list_handle;
call.setAttributes(attribute_list); call.setAttributes(attribute_list);
} }
fn String stream_to_string(raw_string_ostream& stream) fn String stream_to_string(llvm::raw_string_ostream& stream)
{ {
// No need to call stream.flush(); because it's string-based // No need to call stream.flush(); because it's string-based
stream.flush(); stream.flush();
@ -933,20 +931,20 @@ fn String stream_to_string(raw_string_ostream& stream)
return String{ result, length }; return String{ result, length };
} }
EXPORT String llvm_function_to_string(Function& function) EXPORT String llvm_function_to_string(llvm::Function& function)
{ {
std::string buffer; std::string buffer;
raw_string_ostream os(buffer); llvm::raw_string_ostream os(buffer);
function.print(os); function.print(os);
os.flush(); os.flush();
auto result = stream_to_string(os); auto result = stream_to_string(os);
return result; return result;
} }
EXPORT bool llvm_function_verify(Function& function, String* error_message) EXPORT bool llvm_function_verify(llvm::Function& function, String* error_message)
{ {
std::string message_buffer; std::string message_buffer;
raw_string_ostream message_stream(message_buffer); llvm::raw_string_ostream message_stream(message_buffer);
bool result = verifyFunction(function, &message_stream); bool result = verifyFunction(function, &message_stream);
auto size = message_stream.str().size(); auto size = message_stream.str().size();
@ -956,22 +954,22 @@ EXPORT bool llvm_function_verify(Function& function, String* error_message)
return !result; return !result;
} }
EXPORT bool llvm_module_verify(const Module& module, String* error_message) EXPORT bool llvm_module_verify(const llvm::Module& module, String* error_message)
{ {
std::string message_buffer; std::string message_buffer;
raw_string_ostream message_stream(message_buffer); llvm::raw_string_ostream message_stream(message_buffer);
bool result = verifyModule(module, &message_stream); bool result = llvm::verifyModule(module, &message_stream);
*error_message = stream_to_string(message_stream); *error_message = stream_to_string(message_stream);
// We invert the condition because LLVM conventions are just stupid // We invert the condition because LLVM conventions are just stupid
return !result; return !result;
} }
EXPORT String llvm_module_to_string(Module* module) EXPORT String llvm_module_to_string(llvm::Module* module)
{ {
std::string buffer; std::string buffer;
raw_string_ostream stream(buffer); llvm::raw_string_ostream stream(buffer);
module->print(stream, 0); module->print(stream, 0);
return stream_to_string(stream); return stream_to_string(stream);
@ -1000,9 +998,9 @@ EXPORT String llvm_host_cpu_name()
EXPORT String llvm_host_cpu_features() EXPORT String llvm_host_cpu_features()
{ {
SubtargetFeatures Features; llvm::SubtargetFeatures Features;
#if LLVM_VERSION_MAJOR >= 19 #if LLVM_VERSION_MAJOR >= 19
auto host_cpu_features = sys::getHostCPUFeatures(); auto host_cpu_features = llvm::sys::getHostCPUFeatures();
#else #else
StringMap<bool> host_cpu_features; StringMap<bool> host_cpu_features;
if (!sys::getHostCPUFeatures(host_cpu_features)) { if (!sys::getHostCPUFeatures(host_cpu_features)) {
@ -1279,50 +1277,50 @@ struct BBLLVMTargetMachineCreate
static_assert(sizeof(BBLLVMTargetMachineCreate) == 192); static_assert(sizeof(BBLLVMTargetMachineCreate) == 192);
static_assert(BB_LLVM_TARGET_MACHINE_CREATE_PADDING_BYTE_COUNT == 4); static_assert(BB_LLVM_TARGET_MACHINE_CREATE_PADDING_BYTE_COUNT == 4);
EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate& create, String* error_message) EXPORT llvm::TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate& create, String* error_message)
{ {
std::string error_message_string; std::string error_message_string;
const Target* target = TargetRegistry::lookupTarget(string_ref(create.target_triple), error_message_string); const llvm::Target* target = llvm::TargetRegistry::lookupTarget(string_ref(create.target_triple), error_message_string);
TargetMachine* target_machine; llvm::TargetMachine* target_machine;
if (target) if (target)
{ {
std::optional<CodeModel::Model> code_model; std::optional<llvm::CodeModel::Model> code_model;
switch (create.code_model) switch (create.code_model)
{ {
case BBLLVMCodeModel::none: code_model = std::nullopt; break; case BBLLVMCodeModel::none: code_model = std::nullopt; break;
case BBLLVMCodeModel::tiny: code_model = CodeModel::Tiny; break; case BBLLVMCodeModel::tiny: code_model = llvm::CodeModel::Tiny; break;
case BBLLVMCodeModel::small: code_model = CodeModel::Small; break; case BBLLVMCodeModel::small: code_model = llvm::CodeModel::Small; break;
case BBLLVMCodeModel::kernel: code_model = CodeModel::Kernel; break; case BBLLVMCodeModel::kernel: code_model = llvm::CodeModel::Kernel; break;
case BBLLVMCodeModel::medium: code_model = CodeModel::Medium; break; case BBLLVMCodeModel::medium: code_model = llvm::CodeModel::Medium; break;
case BBLLVMCodeModel::large: code_model = CodeModel::Large; break; case BBLLVMCodeModel::large: code_model = llvm::CodeModel::Large; break;
} }
std::optional<Reloc::Model> relocation_model; std::optional<llvm::Reloc::Model> relocation_model;
switch (create.relocation_model) switch (create.relocation_model)
{ {
case BBLLVMRelocationModel::default_relocation: relocation_model = std::nullopt; break; case BBLLVMRelocationModel::default_relocation: relocation_model = std::nullopt; break;
case BBLLVMRelocationModel::static_relocation: relocation_model = Reloc::Static; break; case BBLLVMRelocationModel::static_relocation: relocation_model = llvm::Reloc::Static; break;
case BBLLVMRelocationModel::pic: relocation_model = Reloc::PIC_; break; case BBLLVMRelocationModel::pic: relocation_model = llvm::Reloc::PIC_; break;
case BBLLVMRelocationModel::dynamic_no_pic: relocation_model = Reloc::DynamicNoPIC; break; case BBLLVMRelocationModel::dynamic_no_pic: relocation_model = llvm::Reloc::DynamicNoPIC; break;
case BBLLVMRelocationModel::ropi: relocation_model = Reloc::ROPI; break; case BBLLVMRelocationModel::ropi: relocation_model = llvm::Reloc::ROPI; break;
case BBLLVMRelocationModel::rwpi: relocation_model = Reloc::RWPI; break; case BBLLVMRelocationModel::rwpi: relocation_model = llvm::Reloc::RWPI; break;
case BBLLVMRelocationModel::ropi_rwpi: relocation_model = Reloc::ROPI_RWPI; break; case BBLLVMRelocationModel::ropi_rwpi: relocation_model = llvm::Reloc::ROPI_RWPI; break;
} }
CodeGenOptLevel optimization_level; llvm::CodeGenOptLevel optimization_level;
switch (create.optimization_level) switch (create.optimization_level)
{ {
case BBLLVMCodeGenerationOptimizationLevel::none: optimization_level = CodeGenOptLevel::None; break; case BBLLVMCodeGenerationOptimizationLevel::none: optimization_level = llvm::CodeGenOptLevel::None; break;
case BBLLVMCodeGenerationOptimizationLevel::less: optimization_level = CodeGenOptLevel::Less; break; case BBLLVMCodeGenerationOptimizationLevel::less: optimization_level = llvm::CodeGenOptLevel::Less; break;
case BBLLVMCodeGenerationOptimizationLevel::normal: optimization_level = CodeGenOptLevel::Default; break; case BBLLVMCodeGenerationOptimizationLevel::normal: optimization_level = llvm::CodeGenOptLevel::Default; break;
case BBLLVMCodeGenerationOptimizationLevel::aggressive: optimization_level = CodeGenOptLevel::Aggressive; break; case BBLLVMCodeGenerationOptimizationLevel::aggressive: optimization_level = llvm::CodeGenOptLevel::Aggressive; break;
} }
// INFO: This calls the default constructor, so all LLVM defaults are set and we only override what we control // INFO: This calls the default constructor, so all LLVM defaults are set and we only override what we control
TargetOptions target_options; llvm::TargetOptions target_options;
target_options.UnsafeFPMath = create.target_options.unsafe_fp_math; target_options.UnsafeFPMath = create.target_options.unsafe_fp_math;
target_options.NoInfsFPMath = create.target_options.no_infs_fp_math; target_options.NoInfsFPMath = create.target_options.no_infs_fp_math;
@ -1341,16 +1339,16 @@ EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate
auto global_isel_abort_mode = (BBLLVMGlobalISelAbortMode)create.target_options.global_isel_abort_mode; auto global_isel_abort_mode = (BBLLVMGlobalISelAbortMode)create.target_options.global_isel_abort_mode;
switch (global_isel_abort_mode) switch (global_isel_abort_mode)
{ {
case BBLLVMGlobalISelAbortMode::disable: target_options.GlobalISelAbort = GlobalISelAbortMode::Disable; break; case BBLLVMGlobalISelAbortMode::disable: target_options.GlobalISelAbort = llvm::GlobalISelAbortMode::Disable; break;
case BBLLVMGlobalISelAbortMode::enable: target_options.GlobalISelAbort = GlobalISelAbortMode::Enable; break; case BBLLVMGlobalISelAbortMode::enable: target_options.GlobalISelAbort = llvm::GlobalISelAbortMode::Enable; break;
case BBLLVMGlobalISelAbortMode::disable_with_diag: target_options.GlobalISelAbort = GlobalISelAbortMode::DisableWithDiag; break; case BBLLVMGlobalISelAbortMode::disable_with_diag: target_options.GlobalISelAbort = llvm::GlobalISelAbortMode::DisableWithDiag; break;
} }
auto swift_async_frame_pointer = (BBLLVMSwiftAsyncFramePointerMode)create.target_options.swift_async_frame_pointer; auto swift_async_frame_pointer = (BBLLVMSwiftAsyncFramePointerMode)create.target_options.swift_async_frame_pointer;
switch (swift_async_frame_pointer) switch (swift_async_frame_pointer)
{ {
case BBLLVMSwiftAsyncFramePointerMode::deployment_based: target_options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::DeploymentBased; break; case BBLLVMSwiftAsyncFramePointerMode::deployment_based: target_options.SwiftAsyncFramePointer = llvm::SwiftAsyncFramePointerMode::DeploymentBased; break;
case BBLLVMSwiftAsyncFramePointerMode::always: target_options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always; break; case BBLLVMSwiftAsyncFramePointerMode::always: target_options.SwiftAsyncFramePointer = llvm::SwiftAsyncFramePointerMode::Always; break;
case BBLLVMSwiftAsyncFramePointerMode::never: target_options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never; break; case BBLLVMSwiftAsyncFramePointerMode::never: target_options.SwiftAsyncFramePointer = llvm::SwiftAsyncFramePointerMode::Never; break;
} }
target_options.UseInitArray = create.target_options.use_init_array; target_options.UseInitArray = create.target_options.use_init_array;
@ -1382,10 +1380,10 @@ EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate
auto bb_sections = (BBLLVMBasicBlockSection) create.target_options.bb_sections; auto bb_sections = (BBLLVMBasicBlockSection) create.target_options.bb_sections;
switch (bb_sections) switch (bb_sections)
{ {
case BBLLVMBasicBlockSection::all: target_options.BBSections = BasicBlockSection::All; break; case BBLLVMBasicBlockSection::all: target_options.BBSections = llvm::BasicBlockSection::All; break;
case BBLLVMBasicBlockSection::list: target_options.BBSections = BasicBlockSection::List; break; case BBLLVMBasicBlockSection::list: target_options.BBSections = llvm::BasicBlockSection::List; break;
case BBLLVMBasicBlockSection::preset: target_options.BBSections = BasicBlockSection::Preset; break; case BBLLVMBasicBlockSection::preset: target_options.BBSections = llvm::BasicBlockSection::Preset; break;
case BBLLVMBasicBlockSection::none: target_options.BBSections = BasicBlockSection::None; break; case BBLLVMBasicBlockSection::none: target_options.BBSections = llvm::BasicBlockSection::None; break;
} }
target_options.EmitCallSiteInfo = create.target_options.emit_call_site_information; target_options.EmitCallSiteInfo = create.target_options.emit_call_site_information;
@ -1405,57 +1403,57 @@ EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate
auto float_abi = (BBLLVMFloatAbi) create.target_options.float_abi; auto float_abi = (BBLLVMFloatAbi) create.target_options.float_abi;
switch (float_abi) switch (float_abi)
{ {
case BBLLVMFloatAbi::normal: target_options.FloatABIType = FloatABI::Default; break; case BBLLVMFloatAbi::normal: target_options.FloatABIType = llvm::FloatABI::Default; break;
case BBLLVMFloatAbi::soft: target_options.FloatABIType = FloatABI::Soft; break; case BBLLVMFloatAbi::soft: target_options.FloatABIType = llvm::FloatABI::Soft; break;
case BBLLVMFloatAbi::hard: target_options.FloatABIType = FloatABI::Hard; break; case BBLLVMFloatAbi::hard: target_options.FloatABIType = llvm::FloatABI::Hard; break;
} }
auto thread_model = (BBLLVMThreadModel) create.target_options.thread_model; auto thread_model = (BBLLVMThreadModel) create.target_options.thread_model;
switch (thread_model) switch (thread_model)
{ {
case BBLLVMThreadModel::posix: target_options.ThreadModel = ThreadModel::POSIX; break; case BBLLVMThreadModel::posix: target_options.ThreadModel = llvm::ThreadModel::POSIX; break;
case BBLLVMThreadModel::single: target_options.ThreadModel = ThreadModel::Single; break; case BBLLVMThreadModel::single: target_options.ThreadModel = llvm::ThreadModel::Single; break;
} }
auto fp_op_fusion_mode = (BBLLVMFPOpFusion) create.target_options.fp_op_fusion_mode; auto fp_op_fusion_mode = (BBLLVMFPOpFusion) create.target_options.fp_op_fusion_mode;
switch (fp_op_fusion_mode) switch (fp_op_fusion_mode)
{ {
case BBLLVMFPOpFusion::fast: target_options.AllowFPOpFusion = FPOpFusion::Fast; break; case BBLLVMFPOpFusion::fast: target_options.AllowFPOpFusion = llvm::FPOpFusion::Fast; break;
case BBLLVMFPOpFusion::standard: target_options.AllowFPOpFusion = FPOpFusion::Standard; break; case BBLLVMFPOpFusion::standard: target_options.AllowFPOpFusion = llvm::FPOpFusion::Standard; break;
case BBLLVMFPOpFusion::strict: target_options.AllowFPOpFusion = FPOpFusion::Strict; break; case BBLLVMFPOpFusion::strict: target_options.AllowFPOpFusion = llvm::FPOpFusion::Strict; break;
} }
auto eabi_version = (BBLLVMEAbi) create.target_options.eabi_version; auto eabi_version = (BBLLVMEAbi) create.target_options.eabi_version;
switch (eabi_version) switch (eabi_version)
{ {
case BBLLVMEAbi::unknown: target_options.EABIVersion = EABI::Unknown; break; case BBLLVMEAbi::unknown: target_options.EABIVersion = llvm::EABI::Unknown; break;
case BBLLVMEAbi::normal: target_options.EABIVersion = EABI::Default; break; case BBLLVMEAbi::normal: target_options.EABIVersion = llvm::EABI::Default; break;
case BBLLVMEAbi::eabi4: target_options.EABIVersion = EABI::EABI4; break; case BBLLVMEAbi::eabi4: target_options.EABIVersion = llvm::EABI::EABI4; break;
case BBLLVMEAbi::eabi5: target_options.EABIVersion = EABI::EABI5; break; case BBLLVMEAbi::eabi5: target_options.EABIVersion = llvm::EABI::EABI5; break;
case BBLLVMEAbi::gnu: target_options.EABIVersion = EABI::GNU; break; case BBLLVMEAbi::gnu: target_options.EABIVersion = llvm::EABI::GNU; break;
} }
auto debugger_kind = (BBLLVMDebuggerKind) create.target_options.debugger_kind; auto debugger_kind = (BBLLVMDebuggerKind) create.target_options.debugger_kind;
switch (debugger_kind) switch (debugger_kind)
{ {
case BBLLVMDebuggerKind::normal: target_options.DebuggerTuning = DebuggerKind::Default; break; case BBLLVMDebuggerKind::normal: target_options.DebuggerTuning = llvm::DebuggerKind::Default; break;
case BBLLVMDebuggerKind::gdb: target_options.DebuggerTuning = DebuggerKind::GDB; break; case BBLLVMDebuggerKind::gdb: target_options.DebuggerTuning = llvm::DebuggerKind::GDB; break;
case BBLLVMDebuggerKind::lldb: target_options.DebuggerTuning = DebuggerKind::LLDB; break; case BBLLVMDebuggerKind::lldb: target_options.DebuggerTuning = llvm::DebuggerKind::LLDB; break;
case BBLLVMDebuggerKind::sce: target_options.DebuggerTuning = DebuggerKind::SCE; break; case BBLLVMDebuggerKind::sce: target_options.DebuggerTuning = llvm::DebuggerKind::SCE; break;
case BBLLVMDebuggerKind::dbx: target_options.DebuggerTuning = DebuggerKind::DBX; break; case BBLLVMDebuggerKind::dbx: target_options.DebuggerTuning = llvm::DebuggerKind::DBX; break;
} }
auto exception_handling = (BBLLVMExceptionHandling) create.target_options.exception_handling; auto exception_handling = (BBLLVMExceptionHandling) create.target_options.exception_handling;
switch (exception_handling) switch (exception_handling)
{ {
case BBLLVMExceptionHandling::none: target_options.ExceptionModel = ExceptionHandling::None; break; case BBLLVMExceptionHandling::none: target_options.ExceptionModel = llvm::ExceptionHandling::None; break;
case BBLLVMExceptionHandling::dwarf_cfi: target_options.ExceptionModel = ExceptionHandling::DwarfCFI; break; case BBLLVMExceptionHandling::dwarf_cfi: target_options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI; break;
case BBLLVMExceptionHandling::setjmp_longjmp: target_options.ExceptionModel = ExceptionHandling::SjLj; break; case BBLLVMExceptionHandling::setjmp_longjmp: target_options.ExceptionModel = llvm::ExceptionHandling::SjLj; break;
case BBLLVMExceptionHandling::arm: target_options.ExceptionModel = ExceptionHandling::ARM; break; case BBLLVMExceptionHandling::arm: target_options.ExceptionModel = llvm::ExceptionHandling::ARM; break;
case BBLLVMExceptionHandling::win_eh: target_options.ExceptionModel = ExceptionHandling::WinEH; break; case BBLLVMExceptionHandling::win_eh: target_options.ExceptionModel = llvm::ExceptionHandling::WinEH; break;
case BBLLVMExceptionHandling::wasm: target_options.ExceptionModel = ExceptionHandling::Wasm; break; case BBLLVMExceptionHandling::wasm: target_options.ExceptionModel = llvm::ExceptionHandling::Wasm; break;
case BBLLVMExceptionHandling::aix: target_options.ExceptionModel = ExceptionHandling::AIX; break; case BBLLVMExceptionHandling::aix: target_options.ExceptionModel = llvm::ExceptionHandling::AIX; break;
case BBLLVMExceptionHandling::zos: target_options.ExceptionModel = ExceptionHandling::ZOS; break; case BBLLVMExceptionHandling::zos: target_options.ExceptionModel = llvm::ExceptionHandling::ZOS; break;
} }
target_options.LoopAlignment = create.target_options.loop_alignment; target_options.LoopAlignment = create.target_options.loop_alignment;
@ -1520,26 +1518,26 @@ EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate
auto emit_dwarf_unwind = (BBLLVMEmitDwarfUnwindType) create.target_options.mc.emit_dwarf_unwind; auto emit_dwarf_unwind = (BBLLVMEmitDwarfUnwindType) create.target_options.mc.emit_dwarf_unwind;
switch (emit_dwarf_unwind) switch (emit_dwarf_unwind)
{ {
case BBLLVMEmitDwarfUnwindType::always: target_options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always; break; case BBLLVMEmitDwarfUnwindType::always: target_options.MCOptions.EmitDwarfUnwind = llvm::EmitDwarfUnwindType::Always; break;
case BBLLVMEmitDwarfUnwindType::no_compact_unwind: target_options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::NoCompactUnwind; break; case BBLLVMEmitDwarfUnwindType::no_compact_unwind: target_options.MCOptions.EmitDwarfUnwind = llvm::EmitDwarfUnwindType::NoCompactUnwind; break;
case BBLLVMEmitDwarfUnwindType::normal: target_options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Default; break; case BBLLVMEmitDwarfUnwindType::normal: target_options.MCOptions.EmitDwarfUnwind = llvm::EmitDwarfUnwindType::Default; break;
} }
auto use_dwarf_directory = (BBLLVMDwarfDirectory) create.target_options.mc.use_dwarf_directory; auto use_dwarf_directory = (BBLLVMDwarfDirectory) create.target_options.mc.use_dwarf_directory;
switch (use_dwarf_directory) switch (use_dwarf_directory)
{ {
case BBLLVMDwarfDirectory::disable: target_options.MCOptions.MCUseDwarfDirectory = MCTargetOptions::DwarfDirectory::DisableDwarfDirectory; break; case BBLLVMDwarfDirectory::disable: target_options.MCOptions.MCUseDwarfDirectory = llvm::MCTargetOptions::DwarfDirectory::DisableDwarfDirectory; break;
case BBLLVMDwarfDirectory::enable: target_options.MCOptions.MCUseDwarfDirectory = MCTargetOptions::DwarfDirectory::EnableDwarfDirectory; break; case BBLLVMDwarfDirectory::enable: target_options.MCOptions.MCUseDwarfDirectory = llvm::MCTargetOptions::DwarfDirectory::EnableDwarfDirectory; break;
case BBLLVMDwarfDirectory::normal: target_options.MCOptions.MCUseDwarfDirectory = MCTargetOptions::DwarfDirectory::DefaultDwarfDirectory; break; case BBLLVMDwarfDirectory::normal: target_options.MCOptions.MCUseDwarfDirectory = llvm::MCTargetOptions::DwarfDirectory::DefaultDwarfDirectory; break;
} }
#if LLVM_VERSION_MAJOR >= 19 #if LLVM_VERSION_MAJOR >= 19
auto debug_compression_type = (BBLLVMDebugCompressionType) create.target_options.mc.debug_compression_type; auto debug_compression_type = (BBLLVMDebugCompressionType) create.target_options.mc.debug_compression_type;
switch (debug_compression_type) switch (debug_compression_type)
{ {
case BBLLVMDebugCompressionType::none: target_options.MCOptions.CompressDebugSections = DebugCompressionType::None; break; case BBLLVMDebugCompressionType::none: target_options.MCOptions.CompressDebugSections = llvm::DebugCompressionType::None; break;
case BBLLVMDebugCompressionType::zlib: target_options.MCOptions.CompressDebugSections = DebugCompressionType::Zlib; break; case BBLLVMDebugCompressionType::zlib: target_options.MCOptions.CompressDebugSections = llvm::DebugCompressionType::Zlib; break;
case BBLLVMDebugCompressionType::zstd: target_options.MCOptions.CompressDebugSections = DebugCompressionType::Zstd; break; case BBLLVMDebugCompressionType::zstd: target_options.MCOptions.CompressDebugSections = llvm::DebugCompressionType::Zstd; break;
} }
#endif #endif
@ -1562,11 +1560,11 @@ EXPORT TargetMachine* llvm_create_target_machine(const BBLLVMTargetMachineCreate
return target_machine; return target_machine;
} }
EXPORT void llvm_module_set_target(Module& module, TargetMachine& target_machine) EXPORT void llvm_module_set_target(llvm::Module& module, llvm::TargetMachine& target_machine)
{ {
module.setDataLayout(target_machine.createDataLayout()); module.setDataLayout(target_machine.createDataLayout());
auto& triple_string = target_machine.getTargetTriple().getTriple(); auto& triple_string = target_machine.getTargetTriple().getTriple();
module.setTargetTriple(StringRef(triple_string)); module.setTargetTriple(llvm::StringRef(triple_string));
} }
enum class BBLLVMOptimizationLevel : u8 enum class BBLLVMOptimizationLevel : u8
@ -1599,12 +1597,12 @@ struct BBLLVMOptimizationPipelineOptions
static_assert(sizeof(BBLLVMOptimizationPipelineOptions) == sizeof(u64)); static_assert(sizeof(BBLLVMOptimizationPipelineOptions) == sizeof(u64));
static_assert(BB_LLVM_OPTIMIZATION_PIPELINE_OPTIONS_PADDING_BIT_COUNT == 51); static_assert(BB_LLVM_OPTIMIZATION_PIPELINE_OPTIONS_PADDING_BIT_COUNT == 51);
EXPORT void llvm_module_run_optimization_pipeline(Module& module, TargetMachine& target_machine, BBLLVMOptimizationPipelineOptions options) EXPORT void llvm_module_run_optimization_pipeline(llvm::Module& module, llvm::TargetMachine& target_machine, BBLLVMOptimizationPipelineOptions options)
{ {
// TODO: PGO // TODO: PGO
// TODO: CS profile // TODO: CS profile
PipelineTuningOptions pipeline_tuning_options; llvm::PipelineTuningOptions pipeline_tuning_options;
pipeline_tuning_options.LoopUnrolling = options.loop_unrolling; pipeline_tuning_options.LoopUnrolling = options.loop_unrolling;
pipeline_tuning_options.LoopInterleaving = options.loop_interleaving; pipeline_tuning_options.LoopInterleaving = options.loop_interleaving;
pipeline_tuning_options.LoopVectorization = options.loop_vectorization; pipeline_tuning_options.LoopVectorization = options.loop_vectorization;
@ -1615,24 +1613,24 @@ EXPORT void llvm_module_run_optimization_pipeline(Module& module, TargetMachine&
// TODO: instrumentation // TODO: instrumentation
LoopAnalysisManager loop_analysis_manager; llvm::LoopAnalysisManager loop_analysis_manager;
FunctionAnalysisManager function_analysis_manager; llvm::FunctionAnalysisManager function_analysis_manager;
CGSCCAnalysisManager cgscc_analysis_manager; llvm::CGSCCAnalysisManager cgscc_analysis_manager;
ModuleAnalysisManager module_analysis_manager; llvm::ModuleAnalysisManager module_analysis_manager;
PassBuilder pass_builder(&target_machine, pipeline_tuning_options); llvm::PassBuilder pass_builder(&target_machine, pipeline_tuning_options);
if (options.assignment_tracking && options.debug_info != 0) if (options.assignment_tracking && options.debug_info != 0)
{ {
pass_builder.registerPipelineStartEPCallback([&](ModulePassManager& MPM, OptimizationLevel Level) { pass_builder.registerPipelineStartEPCallback([&](llvm::ModulePassManager& MPM, llvm::OptimizationLevel Level) {
MPM.addPass(AssignmentTrackingPass()); MPM.addPass(llvm::AssignmentTrackingPass());
}); });
} }
Triple target_triple = target_machine.getTargetTriple(); // Need to make a copy, incoming bugfix: https://github.com/llvm/llvm-project/pull/127718 llvm::Triple target_triple = target_machine.getTargetTriple(); // Need to make a copy, incoming bugfix: https://github.com/llvm/llvm-project/pull/127718
// TODO: add library (?) // TODO: add library (?)
std::unique_ptr<TargetLibraryInfoImpl> TLII(llvm::driver::createTLII(target_triple, driver::VectorLibrary::NoLibrary)); std::unique_ptr<llvm::TargetLibraryInfoImpl> TLII(llvm::driver::createTLII(target_triple, llvm::driver::VectorLibrary::NoLibrary));
function_analysis_manager.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); function_analysis_manager.registerPass([&] { return llvm::TargetLibraryAnalysis(*TLII); });
pass_builder.registerModuleAnalyses(module_analysis_manager); pass_builder.registerModuleAnalyses(module_analysis_manager);
pass_builder.registerCGSCCAnalyses(cgscc_analysis_manager); pass_builder.registerCGSCCAnalyses(cgscc_analysis_manager);
@ -1640,25 +1638,25 @@ EXPORT void llvm_module_run_optimization_pipeline(Module& module, TargetMachine&
pass_builder.registerLoopAnalyses(loop_analysis_manager); pass_builder.registerLoopAnalyses(loop_analysis_manager);
pass_builder.crossRegisterProxies(loop_analysis_manager, function_analysis_manager, cgscc_analysis_manager, module_analysis_manager); pass_builder.crossRegisterProxies(loop_analysis_manager, function_analysis_manager, cgscc_analysis_manager, module_analysis_manager);
ModulePassManager module_pass_manager; llvm::ModulePassManager module_pass_manager;
if (options.verify_module) if (options.verify_module)
{ {
module_pass_manager.addPass(VerifierPass()); module_pass_manager.addPass(llvm::VerifierPass());
} }
bool thin_lto = false; bool thin_lto = false;
bool lto = false; bool lto = false;
OptimizationLevel optimization_level; llvm::OptimizationLevel optimization_level;
switch ((BBLLVMOptimizationLevel)options.optimization_level) switch ((BBLLVMOptimizationLevel)options.optimization_level)
{ {
case BBLLVMOptimizationLevel::O0: optimization_level = OptimizationLevel::O0; break; case BBLLVMOptimizationLevel::O0: optimization_level = llvm::OptimizationLevel::O0; break;
case BBLLVMOptimizationLevel::O1: optimization_level = OptimizationLevel::O1; break; case BBLLVMOptimizationLevel::O1: optimization_level = llvm::OptimizationLevel::O1; break;
case BBLLVMOptimizationLevel::O2: optimization_level = OptimizationLevel::O2; break; case BBLLVMOptimizationLevel::O2: optimization_level = llvm::OptimizationLevel::O2; break;
case BBLLVMOptimizationLevel::O3: optimization_level = OptimizationLevel::O3; break; case BBLLVMOptimizationLevel::O3: optimization_level = llvm::OptimizationLevel::O3; break;
case BBLLVMOptimizationLevel::Os: optimization_level = OptimizationLevel::Os; break; case BBLLVMOptimizationLevel::Os: optimization_level = llvm::OptimizationLevel::Os; break;
case BBLLVMOptimizationLevel::Oz: optimization_level = OptimizationLevel::Oz; break; case BBLLVMOptimizationLevel::Oz: optimization_level = llvm::OptimizationLevel::Oz; break;
} }
// TODO: thin lto post-link // TODO: thin lto post-link
@ -1707,12 +1705,12 @@ enum class BBLLVMCodeGenerationPipelineResult : u8
failed_to_add_emit_passes = 2, failed_to_add_emit_passes = 2,
}; };
EXPORT BBLLVMCodeGenerationPipelineResult llvm_module_run_code_generation_pipeline(Module& module, TargetMachine& target_machine, BBLLVMCodeGenerationPipelineOptions options) EXPORT BBLLVMCodeGenerationPipelineResult llvm_module_run_code_generation_pipeline(llvm::Module& module, llvm::TargetMachine& target_machine, BBLLVMCodeGenerationPipelineOptions options)
{ {
// We still use the legacy PM to run the codegen pipeline since the new PM // We still use the legacy PM to run the codegen pipeline since the new PM
// does not work with the codegen pipeline. // does not work with the codegen pipeline.
// FIXME: make the new PM work with the codegen pipeline. // FIXME: make the new PM work with the codegen pipeline.
legacy::PassManager CodeGenPasses; llvm::legacy::PassManager CodeGenPasses;
#if LLVM_VERSION_MAJOR >= 19 #if LLVM_VERSION_MAJOR >= 19
if (options.optimize_when_possible) if (options.optimize_when_possible)
{ {
@ -1720,7 +1718,7 @@ EXPORT BBLLVMCodeGenerationPipelineResult llvm_module_run_code_generation_pipeli
} }
#endif #endif
raw_pwrite_stream* dwarf_object_file = 0; llvm::raw_pwrite_stream* dwarf_object_file = 0;
if (options.output_dwarf_file_path.length) if (options.output_dwarf_file_path.length)
{ {
__builtin_trap(); __builtin_trap();
@ -1728,19 +1726,19 @@ EXPORT BBLLVMCodeGenerationPipelineResult llvm_module_run_code_generation_pipeli
if (options.optimize_when_possible) if (options.optimize_when_possible)
{ {
Triple target_triple = target_machine.getTargetTriple(); // Need to make a copy, incoming bugfix: https://github.com/llvm/llvm-project/pull/127718 llvm::Triple target_triple = target_machine.getTargetTriple(); // Need to make a copy, incoming bugfix: https://github.com/llvm/llvm-project/pull/127718
// TODO: add library (?) // TODO: add library (?)
std::unique_ptr<TargetLibraryInfoImpl> TLII(llvm::driver::createTLII(target_triple, driver::VectorLibrary::NoLibrary)); std::unique_ptr<llvm::TargetLibraryInfoImpl> TLII(llvm::driver::createTLII(target_triple, llvm::driver::VectorLibrary::NoLibrary));
CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); CodeGenPasses.add(new llvm::TargetLibraryInfoWrapperPass(*TLII));
} }
std::unique_ptr<raw_pwrite_stream> stream; std::unique_ptr<llvm::raw_pwrite_stream> stream;
if (options.output_file_path.length) if (options.output_file_path.length)
{ {
std::error_code error_code; std::error_code error_code;
stream = std::make_unique<llvm::raw_fd_ostream>(string_ref(options.output_file_path), error_code, sys::fs::OF_None); stream = std::make_unique<llvm::raw_fd_ostream>(string_ref(options.output_file_path), error_code, llvm::sys::fs::OF_None);
if (error_code) if (error_code)
{ {
@ -1752,12 +1750,12 @@ EXPORT BBLLVMCodeGenerationPipelineResult llvm_module_run_code_generation_pipeli
stream = std::make_unique<llvm::raw_null_ostream>(); stream = std::make_unique<llvm::raw_null_ostream>();
} }
CodeGenFileType file_type; llvm::CodeGenFileType file_type;
switch ((BBLLVMCodeGenerationFileType)options.code_generation_file_type) switch ((BBLLVMCodeGenerationFileType)options.code_generation_file_type)
{ {
case BBLLVMCodeGenerationFileType::assembly_file: file_type = CodeGenFileType::AssemblyFile; break; case BBLLVMCodeGenerationFileType::assembly_file: file_type = llvm::CodeGenFileType::AssemblyFile; break;
case BBLLVMCodeGenerationFileType::object_file: file_type = CodeGenFileType::ObjectFile; break; case BBLLVMCodeGenerationFileType::object_file: file_type = llvm::CodeGenFileType::ObjectFile; break;
case BBLLVMCodeGenerationFileType::null: file_type = CodeGenFileType::Null; break; case BBLLVMCodeGenerationFileType::null: file_type = llvm::CodeGenFileType::Null; break;
} }
auto disable_verify = !options.verify_module; auto disable_verify = !options.verify_module;

View File

@ -1,10 +1,85 @@
#include <lib.h> #pragma once
namespace llvm #include <compiler.h>
enum class DwarfEmissionKind
{ {
class Type; none,
class Value; full,
} line_tables_only,
};
enum class DwarfSourceLanguage
{
C89,
C,
Ada83,
C_plus_plus,
Cobol74,
Cobol85,
Fortran77,
Fortran90,
Pascal83,
Modula2,
// New in DWARF v3:
Java,
C99,
Ada95,
Fortran95,
PLI,
ObjC,
ObjC_plus_plus,
UPC,
D,
// New in DWARF v4:
Python,
// New in DWARF v5:
OpenCL,
Go,
Modula3,
Haskell,
C_plus_plus_03,
C_plus_plus_11,
OCaml,
Rust,
C11,
Swift,
Julia,
Dylan,
C_plus_plus_14,
Fortran03,
Fortran08,
RenderScript,
BLISS,
Kotlin,
Zig,
Crystal,
C_plus_plus_17,
C_plus_plus_20,
C17,
Fortran18,
Ada2005,
Ada2012,
HIP,
Assembly,
C_sharp,
Mojo,
GLSL,
GLSL_ES,
HLSL,
OpenCL_CPP,
CPP_for_OpenCL,
SYCL,
Ruby,
Move,
Hylo,
// Vendor extensions:
Mips_Assembler,
GOOGLE_RenderScript,
BORLAND_Delphi,
};
fn bool llvm_initialized = false; fn bool llvm_initialized = false;
@ -19,6 +94,17 @@ extern "C" String llvm_default_target_triple();
extern "C" String llvm_host_cpu_name(); extern "C" String llvm_host_cpu_name();
extern "C" String llvm_host_cpu_features(); extern "C" String llvm_host_cpu_features();
extern "C" llvm::LLVMContext* LLVMContextCreate();
extern "C" llvm::Module* llvm_context_create_module(llvm::LLVMContext* context, String name);
extern "C" llvm::Builder* LLVMCreateBuilderInContext(llvm::LLVMContext* context);
extern "C" llvm::Type* LLVMVoidTypeInContext(llvm::LLVMContext* context);
extern "C" llvm::Type* LLVMPointerTypeInContext(llvm::LLVMContext* context);
extern "C" LLVMIntrinsicId LLVMLookupIntrinsicID(const u8* name_pointer, u64 name_length);
extern "C" llvm::DIBuilder* LLVMCreateDIBuilder(llvm::Module* module);
extern "C" llvm::DIFile* LLVMDIBuilderCreateFile(llvm::DIBuilder* builder, const u8* file_name_pointer, u64 file_name_length, const u8* directory_name_pointer, u64 directory_name_length);
extern "C" llvm::DICompileUnit* LLVMDIBuilderCreateCompileUnit(llvm::DIBuilder* builder, DwarfSourceLanguage dwarf_source_language, llvm::DIFile* file, const u8* producer_name_pointer, u64 producer_name_length, int is_optimized, const u8* flag_pointer, u64 flag_length, unsigned runtime_version, const u8* split_name_pointer, u64 split_name_length, DwarfEmissionKind emission_kind, unsigned debug_with_offset_id, int split_debug_inlining, int debug_info_for_profiling, const u8* sysroot_name_pointer, u64 sysroot_name_length, const u8* sdk_name_pointer, u64 sdk_name_length);
struct LLVMGlobal struct LLVMGlobal
{ {
String host_triple; String host_triple;
@ -28,9 +114,10 @@ struct LLVMGlobal
global_variable LLVMGlobal llvm_global; global_variable LLVMGlobal llvm_global;
fn void initialize_all() fn void llvm_initialize_all_raw()
{ {
assert(!llvm_initialized); assert(!llvm_initialized);
LLVMInitializeX86TargetInfo(); LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target(); LLVMInitializeX86Target();
LLVMInitializeX86TargetMC(); LLVMInitializeX86TargetMC();
@ -44,3 +131,11 @@ fn void initialize_all()
.host_cpu_features = llvm_host_cpu_features(), .host_cpu_features = llvm_host_cpu_features(),
}; };
} }
fn void llvm_initialize_all()
{
if (!llvm_initialized)
{
llvm_initialize_all_raw();
}
}