aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_stmt.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-05-30 00:21:40 +0100
committergingerBill <bill@gingerbill.org>2023-05-30 00:21:40 +0100
commit837ba6c33b3d78dce332eeb5d5abe7da5d4f8b3a (patch)
tree4f4031c3336f360eacfe6d303ee59045c0479f58 /src/llvm_backend_stmt.cpp
parent3ab01dbc004e7c4b8eebdb5e1dc726e80bc535cc (diff)
Minor change to `#reverse for` logic; add comments explaining it
Diffstat (limited to 'src/llvm_backend_stmt.cpp')
-rw-r--r--src/llvm_backend_stmt.cpp127
1 files changed, 103 insertions, 24 deletions
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp
index 7f677b238..b305cc796 100644
--- a/src/llvm_backend_stmt.cpp
+++ b/src/llvm_backend_stmt.cpp
@@ -267,32 +267,61 @@ gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_
lbBlock *done = nullptr;
lbBlock *body = nullptr;
+ loop = lb_create_block(p, "for.index.loop");
+ body = lb_create_block(p, "for.index.body");
+ done = lb_create_block(p, "for.index.done");
- lbAddr index = {};
- lbValue incr = {};
- lbValue cond = {};
-
- index = lb_add_local_generated(p, t_int, false);
+ lbAddr index = lb_add_local_generated(p, t_int, false);
if (!is_reverse) {
+ /*
+ for x, i in array {
+ ...
+ }
+
+ i := -1
+ for {
+ i += 1
+ if !(i < len(array)) {
+ break
+ }
+ #no_bounds_check x := array[i]
+ ...
+ }
+ */
+
lb_addr_store(p, index, lb_const_int(m, t_int, cast(u64)-1));
- loop = lb_create_block(p, "for.index.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(m, t_int, 1), t_int);
+ lbValue incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(m, t_int, 1), t_int);
lb_addr_store(p, index, incr);
- body = lb_create_block(p, "for.index.body");
- done = lb_create_block(p, "for.index.done");
if (count.value == nullptr) {
GB_ASSERT(count_ptr.value != nullptr);
count = lb_emit_load(p, count_ptr);
}
- cond = lb_emit_comp(p, Token_Lt, incr, count);
+ lbValue cond = lb_emit_comp(p, Token_Lt, incr, count);
+ lb_emit_if(p, cond, body, done);
} else {
// NOTE(bill): REVERSED LOGIC
+ /*
+ #reverse for x, i in array {
+ ...
+ }
+
+ i := len(array)
+ for {
+ i -= 1
+ if i < 0 {
+ break
+ }
+ #no_bounds_check x := array[i]
+ ...
+ }
+ */
+
if (count.value == nullptr) {
GB_ASSERT(count_ptr.value != nullptr);
count = lb_emit_load(p, count_ptr);
@@ -300,19 +329,16 @@ gb_internal void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_
count = lb_emit_conv(p, count, t_int);
lb_addr_store(p, index, count);
- loop = lb_create_block(p, "for.index.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(m, t_int, 1), t_int);
+ lbValue incr = lb_emit_arith(p, Token_Sub, lb_addr_load(p, index), lb_const_int(m, t_int, 1), t_int);
lb_addr_store(p, index, incr);
- body = lb_create_block(p, "for.index.body");
- done = lb_create_block(p, "for.index.done");
- cond = lb_emit_comp(p, Token_GtEq, incr, lb_const_int(m, t_int, 0));
+ lbValue anti_cond = lb_emit_comp(p, Token_Lt, incr, lb_const_int(m, t_int, 0));
+ lb_emit_if(p, anti_cond, done, body);
}
- lb_emit_if(p, cond, body, done);
lb_start_block(p, body);
idx = lb_addr_load(p, index);
@@ -509,6 +535,18 @@ gb_internal void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_t
lbValue cond = {};
if (!is_reverse) {
+ /*
+ for c, offset in str {
+ ...
+ }
+
+ offset := 0
+ for offset < len(str) {
+ c, _w := string_decode_rune(str[offset:])
+ ...
+ offset += _w
+ }
+ */
lb_addr_store(p, offset_, lb_const_int(m, t_int, 0));
lb_emit_jump(p, loop);
@@ -519,6 +557,18 @@ gb_internal void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_t
cond = lb_emit_comp(p, Token_Lt, offset, count);
} else {
// NOTE(bill): REVERSED LOGIC
+ /*
+ #reverse for c, offset in str {
+ ...
+ }
+
+ offset := len(str)
+ for offset > 0 {
+ c, _w := string_decode_last_rune(str[:offset])
+ offset -= _w
+ ...
+ }
+ */
lb_addr_store(p, offset_, count);
lb_emit_jump(p, loop);
@@ -784,40 +834,69 @@ gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs
lbAddr index = lb_add_local_generated(p, t_int, false);
- lbValue incr = {};
- lbValue cond = {};
-
if (!is_reverse) {
+ /*
+ for x, i in array {
+ ...
+ }
+
+ i := -1
+ for {
+ i += 1
+ if !(i < len(array)) {
+ break
+ }
+ x := array[i] // but #soa-ified
+ ...
+ }
+ */
+
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);
+ 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);
body = lb_create_block(p, "for.soa.body");
done = lb_create_block(p, "for.soa.done");
- cond = lb_emit_comp(p, Token_Lt, incr, count);
+ lbValue cond = lb_emit_comp(p, Token_Lt, incr, count);
+ lb_emit_if(p, cond, body, done);
} else {
// NOTE(bill): REVERSED LOGIC
+ /*
+ #reverse for x, i in array {
+ ...
+ }
+
+ i := len(array)
+ for {
+ i -= 1
+ if i < 0 {
+ break
+ }
+ #no_bounds_check x := array[i] // but #soa-ified
+ ...
+ }
+ */
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);
+ lbValue 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));
+ lbValue cond = lb_emit_comp(p, Token_Lt, incr, lb_const_int(p->module, t_int, 0));
+ lb_emit_if(p, cond, done, body);
}
- lb_emit_if(p, cond, body, done);
lb_start_block(p, body);