Eliminate use of LLVMGetElementType for pointers

This commit is contained in:
gingerBill
2022-08-09 15:36:18 +01:00
parent 076700bd22
commit cb0a59bb2c
9 changed files with 164 additions and 126 deletions

View File

@@ -29,6 +29,8 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
old_memory: rawptr, old_size: int, location := #caller_location) -> ([]byte, runtime.Allocator_Error) {
la := (^Log_Allocator)(allocator_data)
padding := " " if la.prefix != "" else ""
if !la.locked {
la.locked = true
defer la.locked = false
@@ -38,7 +40,7 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
logf(
level=la.level,
fmt_str = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)",
args = {la.prefix, " " if la.prefix != "" else "", size, alignment},
args = {la.prefix, padding, size, alignment},
location = location,
)
case .Free:
@@ -46,14 +48,14 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)",
args = {la.prefix, " " if la.prefix != "" else "", old_memory, old_size},
args = {la.prefix, padding, old_memory, old_size},
location = location,
)
} else {
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)",
args = {la.prefix, " " if la.prefix != "" else "", old_memory},
args = {la.prefix, padding, old_memory},
location = location,
)
}
@@ -61,32 +63,45 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free_All)",
args = {la.prefix, " " if la.prefix != "" else ""},
args = {la.prefix, padding},
location = location,
)
case .Resize:
logf(
level=la.level,
fmt_str = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)",
args = {la.prefix, " " if la.prefix != "" else "", old_memory, old_size, size, alignment},
args = {la.prefix, padding, old_memory, old_size, size, alignment},
location = location,
)
case .Query_Features:
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR(mode=.Query_Features)",
args = {la.prefix, " " if la.prefix != "" else ""},
args = {la.prefix, padding},
location = location,
)
case .Query_Info:
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR(mode=.Query_Info)",
args = {la.prefix, " " if la.prefix != "" else ""},
args = {la.prefix, padding},
location = location,
)
}
}
return la.allocator.procedure(la.allocator.data, mode, size, alignment, old_memory, old_size, location)
data, err := la.allocator.procedure(la.allocator.data, mode, size, alignment, old_memory, old_size, location)
if !la.locked {
la.locked = true
defer la.locked = false
if err != nil {
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR ERROR=%v",
args = {la.prefix, padding, error},
location = location,
)
}
}
return data, err
}

View File

@@ -62,7 +62,7 @@ bool lb_is_type_kind(LLVMTypeRef type, LLVMTypeKind kind) {
return LLVMGetTypeKind(type) == kind;
}
LLVMTypeRef lb_function_type_to_llvm_ptr(lbFunctionType *ft, bool is_var_arg) {
LLVMTypeRef lb_function_type_to_llvm_raw(lbFunctionType *ft, bool is_var_arg) {
unsigned arg_count = cast(unsigned)ft->args.count;
unsigned offset = 0;
@@ -108,10 +108,16 @@ LLVMTypeRef lb_function_type_to_llvm_ptr(lbFunctionType *ft, bool is_var_arg) {
}
unsigned total_arg_count = arg_index;
LLVMTypeRef func_type = LLVMFunctionType(ret, args, total_arg_count, is_var_arg);
return LLVMPointerType(func_type, 0);
return func_type;
}
// LLVMTypeRef lb_function_type_to_llvm_ptr(lbFunctionType *ft, bool is_var_arg) {
// LLVMTypeRef func_type = lb_function_type_to_llvm_raw(ft, is_var_arg);
// return LLVMPointerType(func_type, 0);
// }
void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType *ft, ProcCallingConvention calling_convention) {
if (ft == nullptr) {
return;

View File

@@ -739,11 +739,11 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
lb_begin_procedure_body(p);
if (startup_type_info) {
LLVMBuildCall2(p->builder, lb_llvm_get_pointer_type(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, startup_type_info->type), startup_type_info->value, nullptr, 0, "");
}
if (objc_names) {
LLVMBuildCall2(p->builder, lb_llvm_get_pointer_type(lb_type(main_module, objc_names->type)), objc_names->value, nullptr, 0, "");
LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, objc_names->type), objc_names->value, nullptr, 0, "");
}
for_array(i, global_variables) {

View File

@@ -127,6 +127,7 @@ struct lbModule {
AstPackage *pkg; // associated
PtrMap<Type *, LLVMTypeRef> types;
PtrMap<Type *, LLVMTypeRef> func_raw_types;
PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *
i32 internal_type_level;
@@ -330,7 +331,8 @@ lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_b
void lb_end_procedure(lbProcedure *p);
LLVMTypeRef lb_type(lbModule *m, Type *type);
LLVMTypeRef lb_type(lbModule *m, Type *type);
LLVMTypeRef llvm_get_element_type(LLVMTypeRef type);
lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append=false);
@@ -343,7 +345,6 @@ lbValue lb_const_int(lbModule *m, Type *type, u64 value);
lbAddr lb_addr(lbValue addr);
Type *lb_addr_type(lbAddr const &addr);
LLVMTypeRef lb_llvm_get_pointer_type(LLVMTypeRef type);
LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);

