Browse Source

Fixes for constants and `nil` parameters

gingerBill 5 years ago
parent
commit
bf0c6f5a30
2 changed files with 83 additions and 14 deletions
  1. 81 13
      src/llvm_backend.cpp
  2. 2 1
      src/llvm_backend.hpp

+ 81 - 13
src/llvm_backend.cpp

@@ -40,6 +40,12 @@ LLVMValueRef llvm_one32(lbModule *m) {
 	return LLVMConstInt(lb_type(m, t_i32), 1, false);
 }
 
+LLVMValueRef llvm_cstring(lbModule *m, String const &str) {
+	lbValue v = lb_find_or_add_entity_string(m, str);
+	unsigned indices[1] = {0};
+	return LLVMConstExtractValue(v.value, indices, gb_count_of(indices));
+}
+
 
 lbAddr lb_addr(lbValue addr) {
 	lbAddr v = {lbAddr_Default, addr};
@@ -2135,7 +2141,7 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
 			lb_addr_store(p, key, lb_emit_load(p, str));
 		} else {
 			lbValue hash_ptr = lb_emit_struct_ep(p, hash, 0);
-			hash_ptr = lb_emit_conv(p, hash_ptr, lb_addr_type(key));
+			hash_ptr = lb_emit_conv(p, hash_ptr, key.addr.type);
 			lb_addr_store(p, key, lb_emit_load(p, hash_ptr));
 		}
 
@@ -3544,7 +3550,34 @@ lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) {
 		res.type = t_string;
 		return res;
 	} else {
-		return lb_const_value(m, t_string, exact_value_string(str));
+		LLVMValueRef indices[2] = {llvm_zero32(m), llvm_zero32(m)};
+		LLVMValueRef data = LLVMConstStringInContext(m->ctx,
+			cast(char const *)str.text,
+			cast(unsigned)str.len,
+			false);
+
+
+		isize max_len = 7+8+1;
+		char *name = gb_alloc_array(heap_allocator(), char, max_len);
+		isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index);
+		len -= 1;
+		m->global_array_index++;
+
+		LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
+		LLVMSetInitializer(global_data, data);
+
+		LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
+
+		LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true);
+		LLVMValueRef values[2] = {ptr, str_len};
+
+		lbValue res = {};
+		res.value = LLVMConstNamedStruct(lb_type(m, t_string), values, 2);
+		res.type = t_string;
+
+		map_set(&m->const_strings, key, ptr);
+
+		return res;
 	}
 }
 
@@ -3582,10 +3615,9 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
 		LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true);
 		LLVMValueRef values[2] = {ptr, str_len};
 
-		Type *original_type = t_u8_slice;
 		lbValue res = {};
-		res.value = LLVMConstNamedStruct(lb_type(m, original_type), values, 2);
-		res.type = default_type(original_type);
+		res.value = LLVMConstNamedStruct(lb_type(m, t_u8_slice), values, 2);
+		res.type = t_u8_slice;
 
 		map_set(&m->const_strings, key, ptr);
 
@@ -4132,7 +4164,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value) {
 			ast_node(cl, CompoundLit, value.value_compound);
 
 			if (cl->elems.count == 0) {
-				return lb_const_nil(m, type);
+				return lb_const_nil(m, original_type);
 			}
 
 			isize offset = 0;
@@ -4232,7 +4264,13 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value) {
 		}
 		break;
 	case ExactValue_Procedure:
-		GB_PANIC("TODO(bill): ExactValue_Procedure");
+		{
+			Ast *expr = value.value_procedure;
+			GB_ASSERT(expr != nullptr);
+			if (expr->kind == Ast_ProcLit) {
+				return lb_generate_anonymous_proc_lit(m, str_lit("_proclit"), expr);
+			}
+		}
 		break;
 	case ExactValue_Typeid:
 		return lb_typeid(m, value.value_typeid, original_type);
@@ -4805,7 +4843,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 				String str = lb_get_const_string(m, value);
 				lbValue res = {};
 				res.type = t;
