From 9e698b720f4f26341db81b70ea5f70f5bdfd9e3a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 12 Apr 2020 10:41:44 +0100 Subject: Change behaviour for zero-sized value types of array-related types; Fix make behaviour to always zero memory --- src/ir.cpp | 61 +++++++---------------------------------- src/llvm_backend.cpp | 76 ++++++++++++++++++---------------------------------- 2 files changed, 35 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/ir.cpp b/src/ir.cpp index 9b8eac02f..c01876b5d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4414,6 +4414,7 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue irValue *ptr = ir_emit_conv(proc, x, t_u8_ptr); return ir_emit_comp(proc, op_kind, ptr, v_raw_nil); } else if (is_type_any(t)) { + // TODO(bill): is this correct behaviour for nil comparison for any? irValue *data = ir_emit_struct_ev(proc, x, 0); irValue *ti = ir_emit_struct_ev(proc, x, 1); if (op_kind == Token_CmpEq) { @@ -4426,32 +4427,14 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue return ir_emit_arith(proc, Token_And, a, b, t_bool); } } else if (is_type_slice(t)) { - irValue *data = ir_emit_struct_ev(proc, x, 0); - irValue *cap = ir_emit_struct_ev(proc, x, 1); - if (op_kind == Token_CmpEq) { - irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_CmpEq, cap, v_zero); - return ir_emit_arith(proc, Token_Or, a, b, t_bool); - } else if (op_kind == Token_NotEq) { - irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_NotEq, cap, v_zero); - return ir_emit_arith(proc, Token_And, a, b, t_bool); - } + irValue *len = ir_emit_struct_ev(proc, x, 1); + return ir_emit_comp(proc, op_kind, len, v_zero); } else if (is_type_dynamic_array(t)) { - irValue *data = ir_emit_struct_ev(proc, x, 0); irValue *cap = ir_emit_struct_ev(proc, x, 2); - if (op_kind == Token_CmpEq) { - irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_CmpEq, cap, v_zero); - return ir_emit_arith(proc, Token_Or, a, b, t_bool); - } else if (op_kind == Token_NotEq) { - irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_NotEq, cap, v_zero); - return ir_emit_arith(proc, Token_And, a, b, t_bool); - } + return ir_emit_comp(proc, op_kind, cap, v_zero); } else if (is_type_map(t)) { - irValue *len = ir_map_len(proc, x); - return ir_emit_comp(proc, op_kind, len, v_zero); + irValue *cap = ir_map_cap(proc, x); + return ir_emit_comp(proc, op_kind, cap, v_zero); } else if (is_type_union(t)) { if (type_size_of(t) == 0) { return ir_emit_comp(proc, op_kind, v_zero, v_zero); @@ -4481,38 +4464,12 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue if (bt->Struct.soa_kind == StructSoa_Slice) { ir_emit_comment(proc, str_lit("soa-slice-nil-comp")); irValue *len = ir_soa_struct_len(proc, x); - if (bt->Struct.fields.count > 1) { - irValue *data = ir_emit_struct_ev(proc, x, 0); - if (op_kind == Token_CmpEq) { - irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_CmpEq, len, v_zero); - return ir_emit_arith(proc, Token_Or, a, b, t_bool); - } else if (op_kind == Token_NotEq) { - irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_NotEq, len, v_zero); - return ir_emit_arith(proc, Token_And, a, b, t_bool); - } - } else { - return ir_emit_comp(proc, op_kind, len, v_zero); - } + return ir_emit_comp(proc, op_kind, len, v_zero); } else if (bt->Struct.soa_kind == StructSoa_Dynamic) { ir_emit_comment(proc, str_lit("soa-dynamic-array-nil-comp")); - irValue *cap = ir_soa_struct_len(proc, x); - if (bt->Struct.fields.count > 1) { - irValue *data = ir_emit_struct_ev(proc, x, 0); - if (op_kind == Token_CmpEq) { - irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_CmpEq, cap, v_zero); - return ir_emit_arith(proc, Token_Or, a, b, t_bool); - } else if (op_kind == Token_NotEq) { - irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil); - irValue *b = ir_emit_comp(proc, Token_NotEq, cap, v_zero); - return ir_emit_arith(proc, Token_And, a, b, t_bool); - } - } else { - return ir_emit_comp(proc, op_kind, cap, v_zero); - } + irValue *cap = ir_soa_struct_cap(proc, x); + return ir_emit_comp(proc, op_kind, cap, v_zero); } } return nullptr; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 68d288799..c308f5746 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -7952,6 +7952,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { } return res; } else if (is_type_any(t)) { + // TODO(bill): is this correct behaviour for nil comparison for any? lbValue data = lb_emit_struct_ev(p, x, 0); lbValue ti = lb_emit_struct_ev(p, x, 1); if (op_kind == Token_CmpEq) { @@ -7966,31 +7967,21 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { return res; } } else if (is_type_slice(t)) { - lbValue data = lb_emit_struct_ev(p, x, 0); - lbValue cap = lb_emit_struct_ev(p, x, 1); + lbValue len = lb_emit_struct_ev(p, x, 1); if (op_kind == Token_CmpEq) { - LLVMValueRef a = LLVMBuildIsNull(p->builder, data.value, ""); - LLVMValueRef b = LLVMBuildIsNull(p->builder, cap.value, ""); - res.value = LLVMBuildOr(p->builder, a, b, ""); + res.value = LLVMBuildIsNull(p->builder, len.value, ""); return res; } else if (op_kind == Token_NotEq) { - LLVMValueRef a = LLVMBuildIsNotNull(p->builder, data.value, ""); - LLVMValueRef b = LLVMBuildIsNotNull(p->builder, cap.value, ""); - res.value = LLVMBuildAnd(p->builder, a, b, ""); + res.value = LLVMBuildIsNotNull(p->builder, len.value, ""); return res; } } else if (is_type_dynamic_array(t)) { - lbValue data = lb_emit_struct_ev(p, x, 0); lbValue cap = lb_emit_struct_ev(p, x, 2); if (op_kind == Token_CmpEq) { - LLVMValueRef a = LLVMBuildIsNull(p->builder, data.value, ""); - LLVMValueRef b = LLVMBuildIsNull(p->builder, cap.value, ""); - res.value = LLVMBuildOr(p->builder, a, b, ""); + res.value = LLVMBuildIsNull(p->builder, cap.value, ""); return res; } else if (op_kind == Token_NotEq) { - LLVMValueRef a = LLVMBuildIsNotNull(p->builder, data.value, ""); - LLVMValueRef b = LLVMBuildIsNotNull(p->builder, cap.value, ""); - res.value = LLVMBuildAnd(p->builder, a, b, ""); + res.value = LLVMBuildIsNotNull(p->builder, cap.value, ""); return res; } } else if (is_type_map(t)) { @@ -8019,41 +8010,26 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { lbValue res = lb_emit_comp(p, op_kind, val, lb_const_int(p->module, t_int, 0)); return res; } else if (is_type_soa_struct(t)) { - GB_PANIC("#soa struct nil comparison"); - // Type *bt = base_type(t); - // if (bt->Struct.soa_kind == StructSoa_Slice) { - // lbValue len = lb_soa_struct_len(p, x); - // if (bt->Struct.fields.count > 1) { - // lbValue data = lb_emit_struct_ev(p, x, 0); - // if (op_kind == Token_CmpEq) { - // lbValue a = lb_emit_comp(p, Token_CmpEq, data, v_raw_nil); - // lbValue b = lb_emit_comp(p, Token_CmpEq, len, v_zero); - // return lb_emit_arith(p, Token_Or, a, b, t_bool); - // } else if (op_kind == Token_NotEq) { - // lbValue a = lb_emit_comp(p, Token_NotEq, data, v_raw_nil); - // lbValue b = lb_emit_comp(p, Token_NotEq, len, v_zero); - // return lb_emit_arith(p, Token_And, a, b, t_bool); - // } - // } else { - // return lb_emit_comp(p, op_kind, len, v_zero); - // } - // } else if (bt->Struct.soa_kind == StructSoa_Dynamic) { - // lbValue cap = lb_soa_struct_len(p, x); - // if (bt->Struct.fields.count > 1) { - // lbValue data = lb_emit_struct_ev(p, x, 0); - // if (op_kind == Token_CmpEq) { - // lbValue a = lb_emit_comp(p, Token_CmpEq, data, v_raw_nil); - // lbValue b = lb_emit_comp(p, Token_CmpEq, cap, v_zero); - // return lb_emit_arith(p, Token_Or, a, b, t_bool); - // } else if (op_kind == Token_NotEq) { - // lbValue a = lb_emit_comp(p, Token_NotEq, data, v_raw_nil); - // lbValue b = lb_emit_comp(p, Token_NotEq, cap, v_zero); - // return lb_emit_arith(p, Token_And, a, b, t_bool); - // } - // } else { - // return lb_emit_comp(p, op_kind, cap, v_zero); - // } - // } + Type *bt = base_type(t); + if (bt->Struct.soa_kind == StructSoa_Slice) { + lbValue len = lb_soa_struct_len(p, x); + if (op_kind == Token_CmpEq) { + res.value = LLVMBuildIsNull(p->builder, len.value, ""); + return res; + } else if (op_kind == Token_NotEq) { + res.value = LLVMBuildIsNotNull(p->builder, len.value, ""); + return res; + } + } else if (bt->Struct.soa_kind == StructSoa_Dynamic) { + lbValue cap = lb_soa_struct_cap(p, x); + if (op_kind == Token_CmpEq) { + res.value = LLVMBuildIsNull(p->builder, cap.value, ""); + return res; + } else if (op_kind == Token_NotEq) { + res.value = LLVMBuildIsNotNull(p->builder, cap.value, ""); + return res; + } + } } return {}; } -- cgit v1.2.3