View File

@@ -3345,7 +3345,7 @@ lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
default: GB_PANIC("Unhandled inline asm dialect"); break;
}
LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, t));
LLVMTypeRef func_type = lb_type_internal_for_procedures_raw(p->module, t);
LLVMValueRef the_asm = llvm_get_inline_asm(func_type, asm_string, constraints_string, ia->has_side_effects, ia->has_side_effects, dialect);
GB_ASSERT(the_asm != nullptr);
return {the_asm, t};

View File

@@ -56,6 +56,7 @@ void lb_init_module(lbModule *m, Checker *c) {
gbAllocator a = heap_allocator();
map_init(&m->types, a);
map_init(&m->func_raw_types, a);
map_init(&m->struct_field_remapping, a);
map_init(&m->values, a);
map_init(&m->soa_values, a);
@@ -1416,6 +1417,116 @@ String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
}
LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
Type *original_type = type;
type = base_type(original_type);
GB_ASSERT(type->kind == Type_Proc);
LLVMTypeRef *found = map_get(&m->func_raw_types, type);
if (found) {
return *found;
}
unsigned param_count = 0;
if (type->Proc.calling_convention == ProcCC_Odin) {
param_count += 1;
}
if (type->Proc.param_count != 0) {
GB_ASSERT(type->Proc.params->kind == Type_Tuple);
for_array(i, type->Proc.params->Tuple.variables) {
Entity *e = type->Proc.params->Tuple.variables[i];
if (e->kind != Entity_Variable) {
continue;
}
if (e->flags & EntityFlag_CVarArg) {
continue;
}
param_count += 1;
}
}
m->internal_type_level += 1;
defer (m->internal_type_level -= 1);
LLVMTypeRef ret = nullptr;
LLVMTypeRef *params = gb_alloc_array(permanent_allocator(), LLVMTypeRef, param_count);
if (type->Proc.result_count != 0) {
Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
ret = lb_type(m, single_ret);
if (ret != nullptr) {
if (is_type_boolean(single_ret) &&
is_calling_convention_none(type->Proc.calling_convention) &&
type_size_of(single_ret) <= 1) {
ret = LLVMInt1TypeInContext(m->ctx);
}
}
}
unsigned param_index = 0;
if (type->Proc.param_count != 0) {
GB_ASSERT(type->Proc.params->kind == Type_Tuple);
for_array(i, type->Proc.params->Tuple.variables) {
Entity *e = type->Proc.params->Tuple.variables[i];
if (e->kind != Entity_Variable) {
continue;
}
if (e->flags & EntityFlag_CVarArg) {
continue;
}
Type *e_type = reduce_tuple_to_single_type(e->type);
LLVMTypeRef param_type = nullptr;
if (e->flags & EntityFlag_ByPtr) {
param_type = lb_type(m, alloc_type_pointer(e_type));
} else if (is_type_boolean(e_type) &&
type_size_of(e_type) <= 1) {
param_type = LLVMInt1TypeInContext(m->ctx);
} else {
if (is_type_proc(e_type)) {
param_type = lb_type(m, t_rawptr);
} else {
param_type = lb_type(m, e_type);
}
}
params[param_index++] = param_type;
}
}
if (param_index < param_count) {
params[param_index++] = lb_type(m, t_rawptr);
}
GB_ASSERT(param_index == param_count);
lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, type->Proc.calling_convention);
{
for_array(j, ft->args) {
auto arg = ft->args[j];
GB_ASSERT_MSG(LLVMGetTypeContext(arg.type) == ft->ctx,
"\n\t%s %td/%td"
"\n\tArgTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
LLVMPrintTypeToString(arg.type),
j, ft->args.count,
LLVMGetTypeContext(arg.type), ft->ctx, LLVMGetGlobalContext());
}
GB_ASSERT_MSG(LLVMGetTypeContext(ft->ret.type) == ft->ctx,
"\n\t%s"
"\n\tRetTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
LLVMPrintTypeToString(ft->ret.type),
LLVMGetTypeContext(ft->ret.type), ft->ctx, LLVMGetGlobalContext());
}
map_set(&m->function_type_map, type, ft);
LLVMTypeRef new_abi_fn_type = lb_function_type_to_llvm_raw(ft, type->Proc.c_vararg);
GB_ASSERT_MSG(LLVMGetTypeContext(new_abi_fn_type) == m->ctx,
"\n\tFuncTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
LLVMGetTypeContext(new_abi_fn_type), m->ctx, LLVMGetGlobalContext());
map_set(&m->func_raw_types, type, new_abi_fn_type);
return new_abi_fn_type;
}
LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
LLVMContextRef ctx = m->ctx;
i64 size = type_size_of(type); // Check size
@@ -1919,103 +2030,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
if (m->internal_type_level > 1) { // TODO HACK(bill): is this really enough?
return LLVMPointerType(LLVMIntTypeInContext(m->ctx, 8), 0);
} else {
unsigned param_count = 0;
if (type->Proc.calling_convention == ProcCC_Odin) {
param_count += 1;
}
if (type->Proc.param_count != 0) {
GB_ASSERT(type->Proc.params->kind == Type_Tuple);
for_array(i, type->Proc.params->Tuple.variables) {
Entity *e = type->Proc.params->Tuple.variables[i];
if (e->kind != Entity_Variable) {
continue;
}
if (e->flags & EntityFlag_CVarArg) {
continue;
}
param_count += 1;
}
}
m->internal_type_level += 1;
defer (m->internal_type_level -= 1);
LLVMTypeRef ret = nullptr;
LLVMTypeRef *params = gb_alloc_array(permanent_allocator(), LLVMTypeRef, param_count);
if (type->Proc.result_count != 0) {
Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
ret = lb_type(m, single_ret);
if (ret != nullptr) {
if (is_type_boolean(single_ret) &&
is_calling_convention_none(type->Proc.calling_convention) &&
type_size_of(single_ret) <= 1) {
ret = LLVMInt1TypeInContext(m->ctx);
}
}
}
unsigned param_index = 0;
if (type->Proc.param_count != 0) {
GB_ASSERT(type->Proc.params->kind == Type_Tuple);
for_array(i, type->Proc.params->Tuple.variables) {
Entity *e = type->Proc.params->Tuple.variables[i];
if (e->kind != Entity_Variable) {
continue;
}
if (e->flags & EntityFlag_CVarArg) {
continue;
}
Type *e_type = reduce_tuple_to_single_type(e->type);
LLVMTypeRef param_type = nullptr;
if (e->flags & EntityFlag_ByPtr) {
param_type = lb_type(m, alloc_type_pointer(e_type));
} else if (is_type_boolean(e_type) &&
type_size_of(e_type) <= 1) {
param_type = LLVMInt1TypeInContext(m->ctx);
} else {
if (is_type_proc(e_type)) {
param_type = lb_type(m, t_rawptr);
} else {
param_type = lb_type(m, e_type);
}
}
params[param_index++] = param_type;
}
}
if (param_index < param_count) {
params[param_index++] = lb_type(m, t_rawptr);
}
GB_ASSERT(param_index == param_count);
lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, type->Proc.calling_convention);
{
for_array(j, ft->args) {
auto arg = ft->args[j];
GB_ASSERT_MSG(LLVMGetTypeContext(arg.type) == ft->ctx,
"\n\t%s %td/%td"
"\n\tArgTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
LLVMPrintTypeToString(arg.type),
j, ft->args.count,
LLVMGetTypeContext(arg.type), ft->ctx, LLVMGetGlobalContext());
}
GB_ASSERT_MSG(LLVMGetTypeContext(ft->ret.type) == ft->ctx,
"\n\t%s"
"\n\tRetTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
LLVMPrintTypeToString(ft->ret.type),
LLVMGetTypeContext(ft->ret.type), ft->ctx, LLVMGetGlobalContext());
}
map_set(&m->function_type_map, type, ft);
LLVMTypeRef new_abi_fn_ptr_type = lb_function_type_to_llvm_ptr(ft, type->Proc.c_vararg);
LLVMTypeRef new_abi_fn_type = lb_llvm_get_pointer_type(new_abi_fn_ptr_type);
GB_ASSERT_MSG(LLVMGetTypeContext(new_abi_fn_type) == m->ctx,
"\n\tFuncTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
LLVMGetTypeContext(new_abi_fn_type), m->ctx, LLVMGetGlobalContext());
return new_abi_fn_ptr_type;
LLVMTypeRef proc_raw_type = lb_type_internal_for_procedures_raw(m, type);
return LLVMPointerType(proc_raw_type, 0);
}
break;

