diff options
| author | gingerBill <bill@gingerbill.org> | 2017-12-21 20:59:23 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2017-12-21 20:59:23 +0000 |
| commit | ac277a1cce7b42e0e7d6ff9147a2ef4efc7ca541 (patch) | |
| tree | d2335f6188886d9b12360190d4f4154b4cad44c6 /src/ir.cpp | |
| parent | a17310a83c14d708a129559c90610a7a51a147a1 (diff) | |
Revert `map` to be a value type and not a reference type
(Implement code for "const ref" parameters)
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 139 |
1 files changed, 76 insertions, 63 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 230f8de6a..d30fb958b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -388,9 +388,10 @@ struct irValueGlobal { enum irParamPasskind { - irParamPass_Value, // Pass by value - irParamPass_Pointer, // Pass as a pointer rather than by value - irParamPass_Integer, // Pass as an integer of the same size + irParamPass_Value, // Pass by value + irParamPass_Pointer, // Pass as a pointer rather than by value + irParamPass_Integer, // Pass as an integer of the same size + irParamPass_ConstRef, // Pass as a pointer but the value is immutable }; struct irValueParam { @@ -846,7 +847,11 @@ irValue *ir_value_param(gbAllocator a, irProcedure *parent, Entity *e, Type *abi if (abi_type != e->type) { if (is_type_pointer(abi_type)) { + GB_ASSERT(e->kind == Entity_Variable); v->Param.kind = irParamPass_Pointer; + if (e->flags&EntityFlag_Value) { + v->Param.kind = irParamPass_ConstRef; + } } else if (is_type_integer(abi_type)) { v->Param.kind = irParamPass_Integer; } else { @@ -1445,16 +1450,20 @@ irValue *ir_add_param(irProcedure *proc, Entity *e, AstNode *expr, Type *abi_typ ir_emit_store(proc, l, v); return v; } - case irParamPass_Pointer: { + case irParamPass_Pointer: ir_module_add_value(proc->module, e, v); return ir_emit_load(proc, v); - } + case irParamPass_Integer: { irValue *l = ir_add_local(proc, e, expr, false); irValue *iptr = ir_emit_conv(proc, l, make_type_pointer(proc->module->allocator, p->type)); ir_emit_store(proc, iptr, v); return ir_emit_load(proc, l); } + + case irParamPass_ConstRef: + ir_module_add_value(proc->module, e, v); + return ir_emit_load(proc, v); } GB_PANIC("Unreachable"); @@ -1570,7 +1579,7 @@ irValue *ir_emit_bitcast(irProcedure *proc, irValue *data, Type *type) { } irValue *ir_emit_transmute(irProcedure *proc, irValue *value, Type *t); - +irValue *ir_address_from_load_or_generate_local(irProcedure *proc, irValue *val); irValue *ir_find_or_generate_context_ptr(irProcedure *proc) { if (proc->context_stack.count > 0) { @@ -1605,11 +1614,16 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_ continue; } GB_ASSERT(e->flags & EntityFlag_Param); + Type *original_type = e->type; Type *new_type = pt->Proc.abi_compat_params[i]; if (original_type != new_type) { if (is_type_pointer(new_type)) { - args[i] = ir_copy_value_to_ptr(p, args[i], original_type, 16); + if (e->flags&EntityFlag_Value) { + args[i] = ir_address_from_load_or_generate_local(p, args[i]); + } else { + args[i] = ir_copy_value_to_ptr(p, args[i], original_type, 16); + } } else if (is_type_integer(new_type)) { args[i] = ir_emit_transmute(p, args[i], new_type); } @@ -2073,19 +2087,41 @@ irValue *ir_build_addr_ptr(irProcedure *proc, AstNode *expr) { } +irValue *ir_dynamic_array_len(irProcedure *proc, irValue *da); +irValue *ir_dynamic_array_cap(irProcedure *proc, irValue *da); + + +irValue *ir_map_entries(irProcedure *proc, irValue *value) { + gbAllocator a = proc->module->allocator; + Type *t = base_type(ir_type(value)); + GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); + generate_map_internal_types(a, t); + Type *gst = t->Map.generated_struct_type; + isize index = 1; + irValue *entries = ir_emit(proc, ir_instr_struct_extract_value(proc, value, index, gst->Struct.fields[index]->type)); + return entries; +} + +irValue *ir_map_entries_ptr(irProcedure *proc, irValue *value) { + gbAllocator a = proc->module->allocator; + Type *t = base_type(type_deref(ir_type(value))); + GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); + generate_map_internal_types(a, t); + Type *gst = t->Map.generated_struct_type; + isize index = 1; + Type *ptr_t = make_type_pointer(a, gst->Struct.fields[index]->type); + irValue *entries = ir_emit(proc, ir_instr_struct_element_ptr(proc, value, index, ptr_t)); + return entries; +} -irValue *ir_map_count(irProcedure *proc, irValue *value) { - GB_ASSERT(is_type_map(ir_type(value))); - irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1); - args[0] = ir_emit_transmute(proc, value, t_rawptr); - return ir_emit_global_call(proc, "__dynamic_map_len", args, 1); +irValue *ir_map_len(irProcedure *proc, irValue *value) { + irValue *entries = ir_map_entries(proc, value); + return ir_dynamic_array_len(proc, entries); } -irValue *ir_map_capacity(irProcedure *proc, irValue *value) { - GB_ASSERT(is_type_map(ir_type(value))); - irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1); - args[0] = ir_emit_transmute(proc, value, t_rawptr); - return ir_emit_global_call(proc, "__dynamic_map_cap", args, 1); +irValue *ir_map_cap(irProcedure *proc, irValue *value) { + irValue *entries = ir_map_entries(proc, value); + return ir_dynamic_array_cap(proc, entries); } @@ -2366,7 +2402,7 @@ 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_map(t)) { - irValue *len = ir_map_count(proc, x); + irValue *len = ir_map_len(proc, x); return ir_emit_comp(proc, op_kind, len, v_zero); } else if (is_type_union(t)) { irValue *tag = ir_emit_union_tag_value(proc, x); @@ -2765,7 +2801,7 @@ irValue *ir_slice_elem(irProcedure *proc, irValue *slice) { GB_ASSERT(is_type_slice(ir_type(slice))); return ir_emit_struct_ev(proc, slice, 0); } -irValue *ir_slice_count(irProcedure *proc, irValue *slice) { +irValue *ir_slice_len(irProcedure *proc, irValue *slice) { GB_ASSERT(is_type_slice(ir_type(slice))); return ir_emit_struct_ev(proc, slice, 1); } @@ -2773,11 +2809,11 @@ irValue *ir_dynamic_array_elem(irProcedure *proc, irValue *da) { GB_ASSERT(is_type_dynamic_array(ir_type(da))); return ir_emit_struct_ev(proc, da, 0); } -irValue *ir_dynamic_array_count(irProcedure *proc, irValue *da) { +irValue *ir_dynamic_array_len(irProcedure *proc, irValue *da) { GB_ASSERT(is_type_dynamic_array(ir_type(da))); return ir_emit_struct_ev(proc, da, 1); } -irValue *ir_dynamic_array_capacity(irProcedure *proc, irValue *da) { +irValue *ir_dynamic_array_cap(irProcedure *proc, irValue *da) { GB_ASSERT(is_type_dynamic_array(ir_type(da))); return ir_emit_struct_ev(proc, da, 2); } @@ -2836,7 +2872,7 @@ irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base, if (high == nullptr) { switch (bt->kind) { case Type_Array: high = ir_array_len(proc, base); break; - case Type_Slice: high = ir_slice_count(proc, base); break; + case Type_Slice: high = ir_slice_len(proc, base); break; case Type_Pointer: high = v_one; break; } } @@ -3181,7 +3217,7 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { // []byte/[]u8 <-> string if (is_type_u8_slice(src) && is_type_string(dst)) { irValue *elem = ir_slice_elem(proc, value); - irValue *len = ir_slice_count(proc, value); + irValue *len = ir_slice_len(proc, value); return ir_emit_string(proc, elem, len); } if (is_type_string(src) && is_type_u8_slice(dst)) { @@ -4055,11 +4091,11 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); } else if (is_type_slice(t)) { - return ir_slice_count(proc, v); + return ir_slice_len(proc, v); } else if (is_type_dynamic_array(t)) { - return ir_dynamic_array_count(proc, v); + return ir_dynamic_array_len(proc, v); } else if (is_type_map(t)) { - return ir_map_count(proc, v); + return ir_map_len(proc, v); } GB_PANIC("Unreachable"); @@ -4079,11 +4115,11 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); } else if (is_type_slice(t)) { - return ir_slice_count(proc, v); + return ir_slice_len(proc, v); } else if (is_type_dynamic_array(t)) { - return ir_dynamic_array_capacity(proc, v); + return ir_dynamic_array_cap(proc, v); } else if (is_type_map(t)) { - return ir_map_capacity(proc, v); + return ir_map_cap(proc, v); } GB_PANIC("Unreachable"); @@ -4463,7 +4499,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue *item_slice = args[1]; irValue *items = ir_slice_elem(proc, item_slice); - irValue *item_count = ir_slice_count(proc, item_slice); + irValue *item_count = ir_slice_len(proc, item_slice); irValue **daa_args = gb_alloc_array(a, irValue *, 5); daa_args[0] = array_ptr; @@ -5515,7 +5551,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } irValue *elem = ir_slice_elem(proc, slice); irValue *index = ir_emit_conv(proc, ir_build_expr(proc, ie->index), t_int); - irValue *len = ir_slice_count(proc, slice); + irValue *len = ir_slice_len(proc, slice); ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len); irValue *v = ir_emit_ptr_offset(proc, elem, index); return ir_addr(v); @@ -5533,7 +5569,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } } irValue *elem = ir_dynamic_array_elem(proc, dynamic_array); - irValue *len = ir_dynamic_array_count(proc, dynamic_array); + irValue *len = ir_dynamic_array_len(proc, dynamic_array); irValue *index = ir_emit_conv(proc, ir_build_expr(proc, ie->index), t_int); ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len); irValue *v = ir_emit_ptr_offset(proc, elem, index); @@ -5596,7 +5632,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { case Type_Slice: { Type *slice_type = type; - if (high == nullptr) high = ir_slice_count(proc, base); + if (high == nullptr) high = ir_slice_len(proc, base); ir_emit_slice_bounds_check(proc, se->open, low, high, false); @@ -5612,8 +5648,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { Type *elem_type = type->DynamicArray.elem; Type *slice_type = make_type_slice(a, elem_type); - if (high == nullptr) high = ir_dynamic_array_count(proc, base); - irValue *cap = ir_dynamic_array_capacity(proc, base); + if (high == nullptr) high = ir_dynamic_array_len(proc, base); + irValue *cap = ir_dynamic_array_cap(proc, base); ir_emit_dynamic_array_bounds_check(proc, se->open, low, high, cap); @@ -6247,11 +6283,7 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir case Type_Map: { irValue *key = ir_add_local_generated(proc, expr_type->Map.key); - Type *itp = make_type_pointer(proc->module->allocator, expr_type->Map.internal_type); - irValue *data_ptr = ir_emit_transmute(proc, expr, itp); - irValue *internal_ptr = ir_emit_load(proc, data_ptr); - - irValue *entries = ir_emit_struct_ep(proc, internal_ptr, 1); + irValue *entries = ir_map_entries_ptr(proc, expr); irValue *elem = ir_emit_struct_ep(proc, entries, 0); elem = ir_emit_load(proc, elem); @@ -6902,28 +6934,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { if (is_type_pointer(type_deref(ir_addr_type(addr)))) { map = ir_addr_load(proc, addr); } - irValue *count_ptr = ir_add_local_generated(proc, t_int); - irValue *count_ptr_ptr = ir_add_local_generated(proc, t_int_ptr); - ir_emit_store(proc, count_ptr_ptr, count_ptr); - - irBlock *not_nil_block = ir_new_block(proc, nullptr, "map.not.nil.block"); - irBlock *end_nil_block = ir_new_block(proc, nullptr, "map.end.nil.block"); - { - Type *itp = make_type_pointer(a, et->Map.internal_type); - irValue *data_ptr = ir_emit_transmute(proc, map, itp); - irValue *internal_ptr = ir_emit_load(proc, data_ptr); - - irValue *cond = ir_emit_comp(proc, Token_NotEq, internal_ptr, v_raw_nil); - ir_emit_if(proc, cond, not_nil_block, end_nil_block); - ir_start_block(proc, not_nil_block); - - irValue *entries_ptr = ir_emit_struct_ep(proc, internal_ptr, 1); - irValue *cp = ir_emit_struct_ep(proc, entries_ptr, 1); - ir_emit_store(proc, count_ptr_ptr, cp); - ir_emit_jump(proc, end_nil_block); - } - ir_start_block(proc, end_nil_block); - ir_build_range_indexed(proc, map, val1_type, ir_emit_load(proc, count_ptr_ptr), &val, &key, &loop, &done); + irValue *entries_ptr = ir_map_entries_ptr(proc, map); + irValue *count_ptr = ir_emit_struct_ep(proc, entries_ptr, 1); + ir_build_range_indexed(proc, map, val1_type, count_ptr, &val, &key, &loop, &done); break; } case Type_Array: { @@ -6955,7 +6968,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { slice = ir_emit_load(proc, slice); } else { count_ptr = ir_add_local_generated(proc, t_int); - ir_emit_store(proc, count_ptr, ir_slice_count(proc, slice)); + ir_emit_store(proc, count_ptr, ir_slice_len(proc, slice)); } ir_build_range_indexed(proc, slice, val0_type, count_ptr, &val, &key, &loop, &done); break; |