diff options
| author | gingerBill <bill@gingerbill.org> | 2023-05-29 23:24:03 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-05-29 23:24:03 +0100 |
| commit | f07453d0aee436ba8c0f81cedfde5db3a7bbe1b4 (patch) | |
| tree | 4314776543e88f46c040e8bb7296571bbd37e683 /src | |
| parent | 97490c6445cb3ba85f470e64e6ed6d24394c421a (diff) | |
Support `#reverse` on `#soa` arrays
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_stmt.cpp | 4 | ||||
| -rw-r--r-- | src/llvm_backend_stmt.cpp | 41 |
2 files changed, 32 insertions, 13 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index c64de40c7..73aaa1c37 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1596,10 +1596,6 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) if (is_ptr) use_by_reference_for_value = true; array_add(&vals, t->Struct.soa_elem); array_add(&vals, t_int); - - if (is_reverse) { - error(node, "#reverse for is not yet supported for #soa types"); - } } break; } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 60468c7f0..da7fdaead 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -730,6 +730,8 @@ gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs lbBlock *body = nullptr; lbBlock *done = nullptr; + bool is_reverse = rs->reverse; + lb_open_scope(p, scope); @@ -751,19 +753,40 @@ gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs lbAddr index = lb_add_local_generated(p, t_int, false); - lb_addr_store(p, index, lb_const_int(p->module, t_int, cast(u64)-1)); - loop = lb_create_block(p, "for.soa.loop"); - lb_emit_jump(p, loop); - lb_start_block(p, loop); + lbValue incr = {}; + lbValue cond = {}; - lbValue incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(p->module, t_int, 1), t_int); - lb_addr_store(p, index, incr); + if (!is_reverse) { + lb_addr_store(p, index, lb_const_int(p->module, t_int, cast(u64)-1)); + + loop = lb_create_block(p, "for.soa.loop"); + lb_emit_jump(p, loop); + lb_start_block(p, loop); + + incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(p->module, t_int, 1), t_int); + lb_addr_store(p, index, incr); - body = lb_create_block(p, "for.soa.body"); - done = lb_create_block(p, "for.soa.done"); + body = lb_create_block(p, "for.soa.body"); + done = lb_create_block(p, "for.soa.done"); - lbValue cond = lb_emit_comp(p, Token_Lt, incr, count); + cond = lb_emit_comp(p, Token_Lt, incr, count); + } else { + // NOTE(bill): REVERSED LOGIC + lb_addr_store(p, index, count); + + loop = lb_create_block(p, "for.soa.loop"); + lb_emit_jump(p, loop); + lb_start_block(p, loop); + + incr = lb_emit_arith(p, Token_Sub, lb_addr_load(p, index), lb_const_int(p->module, t_int, 1), t_int); + lb_addr_store(p, index, incr); + + body = lb_create_block(p, "for.soa.body"); + done = lb_create_block(p, "for.soa.done"); + + cond = lb_emit_comp(p, Token_GtEq, incr, lb_const_int(p->module, t_int, 0)); + } lb_emit_if(p, cond, body, done); lb_start_block(p, body); |