From 4bf833b8d48df812f3a84fe1a1e7620a9aca1f2d Mon Sep 17 00:00:00 2001 From: "alexander.nutz" Date: Wed, 29 May 2024 15:58:00 +0200 Subject: [PATCH] compiling again --- ir/builder.c | 5 ++- ir/opt/cmov.c | 8 ++--- ir/opt/comparisions.c | 7 ++-- ir/opt/constant_eval.c | 12 ++----- ir/opt/dce.c | 18 ++++------ ir/opt/inline_vars.c | 11 +++--- ir/opt/join_compute.c | 14 ++------ ir/opt/ll_jumps.c | 33 ++++++++---------- ir/opt/loop_simplify.c | 79 ++++++++++++++++-------------------------- ir/opt/reduce_if.c | 30 +++++++--------- ir/opt/reduce_loops.c | 22 +++++------- ir/opt/tailcall.c | 13 +++---- ir/opt/vars.c | 10 +++--- 13 files changed, 98 insertions(+), 164 deletions(-) diff --git a/ir/builder.c b/ir/builder.c index 033d336..03dc41f 100644 --- a/ir/builder.c +++ b/ir/builder.c @@ -347,7 +347,10 @@ void vx_IrOp_remove_successor(vx_IrOp *op) { if (op && op->next) { vx_IrOp *newnext = op->next->next; vx_IrOp *old = op->next; - old->next = NULL; + + // WE DON'T DO THAT BECAUSE WE CALL REMOVE WHILE ITERATING IN THE PASSES + // old->next = NULL; + op->next = newnext; } } diff --git a/ir/opt/cmov.c b/ir/opt/cmov.c index f53effa..a5704bc 100644 --- a/ir/opt/cmov.c +++ b/ir/opt/cmov.c @@ -25,11 +25,9 @@ static vx_IrVar block_res_as_var(vx_IrBlock *parent, vx_IrBlock *block) { // cost of then + else is small enough // exactly one out -void vx_opt_cmov(vx_IrView view, vx_IrBlock *block) +void vx_opt_cmov(vx_IrBlock *block) { - for (size_t i = view.start; i < view.end; i ++) { - vx_IrOp *op = &block->ops[i]; - + for (vx_IrOp *op = block->first; op; op = op->next) { if (op->id != VX_IR_OP_IF) continue; @@ -59,7 +57,7 @@ void vx_opt_cmov(vx_IrView view, vx_IrBlock *block) vx_IrBlock *cond = vx_IrOp_param(op, VX_IR_NAME_COND)->block; - vx_IrBlock *body = vx_IrBlock_init_heap(block, i); + vx_IrBlock *body = vx_IrBlock_init_heap(block, op); vx_IrVar v0 = block_res_as_var(body, then); vx_IrVar v1 = block_res_as_var(body, els); diff --git a/ir/opt/comparisions.c b/ir/opt/comparisions.c index 7d1de2a..1354666 100644 --- a/ir/opt/comparisions.c +++ b/ir/opt/comparisions.c @@ -6,12 +6,9 @@ * `constant < a` -> `a > constant` * `constant > a` -> `a < constant` */ -void vx_opt_comparisions(vx_IrView view, - vx_IrBlock *block) +void vx_opt_comparisions(vx_IrBlock *block) { - for (size_t i = view.start; i < view.end; i ++) { - vx_IrOp *op = &block->ops[i]; - + for (vx_IrOp *op = block->first; op; op = op->next) { switch (op->id) { case VX_IR_OP_LTE: { vx_IrValue *b = vx_IrOp_param(op, VX_IR_NAME_OPERAND_B); diff --git a/ir/opt/constant_eval.c b/ir/opt/constant_eval.c index aaf64e9..b7681e9 100644 --- a/ir/opt/constant_eval.c +++ b/ir/opt/constant_eval.c @@ -2,15 +2,9 @@ #include -void vx_opt_constant_eval(vx_IrView view, - vx_IrBlock *block) +void vx_opt_constant_eval(vx_IrBlock *block) { - assert(view.block == block); - - while (vx_IrView_has_next(view)) { - // "unsafe", but we own the underlying block anyways - vx_IrOp *op = (vx_IrOp *) vx_IrView_take(view); - + for (vx_IrOp *op = block->first; op; op = op->next) { #define BINARY(what) { \ vx_IrValue *a = vx_IrOp_param(op, VX_IR_NAME_OPERAND_A); \ vx_IrValue *b = vx_IrOp_param(op, VX_IR_NAME_OPERAND_B); \ @@ -140,7 +134,5 @@ void vx_opt_constant_eval(vx_IrView view, default: break; } - - view = vx_IrView_drop(view, 1); } } diff --git a/ir/opt/dce.c b/ir/opt/dce.c index e73fbf6..a64dd94 100644 --- a/ir/opt/dce.c +++ b/ir/opt/dce.c @@ -1,23 +1,17 @@ #include "../opt.h" -static void rmcode_before_label(vx_IrBlock *block, size_t first) { - for (size_t i = first; i < block->ops_len; i ++) { - vx_IrOp *op = &block->ops[i]; - +static void rmcode_before_label(vx_IrOp *op) { + for (; op; op = op->next) { if (op->id == VX_LIR_OP_LABEL) break; - vx_IrOp_destroy(op); - vx_IrOp_init(op, VX_IR_OP_NOP, block); + vx_IrOp_remove(op); } } void vx_opt_ll_dce(vx_IrBlock *block) { - for (size_t i = 0; i < block->ops_len; i ++) { - vx_IrOp *op = &block->ops[i]; - if (vx_IrOp_ends_flow(op)) { - rmcode_before_label(block, i + 1); - } - } + for (vx_IrOp *op = block->first; op; op = op->next) + if (vx_IrOp_ends_flow(op)) + rmcode_before_label(op->next); } diff --git a/ir/opt/inline_vars.c b/ir/opt/inline_vars.c index d24388f..e56dfaf 100644 --- a/ir/opt/inline_vars.c +++ b/ir/opt/inline_vars.c @@ -1,7 +1,6 @@ #include "../opt.h" -static bool trav (vx_IrOp *op, - void *data) +static bool trav (vx_IrOp *op, void *data) { vx_IrBlock *block = data; @@ -12,14 +11,12 @@ static bool trav (vx_IrOp *op, for (size_t i = 0; i < op->outs_len; i ++) { const vx_IrVar out = op->outs[i].var; - vx_IrView_substitute_var(vx_IrView_of_all(block), block, out, value); + vx_IrBlock_substitute_var(block, out, value); } return false; } -void vx_opt_inline_vars(vx_IrView view, - vx_IrBlock *block) -{ - vx_IrView_deep_traverse(view, trav, block); +void vx_opt_inline_vars(vx_IrBlock *block) { + vx_IrBlock_deep_traverse(block, trav, block); } diff --git a/ir/opt/join_compute.c b/ir/opt/join_compute.c index 0603433..87ba66f 100644 --- a/ir/opt/join_compute.c +++ b/ir/opt/join_compute.c @@ -5,18 +5,10 @@ /** * Find identical computations and join them */ -void vx_opt_join_compute(vx_IrView view, - vx_IrBlock *block) +void vx_opt_join_compute(vx_IrBlock *block) { - assert(view.block == block); - - for (size_t i = 0; i < block->ops_len; i ++) { - vx_IrOp *op = &block->ops[i]; - - size_t j = i; - while (j --> 0) { - vx_IrOp *prev = &block->ops[j]; - + for (vx_IrOp *op = block->first; op; op = op->next) { + for (vx_IrOp *prev = block->first; prev != op; prev = prev->next) { if (prev->id != op->id || vx_IrOp_is_volatile(op) || prev->params_len != op->params_len || prev->outs_len == 0) continue; diff --git a/ir/opt/ll_jumps.c b/ir/opt/ll_jumps.c index 8dbf420..5137339 100644 --- a/ir/opt/ll_jumps.c +++ b/ir/opt/ll_jumps.c @@ -5,16 +5,15 @@ // we go trough all ops between the jump and the label // if all of them have no effect (labels, nops), we can remove the jump instruction static void part1(vx_IrBlock *block) { - vx_IrBlock *root = (vx_IrBlock*)vx_IrBlock_root(block); - for (size_t opid = 0; opid < block->ops_len; opid ++) { - vx_IrOp *op = &block->ops[opid]; + vx_IrBlock *root = vx_IrBlock_root(block); + for (vx_IrOp *op = block->first; op; op = op->next) { if (!(op->id == VX_LIR_GOTO || op->id == VX_LIR_COND)) continue; size_t label_id = vx_IrOp_param(op, VX_IR_NAME_ID)->id; - vx_IrOp *decl = vx_IrBlock_root_get_label_decl(root, label_id); + vx_IrOp *decl = root->as_root.labels[label_id].decl; if (decl->parent != op->parent) continue; @@ -23,8 +22,11 @@ static void part1(vx_IrBlock *block) { continue; bool can_opt = true; - for (size_t i = (op - block->ops) + 1; i < (size_t) (decl - block->ops); i ++) { - if (vx_IrOpType_has_effect(block->ops[i].id)) { + for (vx_IrOp *other = op->next; other; other = other->next) { + if (other == decl) + break; + + if (vx_IrOpType_has_effect(other->id)) { can_opt = false; break; } @@ -33,30 +35,26 @@ static void part1(vx_IrBlock *block) { if (!can_opt) continue; - vx_IrOp_destroy(op); - - vx_IrOp_init(op, VX_IR_OP_NOP, block); + vx_IrOp_remove(op); } } // is the jump dest just another jump? optimize that static void part2(vx_IrBlock *block) { - vx_IrBlock *root = (vx_IrBlock*)vx_IrBlock_root(block); - for (size_t opid = 0; opid < block->ops_len; opid ++) { - vx_IrOp *op = &block->ops[opid]; + vx_IrBlock *root = vx_IrBlock_root(block); + for (vx_IrOp *op = block->first; op; op = op->next) { if (!(op->id == VX_LIR_GOTO || op->id == VX_LIR_COND)) continue; size_t label_id = vx_IrOp_param(op, VX_IR_NAME_ID)->id; - vx_IrOp *decl = vx_IrBlock_root_get_label_decl(root, label_id); + vx_IrOp *decl = root->as_root.labels[label_id].decl; if (decl->parent != block) continue; - size_t decl_id = decl - block->ops; - if (decl_id + 1 < block->ops_len) { - vx_IrOp *following = &block->ops[decl_id + 1]; + if (decl->next) { + vx_IrOp *following = decl->next; if (following->id == VX_LIR_GOTO) { label_id = vx_IrOp_param(following, VX_IR_NAME_ID)->id; @@ -66,8 +64,7 @@ static void part2(vx_IrBlock *block) { } } -void vx_opt_ll_jumps(vx_IrView view, vx_IrBlock *block) { - assert(view.block == block); +void vx_opt_ll_jumps(vx_IrBlock *block) { part1(block); part2(block); } diff --git a/ir/opt/loop_simplify.c b/ir/opt/loop_simplify.c index 7996b10..48495bb 100644 --- a/ir/opt/loop_simplify.c +++ b/ir/opt/loop_simplify.c @@ -1,70 +1,49 @@ #include "../opt.h" -void vx_opt_loop_simplify(vx_IrView view, - vx_IrBlock *block) +void vx_opt_loop_simplify(vx_IrBlock *block) { - while (vx_IrView_find(&view, VX_IR_OP_FOR)) { - vx_IrOp *op = (vx_IrOp *) vx_IrView_take(view); + for (vx_IrOp *op = block->first; op; op = op->next) { + if (op->id != VX_IR_OP_FOR) + continue; vx_IrBlock *cond = vx_IrOp_param(op, VX_IR_NAME_COND)->block; const vx_IrVar condVar = cond->outs[0]; // if it will always we 0, we optimize it out if (vx_Irblock_alwaysis_var(cond, condVar, (vx_IrValue) { .type = VX_IR_VAL_IMM_INT, .imm_int = 0 })) { - vx_IrView_replace(block, view, NULL, 0); - - goto next; + vx_IrOp_remove(op); + continue; } // if it will never be 0 (not might be 0), it is always true => infinite loop if (!vx_Irblock_mightbe_var(cond, condVar, (vx_IrValue) { .type = VX_IR_VAL_IMM_INT, .imm_int = 0 })) { - vx_IrOp new; - vx_IrOp_init(&new, VX_IR_OP_INFINITE, block); - vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_START); - vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_DO); - vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_STRIDE); - vx_IrOp_steal_states(&new, op); - vx_IrOp_steal_outs(&new, op); - - vx_IrView_replace(block, view, &new, 1); - - goto next; + op->id = VX_IR_OP_INFINITE; // we could remove cond param + continue; } // if it is a less than, we can do a repeat - if (cond->ops_len > 0 && cond->ops[0].id == VX_IR_OP_LT) { + if (cond->first && cond->first->id == VX_IR_OP_LT) { + const vx_IrValue *a = vx_IrOp_param(cond->first, VX_IR_NAME_OPERAND_A); + // require it to be the counter + if (a->type != VX_IR_VAL_VAR) + continue; + if (a->var != cond->ins[0].var) + continue; + if (cond->first->outs[0].var != cond->outs[0]) + continue; + + const vx_IrValue b = *vx_IrOp_param(cond->first, VX_IR_NAME_OPERAND_B); - bool break2 = false; - do { - const vx_IrValue *a = vx_IrOp_param(&cond->ops[0], VX_IR_NAME_OPERAND_A); - // require it to be the counter - if (a->type != VX_IR_VAL_VAR) - break; - if (a->var != cond->ins[0].var) - break; - if (cond->ops[0].outs[0].var != cond->outs[0]) - break; - - const vx_IrValue b = *vx_IrOp_param(&cond->ops[0], VX_IR_NAME_OPERAND_B); - - vx_IrOp new; - vx_IrOp_init(&new, VX_IR_OP_REPEAT, block); - vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_DO); - vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_START); - vx_IrOp_add_param_s(&new, VX_IR_NAME_LOOP_ENDEX, b); - vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_STRIDE); - vx_IrOp_steal_states(&new, op); // steal all state init params - vx_IrOp_steal_outs(&new, op); - // we probably do a bit of memory leaking here... - *op = new; - - break2 = true; - } while(0); - if (break2) - goto next; // we optimized already + vx_IrOp new; + vx_IrOp_init(&new, VX_IR_OP_REPEAT, block); + vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_DO); + vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_START); + vx_IrOp_add_param_s(&new, VX_IR_NAME_LOOP_ENDEX, b); + vx_IrOp_steal_param(&new, op, VX_IR_NAME_LOOP_STRIDE); + vx_IrOp_steal_states(&new, op); // steal all state init params + vx_IrOp_steal_outs(&new, op); + // we probably do a bit of memory leaking here... + *op = new; } - - next: - view = vx_IrView_drop(view, 1); } } diff --git a/ir/opt/reduce_if.c b/ir/opt/reduce_if.c index 1d5a30d..61eae2c 100644 --- a/ir/opt/reduce_if.c +++ b/ir/opt/reduce_if.c @@ -1,12 +1,12 @@ #include "../opt.h" -void vx_opt_reduce_if(vx_IrView view, - vx_IrBlock *block) +void vx_opt_reduce_if(vx_IrBlock *block) { - const vx_IrBlock *root = vx_IrBlock_root(block); + vx_IrBlock *root = vx_IrBlock_root(block); - while (vx_IrView_find(&view, VX_IR_OP_IF)) { - vx_IrOp *op = (vx_IrOp *) vx_IrView_take(view); + for (vx_IrOp *op = block->first; op; op = op->next) { + if (op->id != VX_IR_OP_IF) + continue; vx_IrBlock *cond = vx_IrOp_param(op, VX_IR_NAME_COND)->block; const vx_IrVar condVar = cond->outs[0]; @@ -18,9 +18,8 @@ void vx_opt_reduce_if(vx_IrView view, vx_IrBlock *els = pelse ? pelse->block : NULL; if (vx_IrBlock_empty(then) && vx_IrBlock_empty(els)) { - vx_IrOp_destroy(op); - vx_IrOp_init(op, VX_IR_OP_NOP, block); - goto cont; + vx_IrOp_remove(op); + continue; } if (then) { @@ -28,11 +27,11 @@ void vx_opt_reduce_if(vx_IrView view, if (!vx_Irblock_mightbe_var(cond, condVar, (vx_IrValue) { .type = VX_IR_VAL_IMM_INT, .imm_int = 0 })) { for (size_t i = 0; i < op->outs_len; i ++) { const vx_IrVar out = op->outs[i].var; - vx_IrView_rename_var(vx_IrView_of_all(block), block, out, then->outs[i]); // does all the bookkeeping for us + vx_IrBlock_rename_var(block, out, then->outs[i]); // does all the bookkeeping for us } - vx_IrView_replace(block, view, then->ops, then->ops_len); - view = vx_IrView_drop(view, then->ops_len); + op->id = VX_IR_OP_FLATTEN_PLEASE; + vx_IrOp_add_param_s(op, VX_IR_NAME_BLOCK, *pthen); continue; } } @@ -42,11 +41,11 @@ void vx_opt_reduce_if(vx_IrView view, if (vx_Irblock_alwaysis_var(cond, condVar, (vx_IrValue) { .type = VX_IR_VAL_IMM_INT, .imm_int = 0 })) { for (size_t i = 0; i < op->outs_len; i ++) { const vx_IrVar out = op->outs[i].var; - vx_IrView_rename_var(vx_IrView_of_all(block), block, out, els->outs[i]); // does all the bookkeeping for us + vx_IrBlock_rename_var(block, out, els->outs[i]); // does all the bookkeeping for us } - vx_IrView_replace(block, view, els->ops, els->ops_len); - view = vx_IrView_drop(view, els->ops_len); + op->id = VX_IR_OP_FLATTEN_PLEASE; + vx_IrOp_add_param_s(op, VX_IR_NAME_BLOCK, *pelse); continue; } } @@ -61,8 +60,5 @@ void vx_opt_reduce_if(vx_IrView view, i --; } } - - cont: - view = vx_IrView_drop(view, 1); } } diff --git a/ir/opt/reduce_loops.c b/ir/opt/reduce_loops.c index 248e774..3ce3d03 100644 --- a/ir/opt/reduce_loops.c +++ b/ir/opt/reduce_loops.c @@ -29,13 +29,11 @@ * * But when the condition is always true, we need to make it an infinite loop! */ -void vx_opt_reduce_loops(vx_IrView view, - vx_IrBlock *block) +void vx_opt_reduce_loops(vx_IrBlock *block) { - assert(view.block == block); - - while (vx_IrView_find(&view, VX_IR_OP_FOR)) { - vx_IrOp *op = (vx_IrOp *) vx_IrView_take(view); + for (vx_IrOp *op = block->first; op; op = op->next) { + if (op->id != VX_IR_OP_IF) + continue; if (op->id == VX_IR_OP_WHILE && op->outs_len > 0) { // "fast path" for when we don't even have states vx_IrBlock **bdo = &vx_IrOp_param(op, VX_IR_NAME_LOOP_DO)->block; @@ -50,8 +48,7 @@ void vx_opt_reduce_loops(vx_IrView view, struct IrStaticIncrement si; for (stateId = 0; stateId < op->outs_len; stateId ++) { bool found = false; - for (size_t j = 0; j < newdo->ops_len; j ++) { - incOp = &newdo->ops[j]; + for (vx_IrOp *incOp = newdo->first; incOp; incOp = incOp->next) { si = vx_IrOp_detect_static_increment(incOp); if (si.detected && incOp->outs[0].var == op->outs[stateId].var && @@ -87,13 +84,10 @@ void vx_opt_reduce_loops(vx_IrView view, vx_IrOp_add_param_s(&new, VX_IR_NAME_COND, (vx_IrValue) { .type = VX_IR_VAL_BLOCK, .block = newcond }); vx_IrOp_add_param_s(&new, VX_IR_NAME_LOOP_DO, (vx_IrValue) { .type = VX_IR_VAL_BLOCK, .block = newdo }); - vx_IrOp_destroy(incOp); - vx_IrOp_init(incOp, VX_IR_OP_NOP, block); + vx_IrOp_remove(incOp); vx_IrOp_destroy(op); - (void) vx_IrView_replace(block, view, &new, 1); - } - - view = vx_IrView_drop(view, 1); + *op = new; + } } } diff --git a/ir/opt/tailcall.c b/ir/opt/tailcall.c index 506cefb..dfdd5d3 100644 --- a/ir/opt/tailcall.c +++ b/ir/opt/tailcall.c @@ -11,21 +11,19 @@ static bool trav(vx_IrOp *op, void *ignore) { } void vx_opt_tailcall(vx_IrBlock *block) { - vx_IrView_deep_traverse(vx_IrView_of_all(block), trav, NULL); + vx_IrBlock_deep_traverse(block, trav, NULL); } void vx_opt_ll_condtailcall(vx_IrBlock *block) { assert(block->is_root); - for (size_t i = 0; i < block->ops_len; i ++) { - vx_IrOp *op = &block->ops[i]; + for (vx_IrOp *op = block->first; op; op = op->next) { if (op->id != VX_LIR_COND) continue; size_t label = vx_IrOp_param(op, VX_IR_NAME_ID)->id; - vx_IrOp *label_op = vx_IrBlock_root_get_label_decl(block, label); - - vx_IrOp *tailcall = vx_IrOp_next(label_op); + vx_IrOp *label_op = block->as_root.labels[label].decl; + vx_IrOp *tailcall = label_op->next; if (tailcall == NULL) continue; @@ -41,7 +39,6 @@ void vx_opt_ll_condtailcall(vx_IrBlock *block) { vx_IrOp_steal_param(op, tailcall, VX_IR_NAME_ADDR); - vx_IrOp_destroy(tailcall); - vx_IrOp_init(tailcall, VX_IR_OP_NOP, block); + vx_IrOp_remove(tailcall); } } diff --git a/ir/opt/vars.c b/ir/opt/vars.c index a5a40f1..7b14800 100644 --- a/ir/opt/vars.c +++ b/ir/opt/vars.c @@ -1,12 +1,11 @@ #include "../opt.h" -void vx_opt_vars(vx_IrView view, vx_IrBlock *block) { - const vx_IrBlock *root = vx_IrBlock_root(block); +void vx_opt_vars(vx_IrBlock *block) { + vx_IrBlock *root = vx_IrBlock_root(block); if (root == NULL) root = block; - for (size_t i = 0; i < block->ops_len; i ++) { - vx_IrOp *op = &view.block->ops[i]; + for (vx_IrOp *op = block->first; op; op = op->next) { if (vx_IrOp_is_volatile(op)) continue; @@ -25,7 +24,6 @@ void vx_opt_vars(vx_IrView view, vx_IrBlock *block) { if (!can_rem) continue; - vx_IrOp_destroy(op); - vx_IrOp_init(op, VX_IR_OP_NOP, block); + vx_IrOp_remove(op); } }