Browse Source

Change runtime.Type_Info_Enum_Value to be `i64` internally rather than a `union`

gingerBill 5 years ago
parent
commit
d80049bfd2
4 changed files with 93 additions and 106 deletions
  1. 68 76
      core/fmt/fmt.odin
  2. 1 5
      core/runtime/core.odin
  3. 5 5
      src/ir.cpp
  4. 19 20
      src/llvm_backend.cpp

+ 68 - 76
core/fmt/fmt.odin

@@ -158,10 +158,10 @@ fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) {
 
 sbprint :: proc(buf: ^strings.Builder, args: ..any) -> string {
 	fi: Info;
-	prev_string := false;
 
 	fi.buf = buf;
 
+	prev_string := false;
 	for arg, i in args {
 		is_string := arg != nil && reflect.is_string(type_info_of(arg.id));
 		if i > 0 && !is_string && !prev_string {
@@ -937,23 +937,68 @@ enum_value_to_string :: proc(val: any) -> (string, bool) {
 	#partial switch e in type_info.variant {
 	case: return "", false;
 	case runtime.Type_Info_Enum:
-		get_str :: proc(data: rawptr, e: runtime.Type_Info_Enum) -> (string, bool) {
+		Enum_Value :: runtime.Type_Info_Enum_Value;
+
+		ev: Enum_Value;
+		ok := true;
+
+		bv := v;
+		bv.id = runtime.typeid_core(e.base.id);
+
+		switch i in bv {
+		case i8:   ev = Enum_Value(i);
+		case i16:  ev = Enum_Value(i);
+		case i32:  ev = Enum_Value(i);
+		case i64:  ev = Enum_Value(i);
+		case i128: ev = Enum_Value(i);
+
+		case int:  ev = Enum_Value(i);
+
+		case u8:   ev = Enum_Value(i);
+		case u16:  ev = Enum_Value(i);
+		case u32:  ev = Enum_Value(i);
+		case u64:  ev = Enum_Value(i);
+		case u128: ev = Enum_Value(i);
+		case uint: ev = Enum_Value(i);
+
+		case uintptr: ev = Enum_Value(i);
+
+		case i16le:  ev = Enum_Value(i);
+		case i32le:  ev = Enum_Value(i);
+		case i64le:  ev = Enum_Value(i);
+		case i128le: ev = Enum_Value(i);
+
+		case u16le:  ev = Enum_Value(i);
+		case u32le:  ev = Enum_Value(i);
+		case u64le:  ev = Enum_Value(i);
+		case u128le: ev = Enum_Value(i);
+
+		case i16be:  ev = Enum_Value(i);
+		case i32be:  ev = Enum_Value(i);
+		case i64be:  ev = Enum_Value(i);
+		case i128be: ev = Enum_Value(i);
+
+		case u16be:  ev = Enum_Value(i);
+		case u32be:  ev = Enum_Value(i);
+		case u64be:  ev = Enum_Value(i);
+		case u128be: ev = Enum_Value(i);
+
+		case:
+			ok = false;
+		}
+
+		if ok {
 			if len(e.values) == 0 {
 				return "", true;
 			} else {
-				for _, idx in e.values {
-					val := &e.values[idx];
-					// NOTE(bill): Removes need for parametric polymorphic check
-					res := mem.compare_ptrs(val, data, e.base.size);
-					if res == 0 {
+				for val, idx in e.values {
+					if val == ev {
 						return e.names[idx], true;
 					}
 				}
 			}
 			return "", false;
 		}
-
-		return get_str(v.data, e);
 	}
 
 	return "", false;
@@ -1001,81 +1046,28 @@ stored_enum_value_to_string :: proc(enum_type: ^runtime.Type_Info, ev: runtime.T
 	#partial switch e in et.variant {
 	case: return "", false;
 	case runtime.Type_Info_Enum:
-		get_str :: proc(i: $T, e: runtime.Type_Info_Enum) -> (string, bool) {
-			if reflect.is_string(e.base) {
-				for val, idx in e.values {
-					if v, ok := val.(T); ok && v == i {
-						return e.names[idx], true;
-					}
+		if reflect.is_string(e.base) {
+			for val, idx in e.values {
+				if val == ev {
+					return e.names[idx], true;
 				}
-			} else if len(e.values) == 0 {
-				return "", true;
-			} else {
-				for val, idx in e.values {
-					if v, ok := val.(T); ok && v == i {
-						return e.names[idx], true;
-					}
+			}
+		} else if len(e.values) == 0 {
+			return "", true;
+		} else {
+			for val, idx in e.values {
+				if val == ev {
+					return e.names[idx], true;
 				}
 			}
-			return "", false;
-		}
-
-		switch v in ev {
-		case rune:    return get_str(v + auto_cast offset, e);
-		case i8:      return get_str(v + auto_cast offset, e);
-		case i16:     return get_str(v + auto_cast offset, e);
-		case i32:     return get_str(v + auto_cast offset, e);
-		case i64:     return get_str(v + auto_cast offset, e);
-		case int:     return get_str(v + auto_cast offset, e);
-		case u8:      return get_str(v + auto_cast offset, e);
-		case u16:     return get_str(v + auto_cast offset, e);
-		case u32:     return get_str(v + auto_cast offset, e);
-		case u64:     return get_str(v + auto_cast offset, e);
-		case uint:    return get_str(v + auto_cast offset, e);
-		case uintptr: return get_str(v + auto_cast offset, e);
 		}
+		return "", false;
 	}
 
 	return "", false;
 }
 
 
-enum_value_to_u64 :: proc(ev: runtime.Type_Info_Enum_Value) -> u64 {
-	switch i in ev {
-	case rune:    return u64(i);
-	case i8:      return u64(i);
-	case i16:     return u64(i);
-	case i32:     return u64(i);
-	case i64:     return u64(i);
-	case int:     return u64(i);
-	case u8:      return u64(i);
-	case u16:     return u64(i);
-	case u32:     return u64(i);
-	case u64:     return u64(i);
-	case uint:    return u64(i);
-	case uintptr: return u64(i);
-	}
-	return 0;
-}
-
-enum_value_to_i64 :: proc(ev: runtime.Type_Info_Enum_Value) -> i64 {
-	switch i in ev {
-	case rune:    return i64(i);
-	case i8:      return i64(i);
-	case i16:     return i64(i);
-	case i32:     return i64(i);
-	case i64:     return i64(i);
-	case int:     return i64(i);
-	case u8:      return i64(i);
-	case u16:     return i64(i);
-	case u32:     return i64(i);
-	case u64:     return i64(i);
-	case uint:    return i64(i);
-	case uintptr: return i64(i);
-	}
-	return 0;
-}
-
 fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") {
 	is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool {
 		if ti == nil {
@@ -1152,7 +1144,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") {
 			if commas > 0 do strings.write_string(fi.buf, ", ");
 
 			if is_enum do for ev, evi in e.values {
-				v := enum_value_to_u64(ev);
+				v := u64(ev);
 				if v == u64(i) {
 					strings.write_string(fi.buf, e.names[evi]);
 					commas += 1;
@@ -1437,7 +1429,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
 				strings.write_byte(fi.buf, '.');
 				strings.write_string(fi.buf, idx);
 			} else {
-				strings.write_i64(fi.buf, enum_value_to_i64(info.min_value)+i64(i));
+				strings.write_i64(fi.buf, i64(info.min_value)+i64(i));
 			}
 			strings.write_string(fi.buf, " = ");
 

+ 1 - 5
core/runtime/core.odin

@@ -34,11 +34,7 @@ Calling_Convention :: enum u8 {
 	Fast        = 5,
 }
 
-Type_Info_Enum_Value :: union {
-	rune,
-	i8, i16, i32, i64, int,
-	u8, u16, u32, u64, uint, uintptr,
-};
+Type_Info_Enum_Value :: distinct i64;
 
 Platform_Endianness :: enum u8 {
 	Platform = 0,

+ 5 - 5
src/ir.cpp

@@ -9799,7 +9799,7 @@ void ir_build_range_enum(irProcedure *proc, Type *enum_type, Type *val_type, irV
 		GB_ASSERT(are_types_identical(enum_type, val_type));
 
 		if (is_type_integer(core_elem)) {
-			irValue *i = ir_emit_load(proc, ir_emit_conv(proc, val_ptr, t_i64_ptr));
+			irValue *i = ir_emit_load(proc, val_ptr);
 			val = ir_emit_conv(proc, i, t);
 		} else {
 			GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem));
@@ -11812,8 +11812,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
 			irValue *min_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.min_value);
 			irValue *max_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.max_value);
 
-			ir_emit_store_union_variant(proc, min_value, min_v, ir_type(min_v));
-			ir_emit_store_union_variant(proc, max_value, max_v, ir_type(max_v));
+			ir_emit_store(proc, min_value, min_v);
+			ir_emit_store(proc, max_value, max_v);
 			break;
 		}
 		case Type_DynamicArray: {
@@ -11907,9 +11907,9 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
 						irValue *value_ep = ir_emit_array_epi(proc, value_array, cast(i32)i);
 
 						ExactValue value = fields[i]->Constant.value;
-						irValue *v = ir_value_constant(t->Enum.base_type, value);
+						irValue *v = ir_value_constant(t_i64, value);
 
-						ir_emit_store_union_variant(proc, value_ep, v, ir_type(v));
+						ir_emit_store(proc, value_ep, v);
 						ir_emit_store(proc, name_ep, ir_const_string(proc->module, fields[i]->token.string));
 					}
 

+ 19 - 20
src/llvm_backend.cpp

@@ -2027,6 +2027,11 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
 
 	p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
 
+	lbCallingConventionKind cc_kind = lbCallingConvention_C;
+	// TODO(bill): Clean up this logic
+	if (build_context.metrics.os != TargetOs_js)  {
+		cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
+	}
 	LLVMSetFunctionCallConv(p->value, lb_calling_convention_map[pt->Proc.calling_convention]);
 	lbValue proc_value = {p->value, p->type};
 	lb_add_entity(m, entity,  proc_value);
@@ -4464,6 +4469,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
 
 		LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
 		LLVMSetInitializer(global_data, data);
+		LLVMSetLinkage(global_data, LLVMInternalLinkage);
 
 		LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
 		string_map_set(&m->const_strings, key, ptr);
@@ -4500,6 +4506,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
 	}
 	LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
 	LLVMSetInitializer(global_data, data);
+	LLVMSetLinkage(global_data, LLVMInternalLinkage);
 
 	LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
 	LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true);
@@ -11211,22 +11218,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
 
 					LLVMTypeRef align_type = lb_alignment_prefix_type_hack(m, type_align_of(t));
 					LLVMTypeRef array_type = LLVMArrayType(lb_type(m, t_u8), 8);
-					LLVMTypeRef u64_type = lb_type(m, t_u64);
 
 					for_array(i, fields) {
-						ExactValue value = fields[i]->Constant.value;
-						lbValue v = lb_const_value(m, t->Enum.base_type, value);
-						LLVMValueRef zv = LLVMConstZExt(v.value, u64_type);
-						lbValue tag = lb_const_union_tag(m, t_type_info_enum_value, v.type);
-
-						LLVMValueRef vals[3] = {
-							LLVMConstNull(align_type),
-							zv,
-							tag.value,
-						};
-
 						name_values[i] = lb_const_string(m, fields[i]->token.string).value;
-						value_values[i] = LLVMConstStruct(vals, gb_count_of(vals), false);
+						value_values[i] = lb_const_value(m, t_i64, fields[i]->Constant.value).value;
 					}
 
 					LLVMValueRef name_init  = LLVMConstArray(lb_type(m, t_string),               name_values,  cast(unsigned)fields.count);
@@ -12211,21 +12206,25 @@ void lb_generate_code(lbGenerator *gen) {
 	}
 
 
+	LLVMDIBuilderFinalize(m->debug_builder);
+	if (LLVMVerifyModule(mod, LLVMAbortProcessAction, &llvm_error)) {
+		gb_printf_err("LLVM Error: %s\n", llvm_error);
+		return;
+	}
+	llvm_error = nullptr;
 	if (build_context.keep_temp_files) {
 		TIME_SECTION("LLVM Print Module to File");
-		LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error);
-		// exit(1);
+		if (LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error)) {
+			gb_printf_err("LLVM Error: %s\n", llvm_error);
+			return;
+		}
 	}
-	LLVMDIBuilderFinalize(m->debug_builder);
-	LLVMVerifyModule(mod, LLVMAbortProcessAction, &llvm_error);
-	llvm_error = nullptr;
 
 	TIME_SECTION("LLVM Object Generation");
 
 	LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile;
 
-	LLVMBool was_an_error = LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error);
-	if (was_an_error) {
+	if (LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
 		gb_printf_err("LLVM Error: %s\n", llvm_error);
 		gb_exit(1);
 		return;