Browse Source

Eliminate use of LLVMGetElementType for pointers

gingerBill 3 years ago
parent
commit
cb0a59bb2c

+ 23 - 8
core/log/log_allocator.odin

@@ -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
 }

+ 8 - 2
src/llvm_abi.cpp

@@ -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;

+ 2 - 2
src/llvm_backend.cpp

@@ -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) {

+ 3 - 2
src/llvm_backend.hpp

@@ -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);

+ 1 - 1
src/llvm_backend_expr.cpp

@@ -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};

+ 113 - 97
src/llvm_backend_general.cpp

@@ -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;

+ 6 - 8
src/llvm_backend_proc.cpp

@@ -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"),

+ 7 - 3
src/llvm_backend_type.cpp

@@ -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);

+ 1 - 3
src/llvm_backend_utility.cpp

@@ -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), "");
 	}