diff options
| author | gingerBill <bill@gingerbill.org> | 2022-11-24 01:27:39 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-11-24 01:27:39 +0000 |
| commit | 0befadde1dc9229526f0d200e423ed6360b1c1a4 (patch) | |
| tree | f38894e095ea38ed971b67a05f01bf97875c5838 /src/llvm_backend_stmt.cpp | |
| parent | aef8b25a8e8787759839eb6f02fea61390dc25bc (diff) | |
Basic copy elision support for multiple return values
Diffstat (limited to 'src/llvm_backend_stmt.cpp')
| -rw-r--r-- | src/llvm_backend_stmt.cpp | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 949ceed7d..d026d2ecd 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -698,13 +698,13 @@ void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1 i32 tuple_count = cast(i32)tuple->Tuple.variables.count; i32 cond_index = tuple_count-1; - lbValue cond = lb_emit_struct_ev(p, tuple_value, cond_index); + lbValue cond = lb_emit_tuple_ev(p, tuple_value, cond_index); lb_emit_if(p, cond, body, done); lb_start_block(p, body); - if (val0_) *val0_ = lb_emit_struct_ev(p, tuple_value, 0); - if (val1_) *val1_ = lb_emit_struct_ev(p, tuple_value, 1); + if (val0_) *val0_ = lb_emit_tuple_ev(p, tuple_value, 0); + if (val1_) *val1_ = lb_emit_tuple_ev(p, tuple_value, 1); if (loop_) *loop_ = loop; if (done_) *done_ = done; } @@ -1543,6 +1543,24 @@ void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { lb_add_member(p->module, mangled_name, global_val); } } +void lb_append_tuple_values(lbProcedure *p, Array<lbValue> *dst_values, lbValue src_value) { + Type *t = src_value.type; + if (t->kind == Type_Tuple) { + lbTupleFix *tf = map_get(&p->tuple_fix_map, src_value.value); + if (tf) { + for_array(j, tf->values) { + array_add(dst_values, tf->values[j]); + } + } else { + for_array(i, t->Tuple.variables) { + lbValue v = lb_emit_tuple_ev(p, src_value, cast(i32)i); + array_add(dst_values, v); + } + } + } else { + array_add(dst_values, src_value); + } +} void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> const &values) { @@ -1554,18 +1572,8 @@ void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> cons for_array(i, values) { Ast *rhs = values[i]; - if (is_type_tuple(type_of_expr(rhs))) { - lbValue init = lb_build_expr(p, rhs); - Type *t = init.type; - GB_ASSERT(t->kind == Type_Tuple); - for_array(i, t->Tuple.variables) { - lbValue v = lb_emit_struct_ev(p, init, cast(i32)i); - array_add(&inits, v); - } - } else { - lbValue init = lb_build_expr(p, rhs); - array_add(&inits, init); - } + lbValue init = lb_build_expr(p, rhs); + lb_append_tuple_values(p, &inits, init); } GB_ASSERT(lvals.count == inits.count); @@ -1655,15 +1663,7 @@ void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) { if (res_count != 0) { for (isize res_index = 0; res_index < res_count; res_index++) { lbValue res = lb_build_expr(p, return_results[res_index]); - Type *t = res.type; - if (t->kind == Type_Tuple) { - for_array(i, t->Tuple.variables) { - lbValue v = lb_emit_struct_ev(p, res, cast(i32)i); - array_add(&results, v); - } - } else { - array_add(&results, res); - } + lb_append_tuple_values(p, &results, res); } } else { for (isize res_index = 0; res_index < return_count; res_index++) { |