|
@@ -160,8 +160,6 @@ gbAllocator ir_allocator(void) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
#define IR_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
|
|
#define IR_TYPE_INFO_DATA_NAME "__$type_info_data"
|
|
|
#define IR_TYPE_INFO_TYPES_NAME "__$type_info_types_data"
|
|
@@ -2190,12 +2188,53 @@ irValue *ir_map_cap(irProcedure *proc, irValue *value) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
void ir_emit_increment(irProcedure *proc, irValue *addr);
|
|
|
irValue *ir_emit_array_ep(irProcedure *proc, irValue *s, irValue *index);
|
|
|
irValue *ir_emit_array_epi(irProcedure *proc, irValue *s, i32 index);
|
|
|
irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index);
|
|
|
|
|
|
+struct irLoopData {
|
|
|
+ irValue *idx_addr;
|
|
|
+ irValue *idx;
|
|
|
+ irBlock *body;
|
|
|
+ irBlock *done;
|
|
|
+ irBlock *loop;
|
|
|
+};
|
|
|
+
|
|
|
+irLoopData ir_loop_start(irProcedure *proc, isize count) {
|
|
|
+ irLoopData data = {};
|
|
|
+
|
|
|
+ irValue *max = ir_const_int(count);
|
|
|
+
|
|
|
+ data.idx_addr = ir_add_local_generated(proc, t_int);
|
|
|
+
|
|
|
+ data.body = ir_new_block(proc, nullptr, "loop.body");
|
|
|
+ data.done = ir_new_block(proc, nullptr, "loop.done");
|
|
|
+ data.loop = ir_new_block(proc, nullptr, "loop.loop");
|
|
|
+
|
|
|
+ ir_emit_jump(proc, data.loop);
|
|
|
+ ir_start_block(proc, data.loop);
|
|
|
+
|
|
|
+ data.idx = ir_emit_load(proc, data.idx_addr);
|
|
|
+
|
|
|
+ irValue *cond = ir_emit_comp(proc, Token_Lt, data.idx, max);
|
|
|
+ ir_emit_if(proc, cond, data.body, data.done);
|
|
|
+ ir_start_block(proc, data.body);
|
|
|
+
|
|
|
+ return data;
|
|
|
+}
|
|
|
+
|
|
|
+void ir_loop_end(irProcedure *proc, irLoopData const &data) {
|
|
|
+ if (data.idx_addr != nullptr) {
|
|
|
+ ir_emit_increment(proc, data.idx_addr);
|
|
|
+ ir_emit_jump(proc, data.loop);
|
|
|
+ ir_start_block(proc, data.done);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
irValue *ir_emit_ptr_offset(irProcedure *proc, irValue *ptr, irValue *offset) {
|
|
|
offset = ir_emit_conv(proc, offset, t_int);
|
|
|
return ir_emit(proc, ir_instr_ptr_offset(proc, ptr, offset));
|
|
@@ -2223,10 +2262,26 @@ irValue *ir_emit_unary_arith(irProcedure *proc, TokenKind op, irValue *x, Type *
|
|
|
Type *elem_type = base_array_type(type);
|
|
|
|
|
|
irValue *res = ir_add_local_generated(proc, type);
|
|
|
- for (i32 i = 0; i < tl->Array.count; i++) {
|
|
|
- irValue *e = ir_emit_load(proc, ir_emit_array_epi(proc, val, i));
|
|
|
+
|
|
|
+ bool inline_array_arith = type_size_of(type) <= build_context.max_align;
|
|
|
+
|
|
|
+ i32 count = cast(i32)tl->Array.count;
|
|
|
+
|
|
|
+ if (inline_array_arith) {
|
|
|
+ // inline
|
|
|
+ for (i32 i = 0; i < count; i++) {
|
|
|
+ irValue *e = ir_emit_load(proc, ir_emit_array_epi(proc, val, i));
|
|
|
+ irValue *z = ir_emit_unary_arith(proc, op, e, elem_type);
|
|
|
+ ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ auto loop_data = ir_loop_start(proc, count);
|
|
|
+
|
|
|
+ irValue *e = ir_emit_load(proc, ir_emit_array_ep(proc, val, loop_data.idx));
|
|
|
irValue *z = ir_emit_unary_arith(proc, op, e, elem_type);
|
|
|
- ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z);
|
|
|
+ ir_emit_store(proc, ir_emit_array_ep(proc, res, loop_data.idx), z);
|
|
|
+
|
|
|
+ ir_loop_end(proc, loop_data);
|
|
|
}
|
|
|
ir_emit_comment(proc, str_lit("array.arith.end"));
|
|
|
return ir_emit_load(proc, res);
|
|
@@ -2266,31 +2321,14 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|
|
ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z);
|
|
|
}
|
|
|
} else {
|
|
|
- irValue *idx_addr = ir_add_local_generated(proc, t_int);
|
|
|
- irValue *max = ir_const_int(count);
|
|
|
-
|
|
|
- irBlock *body = ir_new_block(proc, nullptr, "array.arith.body");
|
|
|
- irBlock *done = ir_new_block(proc, nullptr, "array.arith.done");
|
|
|
- irBlock *loop = ir_new_block(proc, nullptr, "array.arith.loop");
|
|
|
+ auto loop_data = ir_loop_start(proc, count);
|
|
|
|
|
|
- ir_emit_jump(proc, loop);
|
|
|
- ir_start_block(proc, loop);
|
|
|
-
|
|
|
- irValue *idx = ir_emit_load(proc, idx_addr);
|
|
|
-
|
|
|
- irValue *cond = ir_emit_comp(proc, Token_Lt, idx, max);
|
|
|
- ir_emit_if(proc, cond, body, done);
|
|
|
- ir_start_block(proc, body);
|
|
|
-
|
|
|
- irValue *x = ir_emit_load(proc, ir_emit_array_ep(proc, lhs, idx));
|
|
|
- irValue *y = ir_emit_load(proc, ir_emit_array_ep(proc, rhs, idx));
|
|
|
+ irValue *x = ir_emit_load(proc, ir_emit_array_ep(proc, lhs, loop_data.idx));
|
|
|
+ irValue *y = ir_emit_load(proc, ir_emit_array_ep(proc, rhs, loop_data.idx));
|
|
|
irValue *z = ir_emit_arith(proc, op, x, y, elem_type);
|
|
|
- ir_emit_store(proc, ir_emit_array_ep(proc, res, idx), z);
|
|
|
-
|
|
|
- ir_emit_increment(proc, idx_addr);
|
|
|
- ir_emit_jump(proc, loop);
|
|
|
+ ir_emit_store(proc, ir_emit_array_ep(proc, res, loop_data.idx), z);
|
|
|
|
|
|
- ir_start_block(proc, done);
|
|
|
+ ir_loop_end(proc, loop_data);
|
|
|
}
|
|
|
ir_emit_comment(proc, str_lit("array.arith.end"));
|
|
|
return ir_emit_load(proc, res);
|
|
@@ -2353,6 +2391,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|
|
}
|
|
|
|
|
|
|
|
|
+#if 0
|
|
|
if (op == Token_Add) {
|
|
|
if (is_type_pointer(t_left)) {
|
|
|
irValue *ptr = ir_emit_conv(proc, left, type);
|
|
@@ -2381,7 +2420,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|
|
return ir_emit_arith(proc, Token_Quo, diff, elem_size, type);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+#endif
|
|
|
|
|
|
switch (op) {
|
|
|
case Token_Shl:
|
|
@@ -2416,14 +2455,13 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|
|
}
|
|
|
|
|
|
if (op == Token_ModMod) {
|
|
|
- irValue *n = left;
|
|
|
- irValue *m = right;
|
|
|
if (is_type_unsigned(type)) {
|
|
|
- return ir_emit_arith(proc, Token_Mod, n, m, type);
|
|
|
+ op = Token_Mod;
|
|
|
+ } else {
|
|
|
+ irValue *a = ir_emit_arith(proc, Token_Mod, left, right, type);
|
|
|
+ irValue *b = ir_emit_arith(proc, Token_Add, a, right, type);
|
|
|
+ return ir_emit_arith(proc, Token_Mod, b, right, type);
|
|
|
}
|
|
|
- irValue *a = ir_emit_arith(proc, Token_Mod, n, m, type);
|
|
|
- irValue *b = ir_emit_arith(proc, Token_Add, a, m, type);
|
|
|
- return ir_emit_arith(proc, Token_Mod, b, m, type);
|
|
|
}
|
|
|
|
|
|
return ir_emit(proc, ir_instr_binary_op(proc, op, left, right, type));
|
|
@@ -2550,12 +2588,26 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
|
|
|
cmp_op = Token_Or;
|
|
|
}
|
|
|
|
|
|
- // IMPORTANT TODO(bill): Make this much more efficient
|
|
|
- for (i32 i = 0; i < tl->Array.count; i++) {
|
|
|
- irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
|
|
|
- irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
|
|
|
+ bool inline_array_arith = type_size_of(tl) <= build_context.max_align;
|
|
|
+ i32 count = cast(i32)tl->Array.count;
|
|
|
+
|
|
|
+ if (inline_array_arith) {
|
|
|
+ // inline
|
|
|
+ for (i32 i = 0; i < count; i++) {
|
|
|
+ irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
|
|
|
+ irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
|
|
|
+ irValue *cmp = ir_emit_comp(proc, op_kind, x, y);
|
|
|
+ res = ir_emit_arith(proc, cmp_op, res, cmp, t_bool);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ auto loop_data = ir_loop_start(proc, count);
|
|
|
+
|
|
|
+ irValue *x = ir_emit_load(proc, ir_emit_array_ep(proc, lhs, loop_data.idx));
|
|
|
+ irValue *y = ir_emit_load(proc, ir_emit_array_ep(proc, rhs, loop_data.idx));
|
|
|
irValue *cmp = ir_emit_comp(proc, op_kind, x, y);
|
|
|
res = ir_emit_arith(proc, cmp_op, res, cmp, t_bool);
|
|
|
+
|
|
|
+ ir_loop_end(proc, loop_data);
|
|
|
}
|
|
|
|
|
|
return ir_emit_conv(proc, res, t_bool);
|
|
@@ -6610,34 +6662,13 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
|
|
case_ast_node(bs, EmptyStmt, node);
|
|
|
case_end;
|
|
|
|
|
|
- // case_ast_node(fb, ForeignBlockDecl, node);
|
|
|
- // ir_build_stmt_list(proc, fb->decls);
|
|
|
- // case_end;
|
|
|
-
|
|
|
case_ast_node(us, UsingStmt, node);
|
|
|
- for_array(i, us->list) {
|
|
|
- Ast *decl = unparen_expr(us->list[i]);
|
|
|
- // if (decl->kind == Ast_GenDecl) {
|
|
|
- // ir_build_stmt(proc, decl);
|
|
|
- // }
|
|
|
- }
|
|
|
case_end;
|
|
|
|
|
|
case_ast_node(ws, WhenStmt, node);
|
|
|
ir_build_when_stmt(proc, ws);
|
|
|
case_end;
|
|
|
|
|
|
- #if 0
|
|
|
- case_ast_node(s, IncDecStmt, node);
|
|
|
- TokenKind op = Token_Add;
|
|
|
- if (s->op.kind == Token_Dec) {
|
|
|
- op = Token_Sub;
|
|
|
- }
|
|
|
- irAddr const &addr = ir_build_addr(proc, s->expr);
|
|
|
- ir_build_assign_op(proc, addr, v_one, op);
|
|
|
- case_end;
|
|
|
- #endif
|
|
|
-
|
|
|
case_ast_node(vd, ValueDecl, node);
|
|
|
if (vd->is_mutable) {
|
|
|
irModule *m = proc->module;
|
|
@@ -6853,9 +6884,12 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
|
|
case_ast_node(is, IfStmt, node);
|
|
|
ir_emit_comment(proc, str_lit("IfStmt"));
|
|
|
if (is->init != nullptr) {
|
|
|
+ // TODO(bill): Should this have a separate block to begin with?
|
|
|
+ #if 1
|
|
|
irBlock *init = ir_new_block(proc, node, "if.init");
|
|
|
ir_emit_jump(proc, init);
|
|
|
ir_start_block(proc, init);
|
|
|
+ #endif
|
|
|
ir_build_stmt(proc, is->init);
|
|
|
}
|
|
|
irBlock *then = ir_new_block(proc, node, "if.then");
|
|
@@ -6891,9 +6925,11 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
|
|
ir_emit_comment(proc, str_lit("ForStmt"));
|
|
|
|
|
|
if (fs->init != nullptr) {
|
|
|
+ #if 1
|
|
|
irBlock *init = ir_new_block(proc, node, "for.init");
|
|
|
ir_emit_jump(proc, init);
|
|
|
ir_start_block(proc, init);
|
|
|
+ #endif
|
|
|
ir_build_stmt(proc, fs->init);
|
|
|
}
|
|
|
irBlock *body = ir_new_block(proc, node, "for.body");
|