Quellcode durchsuchen

Merge branch 'master' into windows-llvm-13.0.0

gingerBill vor 3 Jahren
Ursprung
Commit
3fb84a16e1
4 geänderte Dateien mit 59 neuen und 30 gelöschten Zeilen
  1. 2 10
      src/llvm_backend.cpp
  2. 48 6
      src/llvm_backend_general.cpp
  3. 8 14
      src/llvm_backend_proc.cpp
  4. 1 0
      src/llvm_backend_type.cpp

+ 2 - 10
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) {
-		OdinLLVMBuildCall(p, {startup_type_info->value, startup_type_info->type}, 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) {
-		OdinLLVMBuildCall(p, {objc_names->value, objc_names->type}, 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) {
@@ -780,10 +780,6 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
 				var->init = init;
 			} else if (lb_is_const_or_global(init)) {
 				if (!var->is_initialized) {
-					if (is_type_proc(init.type)) {
-						LLVMTypeRef global_type = llvm_addr_type(p->module, var->var);
-						init.value = LLVMConstPointerCast(init.value, global_type);
-					}
 					LLVMSetInitializer(var->var.value, init.value);
 					var->is_initialized = true;
 					continue;
@@ -1653,10 +1649,6 @@ void lb_generate_code(lbGenerator *gen) {
 					if (tav.value.kind != ExactValue_Invalid) {
 						ExactValue v = tav.value;
 						lbValue init = lb_const_value(m, tav.type, v);
-						if (is_type_proc(init.type)) {
-							LLVMTypeRef global_type = llvm_addr_type(m, var.var);
-							init.value = LLVMConstPointerCast(init.value, global_type);
-						}
 						LLVMSetInitializer(g.value, init.value);
 						var.is_initialized = true;
 					}

+ 48 - 6
src/llvm_backend_general.cpp

@@ -854,6 +854,46 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
 	lb_emit_store(p, addr.addr, value);
 }
 
+void lb_const_store(lbValue ptr, lbValue value) {
+	GB_ASSERT(lb_is_const(ptr));
+	GB_ASSERT(lb_is_const(value));
+	GB_ASSERT(is_type_pointer(ptr.type));
+	LLVMSetInitializer(ptr.value, value.value);
+}
+
+
+bool lb_is_type_proc_recursive(Type *t) {
+	for (;;) {
+		if (t == nullptr) {
+			return false;
+		}
+		switch (t->kind) {
+		case Type_Named:
+			t = t->Named.base;
+			break;
+		case Type_Pointer:
+			t = t->Pointer.elem;
+			break;
+		case Type_Array:
+			t = t->Array.elem;
+			break;
+		case Type_EnumeratedArray:
+			t = t->EnumeratedArray.elem;
+			break;
+		case Type_Slice:
+			t = t->Slice.elem;
+			break;
+		case Type_DynamicArray:
+			t = t->DynamicArray.elem;
+			break;
+		case Type_Proc:
+			return true;
+		default:
+			return false;
+		}
+	}
+}
+
 void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
 	GB_ASSERT(value.value != nullptr);
 	Type *a = type_deref(ptr.type);
@@ -913,7 +953,7 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
 		}
 	}
 
-	if (is_type_proc(a)) {
+	if (lb_is_type_proc_recursive(a)) {
 		// NOTE(bill, 2020-11-11): Because of certain LLVM rules, a procedure value may be
 		// stored as regular pointer with no procedure information
 
@@ -1511,7 +1551,7 @@ LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
 			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) {
+			    type_size_of(e_type) <= 1) {
 				param_type = LLVMInt1TypeInContext(m->ctx);
 			} else {
 				if (is_type_proc(e_type)) {
@@ -2058,13 +2098,15 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
 		}
 
 	case Type_Proc:
-		{
-			// NOTE(bill): we do an explicit cast to the correct procedure type when calling the procedure
+		// if (m->internal_type_level > 256) { // TODO HACK(bill): is this really enough?
+		if (m->internal_type_level > 1) { // TODO HACK(bill): is this really enough?
+			return LLVMPointerType(LLVMIntTypeInContext(m->ctx, 8), 0);
+		} else {
 			LLVMTypeRef proc_raw_type = lb_type_internal_for_procedures_raw(m, type);
-			gb_unused(proc_raw_type);
-			return lb_type(m, t_rawptr);
+			return LLVMPointerType(proc_raw_type, 0);
 		}
 
+		break;
 	case Type_BitSet:
 		{
 			Type *ut = bit_set_to_int(type);

+ 8 - 14
src/llvm_backend_proc.cpp

@@ -1,11 +1,6 @@
-LLVMValueRef OdinLLVMBuildCall(lbProcedure *p, lbValue const &value, LLVMValueRef *args, unsigned arg_count) {
-	GB_ASSERT(is_type_proc(value.type));
-	LLVMTypeRef type = lb_type_internal_for_procedures_raw(p->module, value.type);
-	LLVMValueRef func = LLVMBuildPointerCast(p->builder, value.value, LLVMPointerType(type, 0), "");
-	return LLVMBuildCall2(p->builder, type, func, args, arg_count, "");
-}
 
-LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count) {
+LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count)
+{
 	unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
 	GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
 	LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, type_count);
@@ -745,11 +740,6 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
 	}
 	for_array(i, processed_args) {
 		lbValue arg = processed_args[i];
-		if (is_type_proc(arg.type)) {
-			// NOTE(bill): all procedure types (function pointers) are typed as if they are `rawptr`
-			// and then the correct type is set at the call site
-			arg.value = LLVMBuildPointerCast(p->builder, arg.value, lb_type(p->module, arg.type), "");
-		}
 		args[arg_index++] = arg.value;
 	}
 	if (context_ptr.addr.value != nullptr) {
@@ -762,7 +752,11 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
 
 	{
 		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, "");
+		}
 		GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
 
 		{
@@ -786,7 +780,7 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
 			}
 		}
 
-		LLVMValueRef ret = OdinLLVMBuildCall(p, value, args, arg_count);
+		LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
 
 		if (return_ptr.value != nullptr) {
 			LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0])));

+ 1 - 0
src/llvm_backend_type.cpp

@@ -554,6 +554,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
 				lbValue index     = lb_const_int(m, t_int, i);
 				lbValue type_info = lb_emit_ptr_offset(p, memory_types, index);
 
+				// TODO(bill): Make this constant if possible, 'lb_const_store' does not work
 				lb_emit_store(p, type_info, lb_type_info(m, f->type));
 				if (f->token.string.len > 0) {
 					lbValue name = lb_emit_ptr_offset(p, memory_names, index);