Compare commits

..

No commits in common. "81fd0aebfd1865578ada88ed72934f2268bac957" and "329d5b9f732e8b7ea3d4f15537f292e0e2b15d1c" have entirely different histories.

4 changed files with 870 additions and 2680 deletions

View File

@ -51,6 +51,3 @@ target_link_libraries(bb PUBLIC llvm_bindings)
add_compile_options(-Wall -Wextra -pedantic -Wpedantic -Werror -Wno-c99-extensions -Wno-unused-function -Wno-missing-designated-field-initializers -fno-signed-char -fwrapv -fno-strict-aliasing)
add_compile_definitions(CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}")
add_compile_definitions(BB_CI=${BB_CI})
# add_compile_options(-fsanitize=address)
# add_link_options(-fsanitize=address)

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ fn LLVMValueRef llvm_module_create_function(Arena* arena, LLVMModuleRef module,
return function;
}
fn LLVMValueRef llvm_create_global_variable(LLVMModuleRef module, LLVMTypeRef type, bool is_constant, LLVMLinkage linkage_type, LLVMValueRef initial_value, String name, LLVMThreadLocalMode thread_local_mode, bool externally_initialized, u32 alignment, LLVMUnnamedAddr unnamed_address)
fn LLVMValueRef llvm_module_create_global_variable(LLVMModuleRef module, LLVMTypeRef type, bool is_constant, LLVMLinkage linkage_type, LLVMValueRef initial_value, String name, LLVMThreadLocalMode thread_local_mode, bool externally_initialized, u32 alignment, LLVMUnnamedAddr unnamed_address)
{
assert(name.pointer[name.length] == 0);
auto global = LLVMAddGlobal(module, type, (char*)name.pointer);
@ -609,19 +609,21 @@ fn bool contains_no_user_data(Type* type, u64 start, u64 end)
{
case TypeId::structure:
{
u64 offset = 0;
for (auto& field: type->structure.fields)
{
auto field_offset = field.offset;
if (field_offset >= end)
if (offset >= end)
{
break;
}
auto field_start = field_offset < start ? start - field_offset : 0;
if (!contains_no_user_data(field.type, field_start, end - field_offset))
auto field_start = offset < start ? start - offset : 0;
if (!contains_no_user_data(field.type, field_start, end - offset))
{
return false;
}
offset += get_byte_size(field.type);
}
return true;
@ -853,7 +855,7 @@ fn AbiSystemVClassifyResult abi_system_v_classify_type(Type* type, AbiSystemVCla
u64 vector_size = 16;
if (byte_size > 16 && (byte_size != element_size || byte_size > vector_size))
if (byte_size > 16 && (byte_size != get_byte_size(element_type) || byte_size > vector_size))
{
unreachable();
}
@ -2539,6 +2541,7 @@ fn Global* get_enum_name_array_global(Module* module, Type* enum_type)
auto u64_type = uint64(module);
resolve_type_in_place(module, u8_type);
resolve_type_in_place(module, u64_type);
LLVMValueRef name_before = 0;
LLVMValueRef name_constant_buffer[64];
for (u32 i = 0; i < fields.length; i += 1)
@ -2552,9 +2555,11 @@ fn Global* get_enum_name_array_global(Module* module, Type* enum_type)
string_literal("."),
field.name,
};
unsigned address_space = 0;
auto initial_value = LLVMConstStringInContext2(module->llvm.context, (char*)field.name.pointer, field.name.length, false);
u32 alignment = 1;
auto name_global = llvm_create_global_variable(module->llvm.module, LLVMArrayType2(u8_type->llvm.abi, field.name.length + null_terminate), is_constant, LLVMInternalLinkage, initial_value, arena_join_string(module->arena, array_to_slice(name_parts)), LLVMNotThreadLocal, false, alignment, LLVMGlobalUnnamedAddr);
auto name_global = llvm_module_create_global_variable(module->llvm.module, LLVMArrayType2(u8_type->llvm.abi, field.name.length + null_terminate), is_constant, LLVMInternalLinkage, initial_value, arena_join_string(module->arena, array_to_slice(name_parts)), LLVMNotThreadLocal, false, alignment, LLVMGlobalUnnamedAddr);
name_before = name_global;
LLVMValueRef constants[] = {
name_global,
LLVMConstInt(u64_type->llvm.abi, field.name.length, false),
@ -2568,7 +2573,8 @@ fn Global* get_enum_name_array_global(Module* module, Type* enum_type)
auto name_array = LLVMConstArray2(slice_type->llvm.abi, name_constant_buffer, array_element_count);
auto name_array_type = LLVMArrayType2(slice_type->llvm.abi, array_element_count);
auto is_constant = true;
auto name_array_variable = llvm_create_global_variable(module->llvm.module, name_array_type, is_constant, LLVMInternalLinkage, name_array, string_literal("name.array.enum"), LLVMNotThreadLocal, false, get_byte_alignment(slice_type), LLVMGlobalUnnamedAddr);
unsigned address_space = 0;
auto name_array_variable = llvm_module_create_global_variable(module->llvm.module, name_array_type, is_constant, LLVMInternalLinkage, name_array, string_literal("name.array.enum"), LLVMNotThreadLocal, false, get_byte_alignment(slice_type), LLVMGlobalUnnamedAddr);
auto global_type = get_array_type(module, slice_type, array_element_count);
resolve_type_in_place(module, global_type);
@ -4277,8 +4283,9 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal
auto value_array_variable_type = LLVMArrayType2(enum_value_type, array_element_count);
auto is_constant = true;
LLVMThreadLocalMode thread_local_mode = LLVMNotThreadLocal;
unsigned address_space = 0;
auto externally_initialized = false;
auto value_array_variable = llvm_create_global_variable(module->llvm.module, value_array_variable_type, is_constant, LLVMInternalLinkage, value_array, string_literal("value.array.enum"), thread_local_mode, externally_initialized, enum_alignment, LLVMGlobalUnnamedAddr);
auto value_array_variable = llvm_module_create_global_variable(module->llvm.module, value_array_variable_type, is_constant, LLVMInternalLinkage, value_array, string_literal("value.array.enum"), thread_local_mode, externally_initialized, enum_alignment, LLVMGlobalUnnamedAddr);
auto* entry_block = LLVMAppendBasicBlockInContext(module->llvm.context, llvm_function, "entry");
auto* return_block = LLVMAppendBasicBlockInContext(module->llvm.context, llvm_function, "return_block");
@ -5172,7 +5179,7 @@ fn SliceEmitResult emit_string_literal(Module* module, Value* value)
LLVMThreadLocalMode tlm = LLVMNotThreadLocal;
bool externally_initialized = false;
u32 alignment = 1;
auto global = llvm_create_global_variable(module->llvm.module, string_type, is_constant, LLVMInternalLinkage, constant_string, string_literal("conststring"), tlm, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_module_create_global_variable(module->llvm.module, string_type, is_constant, LLVMInternalLinkage, constant_string, string_literal("conststring"), tlm, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
return { global, LLVMConstInt(uint64(module)->llvm.abi, length, false) };
} break;
@ -5209,22 +5216,6 @@ fn void invalidate_analysis(Module* module, Value* value)
{
invalidate_analysis(module, value->unary.value);
} break;
case ValueId::slice_expression:
{
invalidate_analysis(module, value->slice_expression.array_like);
auto start = value->slice_expression.start;
auto end = value->slice_expression.end;
if (start)
{
invalidate_analysis(module, start);
}
if (end)
{
invalidate_analysis(module, end);
}
} break;
default: trap();
}
@ -5561,10 +5552,11 @@ fn LLVMValueRef emit_call(Module* module, Value* value, LLVMValueRef left_llvm,
bool is_constant = true;
LLVMLinkage linkage_type = LLVMInternalLinkage;
LLVMThreadLocalMode thread_local_mode = {};
u32 address_space = 0;
bool externally_initialized = false;
auto alignment = get_byte_alignment(semantic_argument_type);
auto global = llvm_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("const.struct"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_module_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("conststruct"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
for (u32 i = 0; i < coerce_fields.length; i += 1)
{
@ -5715,7 +5707,7 @@ fn LLVMValueRef emit_call(Module* module, Value* value, LLVMValueRef left_llvm,
bool externally_initialized = false;
auto alignment = get_byte_alignment(semantic_argument_type);
auto global = llvm_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("indirect.const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_module_create_global_variable(module->llvm.module, semantic_argument_type->llvm.memory, is_constant, linkage_type, semantic_call_argument_value->llvm, string_literal("indirect.const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
llvm_abi_argument_value_buffer[abi_argument_count] = global;
abi_argument_count += 1;
@ -5848,6 +5840,7 @@ fn LLVMValueRef emit_call(Module* module, Value* value, LLVMValueRef left_llvm,
auto destination_type = return_abi.semantic_type;
auto source_value = llvm_call;
auto source_type = raw_function_type->function.abi.abi_return_type;
auto destination_size = get_byte_size(destination_type);
@ -6456,10 +6449,11 @@ fn void emit_assignment(Module* module, LLVMValueRef left_llvm, Type* left_type,
bool is_constant = true;
LLVMLinkage linkage_type = LLVMInternalLinkage;
LLVMThreadLocalMode thread_local_mode = {};
u32 address_space = 0;
bool externally_initialized = false;
auto alignment = get_byte_alignment(resolved_value_type);
auto global = llvm_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("array.init"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_module_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("array.init"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
u64 memcpy_size = get_byte_size(resolved_value_type);
LLVMBuildMemCpy(module->llvm.builder, left_llvm, alignment, global, alignment, LLVMConstInt(uint64_type->llvm.abi, memcpy_size, false));
@ -6532,7 +6526,7 @@ fn void emit_assignment(Module* module, LLVMValueRef left_llvm, Type* left_type,
LLVMLinkage linkage_type = LLVMInternalLinkage;
LLVMThreadLocalMode thread_local_mode = LLVMNotThreadLocal;
bool externally_initialized = false;
auto global = llvm_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_module_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
LLVMBuildMemCpy(module->llvm.builder, left_llvm, alignment, global, alignment, byte_size_value);
}
else
@ -7074,8 +7068,7 @@ fn void analyze_block(Module* module, Block* block)
fn LLVMValueRef emit_constant_array(Module* module, Slice<Value*> elements, Type* element_type)
{
LLVMValueRef value_buffer[128];
assert(elements.length <= array_length(value_buffer));
LLVMValueRef value_buffer[64];
resolve_type_in_place(module, element_type);
@ -7336,7 +7329,7 @@ fn void emit_value(Module* module, Value* value, TypeKind type_kind, bool expect
assert(array_type->id == TypeId::array);
resolve_type_in_place(module, array_type);
auto alignment = get_byte_alignment(resolved_value_type);
auto value_array_variable = llvm_create_global_variable(module->llvm.module, array_type->llvm.memory, is_constant, LLVMInternalLinkage, array_value, string_literal("enum.values"), LLVMNotThreadLocal, 0, alignment, LLVMGlobalUnnamedAddr);
auto value_array_variable = llvm_module_create_global_variable(module->llvm.module, array_type->llvm.memory, is_constant, LLVMInternalLinkage, array_value, string_literal("enum.values"), LLVMNotThreadLocal, 0, alignment, LLVMGlobalUnnamedAddr);
llvm_value = value_array_variable;
} break;
}
@ -8622,10 +8615,6 @@ fn void analyze_statement(Module* module, Scope* scope, Statement* statement, u3
if (else_clause_index == invalid_clause_index)
{
LLVMPositionBuilderAtEnd(module->llvm.builder, else_block);
if (module->has_debug_info && !build_mode_is_optimized(module->build_mode))
{
emit_intrinsic_call(module, IntrinsicIndex::trap, {}, {});
}
LLVMBuildUnreachable(module->llvm.builder);
LLVMClearInsertionPosition(module->llvm.builder);
}
@ -8689,16 +8678,6 @@ fn void analyze_statement(Module* module, Scope* scope, Statement* statement, u3
Type* aggregate_type = 0;
if (right->kind == ValueKind::left && right->type->id != TypeId::pointer)
{
if (!type_is_slice(right->type))
{
report_error();
}
right->kind = ValueKind::right;
}
switch (right->kind)
{
case ValueKind::right:
@ -9525,7 +9504,7 @@ void emit(Module* module)
bool externally_initialized = false;
auto alignment = get_byte_alignment(global_type);
auto global_llvm = llvm_create_global_variable(module->llvm.module, global_type->llvm.memory, is_constant, linkage, global->variable.initial_value->llvm, global->variable.name, thread_local_mode, externally_initialized, alignment, LLVMNoUnnamedAddr);
auto global_llvm = llvm_module_create_global_variable(module->llvm.module, global_type->llvm.memory, is_constant, linkage, global->variable.initial_value->llvm, global->variable.name, thread_local_mode, externally_initialized, alignment, LLVMNoUnnamedAddr);
global->variable.storage->llvm = global_llvm;
global->variable.storage->type = get_pointer_type(module, global_type);

View File

@ -1937,7 +1937,7 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder)
case TokenId::left_bracket:
{
u64 element_count = 0;
Value* value_buffer[128];
Value* value_buffer[64];
skip_space(module);
@ -1976,7 +1976,6 @@ fn Value* parse_left(Module* module, Scope* scope, ValueBuilder builder)
}
auto value = parse_value(module, scope, {});
assert(element_count < array_length(value_buffer));
value_buffer[element_count] = value;
element_count += 1;
@ -2823,7 +2822,7 @@ fn Statement* parse_statement(Module* module, Scope* scope)
Value* right_value_buffer[64];
u64 right_value_count = 0;
right_value_buffer[right_value_count] = parse_value(module, scope, {});
right_value_buffer[right_value_count] = parse_value(module, scope, { .kind = ValueKind::left });
right_value_count += 1;
skip_space(module);
@ -2840,17 +2839,15 @@ fn Statement* parse_statement(Module* module, Scope* scope)
report_error();
}
right_value_buffer[0]->kind = ValueKind::right;
right_value_buffer[right_value_count] = parse_value(module, scope, {});
right_value_count += 1;
expect_character(module, right_parenthesis);
kind = ForEachKind::range;
} break;
case TokenId::right_parenthesis:
{
right_value_buffer[0]->kind = ValueKind::left;
kind = ForEachKind::slice;
} break;
case TokenId::right_parenthesis: kind = ForEachKind::slice; break;
default: report_error();
}