Compare commits
No commits in common. "81fd0aebfd1865578ada88ed72934f2268bac957" and "329d5b9f732e8b7ea3d4f15537f292e0e2b15d1c" have entirely different histories.
81fd0aebfd
...
329d5b9f73
@ -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)
|
||||
|
3459
src/compiler.bbb
3459
src/compiler.bbb
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user