-				res.value = LLVMConstString(cast(char const *)str.text, cast(unsigned)str.len, false);
+				res.value = llvm_cstring(m, str);
 				return res;
 			}
 			// if (is_type_float(dst)) {
@@ -5354,6 +5392,8 @@ lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value) {
 		return res;
 	}
 
+	GB_ASSERT(is_type_typed(value.type));
+
 	lbAddr res = lb_add_local_generated(p, value.type, false);
 	lb_addr_store(p, res, value);
 	return res.addr;
@@ -5833,6 +5873,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
 		Type *original_type = e->type;
 		Type *new_type = pt->Proc.abi_compat_params[i];
 		Type *arg_type = args[i].type;
+
 		if (are_types_identical(arg_type, new_type)) {
 			// NOTE(bill): Done
 			array_add(&processed_args, args[i]);
@@ -6507,6 +6548,11 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 
 
 	// "Intrinsics"
+	case BuiltinProc_cpu_relax:
+		// TODO(bill): BuiltinProc_cpu_relax
+		// ir_write_str_lit(f, "call void asm sideeffect \"pause\", \"\"()");
+		return {};
+
 	case BuiltinProc_atomic_fence:
 		LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, "");
 		return {};
@@ -6709,8 +6755,6 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 
 		return {};
 	}
-
-
 	}
 
 	GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name));
@@ -6832,6 +6876,17 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 			}
 		}
 
+		for (isize i = 0; i < args.count; i++) {
+			Entity *e = params->variables[i];
+			if (args[i].type == nullptr) {
+				continue;
+			} else if (is_type_untyped_nil(args[i].type)) {
+				args[i] = lb_const_nil(m, e->type);
+			} else if (is_type_untyped_undef(args[i].type)) {
+				args[i] = lb_const_undef(m, e->type);
+			}
+		}
+
 		return lb_emit_call(p, value, args, ce->inlining, p->return_ptr_hint_ast == expr);
 	}
 
@@ -7028,6 +7083,19 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 		final_count = arg_count;
 	}
 
+	if (param_tuple != nullptr) {
+		for (isize i = 0; i < gb_min(args.count, param_tuple->variables.count); i++) {
+			Entity *e = param_tuple->variables[i];
+			if (args[i].type == nullptr) {
+				continue;
+			} else if (is_type_untyped_nil(args[i].type)) {
+				args[i] = lb_const_nil(m, e->type);
+			} else if (is_type_untyped_undef(args[i].type)) {
+				args[i] = lb_const_undef(m, e->type);
+			}
+		}
+	}
+
 	auto call_args = array_slice(args, 0, final_count);
 	return lb_emit_call(p, value, call_args, ce->inlining, p->return_ptr_hint_ast == expr);
 }
@@ -7577,7 +7645,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri
 }
 
 
-lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent = nullptr) {
+lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
 	ast_node(pl, ProcLit, expr);
 
 	// NOTE(bill): Generate a new name
@@ -7872,7 +7940,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
 		lbValue cond = lb_build_cond(p, te->cond, then, else_);
 		lb_start_block(p, then);
 
-		Type *type = type_of_expr(expr);
+		Type *type = default_type(type_of_expr(expr));
 
 		lb_open_scope(p);
 		incoming_values[0] = lb_emit_conv(p, lb_build_expr(p, te->x), type).value;
@@ -7913,7 +7981,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
 		lbValue cond = lb_build_cond(p, te->cond, then, else_);
 		lb_start_block(p, then);
 
-		Type *type = type_of_expr(expr);
+		Type *type = default_type(type_of_expr(expr));
 
 		lb_open_scope(p);
 		incoming_values[0] = lb_emit_conv(p, lb_build_expr(p, te->x), type).value;

+ 2 - 1
src/llvm_backend.hpp

@@ -312,7 +312,8 @@ void lb_emit_increment(lbProcedure *p, lbValue addr);
 
 lbValue lb_type_info(lbModule *m, Type *type);
 
-
+lbValue lb_find_or_add_entity_string(lbModule *m, String const &str);
+lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent = nullptr);
 
 bool lb_is_const(lbValue value);
 bool lb_is_const_nil(lbValue value);