From fa4e95105f7364367dce8ac435efed182fba6759 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 7 Jul 2018 11:13:20 +0100 Subject: Loop array arithmetic on large arrays --- src/ir.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 9103b5491..c98cec5f4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2192,6 +2192,8 @@ 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); @@ -2253,11 +2255,43 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * irValue *res = ir_add_local_generated(proc, type); i64 count = base_type(type)->Array.count; - 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)); + + bool inline_array_arith = type_size_of(type) <= build_context.max_align; + + 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 *z = ir_emit_arith(proc, op, x, y, elem_type); + 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(proc->module->allocator, 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"); + + 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 *z = ir_emit_arith(proc, op, x, y, elem_type); - ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z); + ir_emit_store(proc, ir_emit_array_ep(proc, res, idx), z); + + ir_emit_increment(proc, idx_addr); + ir_emit_jump(proc, loop); + + ir_start_block(proc, done); } ir_emit_comment(proc, str_lit("array.arith.end")); return ir_emit_load(proc, res); -- cgit v1.2.3