View File

@@ -129,8 +129,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
}
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
LLVMTypeRef func_ptr_type = lb_type(m, p->type);
LLVMTypeRef func_type = lb_llvm_get_pointer_type(func_ptr_type);
LLVMTypeRef func_type = lb_get_procedure_raw_type(m, p->type);
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
@@ -354,8 +353,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
LLVMTypeRef func_ptr_type = lb_type(m, p->type);
LLVMTypeRef func_type = lb_llvm_get_pointer_type(func_ptr_type);
LLVMTypeRef func_type = lb_get_procedure_raw_type(m, p->type);
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
@@ -753,12 +751,12 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
GB_ASSERT(curr_block != p->decl_block->block);
{
LLVMTypeRef ftp = lb_type(p->module, value.type);
LLVMTypeRef fnp = lb_type_internal_for_procedures_raw(p->module, value.type);
LLVMTypeRef ftp = LLVMPointerType(fnp, 0);
LLVMValueRef fn = value.value;
if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
}
LLVMTypeRef fnp = lb_llvm_get_pointer_type(LLVMTypeOf(fn));
GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
{
@@ -2723,7 +2721,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
{
Type *param_types[2] = {t_u32, t_u32};
Type *type = alloc_type_proc_from_types(param_types, gb_count_of(param_types), tv.type, false, ProcCC_None);
LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, type));
LLVMTypeRef func_type = lb_get_procedure_raw_type(p->module, type);
LLVMValueRef the_asm = llvm_get_inline_asm(
func_type,
str_lit("cpuid"),
@@ -2743,7 +2741,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
case BuiltinProc_x86_xgetbv:
{
Type *type = alloc_type_proc_from_types(&t_u32, 1, tv.type, false, ProcCC_None);
LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, type));
LLVMTypeRef func_type = lb_get_procedure_raw_type(p->module, type);
LLVMValueRef the_asm = llvm_get_inline_asm(
func_type,
str_lit("xgetbv"),

View File

@@ -130,12 +130,16 @@ lbValue lb_get_type_info_ptr(lbModule *m, Type *type) {
return res;
}
// The use of this method needs to be eliminated.
LLVMTypeRef lb_llvm_get_pointer_type(LLVMTypeRef type)
{
// NOTE: The use of this method needs to be eliminated for pointers.
LLVMTypeRef llvm_get_element_type(LLVMTypeRef type) {
return LLVMGetElementType(type);
}
LLVMTypeRef lb_get_procedure_raw_type(lbModule *m, Type *type) {
return lb_type_internal_for_procedures_raw(m, type);
}
lbValue lb_type_info_member_types_offset(lbProcedure *p, isize count) {
GB_ASSERT(p->module == &p->module->gen->default_module);
lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_types.addr, lb_global_type_info_member_types_index);

View File

@@ -96,9 +96,7 @@ LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValu
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
// We always get the function pointer type rather than the function and there is apparently no way around that?
LLVMTypeRef type = lb_type(p->module, pr.type);
type = lb_llvm_get_pointer_type(type);
LLVMTypeRef type = lb_type_internal_for_procedures_raw(p->module, pr.type);
return LLVMBuildCall2(p->builder, type, pr.value, args, gb_count_of(args), "");
}