From cc129716719f71bfeb335097f491310ce0968867 Mon Sep 17 00:00:00 2001 From: alex-s168 Date: Tue, 5 Nov 2024 21:52:22 +0100 Subject: [PATCH] refactor done --- build.c | 2 +- build.sh | 2 - build_c | 2 +- cg/x86_stupid/cg.c | 12 ++-- common/targets.cdef | 2 +- ir/ir.c | 87 ++---------------------- ir/ops.cdef | 4 +- ir/opt/cmov.c | 15 ++-- ir/opt/comparisions.c | 10 +-- ir/opt/constant_eval.c | 5 +- ir/opt/dce.c | 6 +- ir/opt/if_opts.c | 6 +- ir/opt/inline_vars.c | 17 +++-- ir/opt/join_compute.c | 6 +- ir/opt/ll_binary.c | 4 +- ir/opt/ll_jumps.c | 12 ++-- ir/opt/ll_sched.c | 5 +- ir/opt/loop_simplify.c | 4 +- ir/opt/reduce_if.c | 4 +- ir/opt/reduce_loops.c | 5 +- ir/opt/simple_patterns.c | 4 +- ir/opt/swap_if_cases.c | 7 +- ir/opt/tailcall.c | 12 ++-- ir/opt/vars.c | 8 ++- ir/passes.c | 79 +++++++++++++++++++++ ir/transform/cmov_expand.c | 8 ++- ir/transform/ll_finalize.c | 10 +-- ir/transform/lower_loops.c | 6 +- ir/transform/normalize.c | 9 +-- ir/transform/share_slots.c | 7 +- ir/transform/single_assign.c | 14 ++-- ir/transform/single_assign_conditional.c | 10 ++- ir/transform/ssair_llir_lower.c | 8 +-- ir/verify_cir.c | 2 +- 34 files changed, 208 insertions(+), 186 deletions(-) diff --git a/build.c b/build.c index 92b4f03..cc1780c 100644 --- a/build.c +++ b/build.c @@ -59,7 +59,7 @@ struct CompileData ir_files[] = { struct CompileData ir_opt_files[] = { DIR("build"), DIR("build/ir"), - SP(CT_C, "ir/opt.c"), + SP(CT_C, "ir/passes.c"), DIR("build/ir/opt"), SP(CT_C, "ir/opt/tailcall.c"), diff --git a/build.sh b/build.sh index e510d43..ab3b9ee 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,3 @@ -#!/usr/bin/bash - set -e : ${CFLAGS:="-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-comment -Wno-format -Wno-sign-compare -Wno-char-subscripts -Wno-implicit-fallthrough -Wno-missing-braces -Werror -g -glldb"} diff --git a/build_c b/build_c index 4e496e9..05cb55b 160000 --- a/build_c +++ b/build_c @@ -1 +1 @@ -Subproject commit 4e496e9fd9f9d14b649a3b3a6a813ee1d6459bfa +Subproject commit 05cb55bad0e87a8987326099f614724b97808d7e diff --git a/cg/x86_stupid/cg.c b/cg/x86_stupid/cg.c index ae3739e..33b6163 100644 --- a/cg/x86_stupid/cg.c +++ b/cg/x86_stupid/cg.c @@ -1320,11 +1320,7 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file) return op->next; } -vx_cg_x86stupid vx_cg_x86stupid_options = (vx_cg_x86stupid) { - .use_red_zone = true, -}; - -void vx_cg_x86stupid_gen(vx_IrBlock* block, FILE* out) { +void vx_cg_x86stupid_gen(vx_CU* cu, vx_IrBlock* block, FILE* out) { fprintf(out, "%s:\n", block->name); assert(block->is_root); @@ -1652,7 +1648,7 @@ void vx_cg_x86stupid_gen(vx_IrBlock* block, FILE* out) { bool needProlog = (stackOff > 0 && !is_leaf) || stackOff > 128 || - (stackOff > 0 && !vx_cg_x86stupid_options.use_red_zone); + (stackOff > 0 && cu->target.flags.x86[vx_Target_X86__NO_REDZONE]); needEpilog = false; if (anyPlaced || needProlog) { @@ -1660,10 +1656,10 @@ void vx_cg_x86stupid_gen(vx_IrBlock* block, FILE* out) { needEpilog = true; } - vx_IrBlock_ll_finalize(block, needEpilog); + vx_IrBlock_ll_finalize(cu, block, needEpilog); if (needProlog) { - if (is_leaf && vx_cg_x86stupid_options.use_red_zone) { + if (is_leaf && cu->target.flags.x86[vx_Target_X86__NO_REDZONE]) { size_t v = 128 - stackOff; fprintf(out, "sub rsp, %zu\n", v); } else { diff --git a/common/targets.cdef b/common/targets.cdef index 3cf0971..a4c7a06 100644 --- a/common/targets.cdef +++ b/common/targets.cdef @@ -7,5 +7,5 @@ table vx_TargetArch ( entry ETCA name "etca" ; - // add target + # // add target } diff --git a/ir/ir.c b/ir/ir.c index 6fd8781..665251f 100644 --- a/ir/ir.c +++ b/ir/ir.c @@ -90,20 +90,6 @@ vx_IrOp *vx_IrBlock_tail(vx_IrBlock *block) { return op; } -void vx_IrBlock_llir_compact(vx_IrBlock *root) { - assert(root->is_root); - - for (vx_IrVar idx = 0; idx < root->as_root.vars_len; idx ++) { - if (root->as_root.vars[idx].ll_type == NULL) { - if (idx + 1 >= root->as_root.vars_len) break; - for (vx_IrVar after = idx + 1; after < root->as_root.vars_len; after ++) { - assert(root != NULL && root->is_root); - vx_IrBlock_renameVar(root, after, after - 1, VX_RENAME_VAR_BOTH); - } - } - } -} - // TODO: remove cir checks and make sure fn called after cir type expand size_t vx_IrType_size(vx_IrType *ty) { @@ -176,71 +162,6 @@ vx_IrTypeRef vx_IrValue_type(vx_IrBlock* root, vx_IrValue value) { } } -void vx_CIrBlock_fix(vx_IrBlock* block) { - vx_IrBlock* root = vx_IrBlock_root(block); - - for (size_t i = 0; i < block->ins_len; i ++) - vx_IrBlock_putVar(root, block->ins[i].var, NULL); - - for (vx_IrOp* op = block->first; op; op = op->next) { - for (size_t i = 0; i < op->outs_len; i ++) - vx_IrBlock_putVar(root, op->outs[i].var, op); - - FOR_INPUTS(op, inp, { - if (inp.type == VX_IR_VAL_BLOCK) - vx_CIrBlock_fix(inp.block); - }); - } -} - -void vx_IrBlock_llir_fix_decl(vx_IrBlock *root) { - assert(root->is_root); - - // TODO: WHY THE FUCK IS THIS EVEN REQUIRED???? - - memset(root->as_root.labels, 0, sizeof(*root->as_root.labels) * root->as_root.labels_len); - memset(root->as_root.vars, 0, sizeof(*root->as_root.vars) * root->as_root.vars_len); - - for (size_t i = 0; i < root->ins_len; i ++) { - vx_IrVar v = root->ins[i].var; - assert(v < root->as_root.vars_len); - root->as_root.vars[v].ll_type = root->ins[i].type; - } - - for (vx_IrOp *op = root->first; op; op = op->next) { - for (size_t j = 0; j < op->outs_len; j ++) { - vx_IrTypedVar out = op->outs[j]; - if (vx_IrType_size(out.type) == 0) { - fprintf(stderr, "size of type %s in 0", out.type->debugName); - exit(1); - } - assert(out.var < root->as_root.vars_len); - vx_IrOp **decl = &root->as_root.vars[out.var].decl; - if (*decl == NULL) { - *decl = op; - root->as_root.vars[out.var].ll_type = out.type; - } - } - - if (op->id == VX_IR_OP_LABEL) { - size_t id = vx_IrOp_param(op, VX_IR_NAME_ID)->id; - assert(id < root->as_root.labels_len); - vx_IrOp **decl = &root->as_root.labels[id].decl; - if (*decl == NULL) { - *decl = op; - } - } - } - - for (vx_IrOp* op = root->first; op; op = op->next) { - if (op->id == VX_IR_OP_PLACE) { - vx_IrValue val = *vx_IrOp_param(op, VX_IR_NAME_VAR); - assert(val.type == VX_IR_VAL_VAR && "inliner fucked up (VX_IR_OP_PLACE)"); - root->as_root.vars[val.var].ever_placed = true; - } - } -} - void vx_IrOp_warn(vx_IrOp *op, const char *optMsg0, const char *optMsg1) { vx_IrBlock *parent = op ? op->parent : NULL; if (parent) { @@ -402,20 +323,20 @@ int vx_CU_compile(vx_CU * cu, FOR_BLOCK({ vx_IrBlock_llir_preLower_loops(cu, block); vx_IrBlock_llir_preLower_ifs(cu, block); - opt_preLower(cu, block); + vx_opt_preLower(cu, block); vx_IrBlock_llir_lower(cu, block); vx_IrBlock_llir_fix_decl(cu, block); }); FOR_BLOCK({ - opt_ll(cu, block); + vx_opt_ll(cu, block); if (optionalOptimizedLlIr != NULL) vx_IrBlock_dump(block, optionalOptimizedLlIr, 0); llir_prep_lower(cu, block); - vx_IrBlock_dump(cu, block, stdout, 0); + vx_IrBlock_dump(block, stdout, 0); }); if (optionalAsm) { @@ -428,7 +349,7 @@ int vx_CU_compile(vx_CU * cu, fprintf(optionalAsm, " global %s\n", cb->v.ir->name); switch (cu->target.arch) { - case VX_TARGET_X86: + case vx_TargetArch_X86_64: vx_cg_x86stupid_gen(cu, cb->v.ir, optionalAsm); break; diff --git a/ir/ops.cdef b/ir/ops.cdef index 65c4c6b..afa7b83 100644 --- a/ir/ops.cdef +++ b/ir/ops.cdef @@ -10,7 +10,7 @@ table vx_IrOpType ( volatile bool ; sideEffect bool ; - boolInv ? str ; + boolInv ? str ; ) enum_entry_prefix "VX_IR_OP_" { @@ -182,7 +182,7 @@ enum_entry_prefix "VX_IR_OP_" entry SUB args "a: value, b: value" debug "sub" - descr "subctract the float or integer b from the float or intege a ; both values have to have the same type as the output type" + descr "subtract the float or integer b from the float or intege a ; both values have to have the same type as the output type" inlineCost 1 execCost 2 endsFlow false diff --git a/ir/opt/cmov.c b/ir/opt/cmov.c index c90b8be..0ff048a 100644 --- a/ir/opt/cmov.c +++ b/ir/opt/cmov.c @@ -1,9 +1,6 @@ -#include "../opt.h" +#include "../passes.h" static vx_IrVar block_res_as_var(vx_IrBlock *parent, vx_IrBlock *block) { - vx_IrBlock* root = vx_IrBlock_root(parent); - assert(root); - vx_IrBlock_addAllOp(parent, block); return block->outs[0]; } @@ -24,10 +21,14 @@ 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_IrBlock *block) +void vx_opt_cmov(vx_CU* cu, vx_IrBlock *block) { + if (!cu->info.cmov_opt) + return; + vx_IrBlock* root = vx_IrBlock_root(block); - for (vx_IrOp *op = block->first; op; op = op->next) { + for (vx_IrOp *op = block->first; op; op = op->next) + { if (op->id != VX_IR_OP_IF) continue; @@ -53,7 +54,7 @@ void vx_opt_cmov(vx_IrBlock *block) continue; size_t total_cost = vx_IrBlock_inlineCost(then) + vx_IrBlock_inlineCost(els); - if (total_cost > vx_g_optconfig.max_total_cmov_inline_cost) + if (total_cost > cu->opt.max_total_cmov_inline_cost) continue; vx_IrValue condv = *vx_IrOp_param(op, VX_IR_NAME_COND); diff --git a/ir/opt/comparisions.c b/ir/opt/comparisions.c index ecd6e22..0a676be 100644 --- a/ir/opt/comparisions.c +++ b/ir/opt/comparisions.c @@ -1,4 +1,4 @@ -#include "../opt.h" +#include "../passes.h" /** * `a <= constant` -> `a < constant + 1` @@ -8,10 +8,12 @@ * `!cmp(a,b)` -> `ncmp(a,b)` * `constant == a` -> `a == constant` */ -void vx_opt_comparisions(vx_IrBlock *block) +void vx_opt_comparisions(vx_CU* cu, vx_IrBlock *block) { - for (vx_IrOp *op = block->first; op; op = op->next) { - switch (op->id) { + for (vx_IrOp *op = block->first; op; op = op->next) + { + switch (op->id) + { case VX_IR_OP_NOT: { vx_IrValue* oldres = vx_IrOp_param(op, VX_IR_NAME_VALUE); vx_IrOp* cmp; diff --git a/ir/opt/constant_eval.c b/ir/opt/constant_eval.c index cc4f6d7..836f6d3 100644 --- a/ir/opt/constant_eval.c +++ b/ir/opt/constant_eval.c @@ -1,8 +1,7 @@ -#include "../opt.h" - #include +#include "../passes.h" -void vx_opt_constant_eval(vx_IrBlock *block) +void vx_opt_constant_eval(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp *op = block->first; op; op = op->next) { #define BINARY(typedest, what) { \ diff --git a/ir/opt/dce.c b/ir/opt/dce.c index cce5fa2..73c9b88 100644 --- a/ir/opt/dce.c +++ b/ir/opt/dce.c @@ -1,4 +1,4 @@ -#include "../opt.h" +#include "../passes.h" static void rmcode_before_label(vx_IrOp *op) { for (; op; op = op->next) { @@ -20,7 +20,9 @@ static bool labelUsed(vx_IrBlock* block, size_t label) return false; } -void vx_opt_ll_dce(vx_IrBlock *block) { +// TODO: rename to vx_opt_dce +void vx_opt_ll_dce(vx_CU* cu, vx_IrBlock *block) +{ for (vx_IrOp *op = block->first; op; op = op->next) { if (op->id == VX_IR_OP_LABEL) { size_t id = vx_IrOp_param(op, VX_IR_NAME_ID)->id; diff --git a/ir/opt/if_opts.c b/ir/opt/if_opts.c index 9ecc5cc..5f09fb2 100644 --- a/ir/opt/if_opts.c +++ b/ir/opt/if_opts.c @@ -1,4 +1,4 @@ -#include "../opt.h" +#include "../passes.h" // TODO: move to ir/transform.c static vx_IrVar genIntoVar(vx_IrBlock* block, vx_IrValue val) @@ -14,7 +14,7 @@ static vx_IrVar genIntoVar(vx_IrBlock* block, vx_IrValue val) return var; } -void vx_opt_if_opts(vx_IrBlock* block) +void vx_opt_if_opts(vx_CU* cu, vx_IrBlock* block) { // move code after if statements that partially end flow into the branch that doesn't end flow for (vx_IrOp* op = block->first; op; op = op->next) @@ -54,7 +54,7 @@ void vx_opt_if_opts(vx_IrBlock* block) break; // there is no next anymore } - vx_opt_ll_dce(block); // it says ll but also works in ssa + vx_opt_ll_dce(cu, block); // it says ll but also works in ssa for (vx_IrOp* op = block->first; op; op = op->next) { diff --git a/ir/opt/inline_vars.c b/ir/opt/inline_vars.c index 4fce445..fbd817f 100644 --- a/ir/opt/inline_vars.c +++ b/ir/opt/inline_vars.c @@ -1,14 +1,17 @@ -#include "../opt.h" +#include "../passes.h" +// TODO: move substitude to transform -struct vx_IrView_substitute_var__data { +struct vx_IrView_substitute_var__data +{ vx_IrBlock *block; vx_IrVar old; vx_IrValue new; vx_IrOp* newSrc; }; -static bool vx_IrView_substitute_var__trav(vx_IrOp *op, void *dataIn) { +static bool vx_IrView_substitute_var__trav(vx_IrOp *op, void *dataIn) +{ struct vx_IrView_substitute_var__data *data = dataIn; /* @@ -43,7 +46,8 @@ static bool vx_IrView_substitute_var__trav(vx_IrOp *op, void *dataIn) { return false; } -static void vx_IrBlock_substitute_var(vx_IrBlock *block, vx_IrVar old, vx_IrValue new, vx_IrOp* newSrc) { +static void vx_IrBlock_substitute_var(vx_IrBlock *block, vx_IrVar old, vx_IrValue new, vx_IrOp* newSrc) +{ struct vx_IrView_substitute_var__data data = { .block = block, .old = old, .new = new, .newSrc = newSrc }; vx_IrBlock_deepTraverse(block, vx_IrView_substitute_var__trav, &data); } @@ -67,11 +71,12 @@ static bool trav (vx_IrOp *op, void *data) return false; } -void vx_opt_inline_vars(vx_IrBlock *block) { +void vx_opt_inline_vars(vx_CU* cu, vx_IrBlock *block) +{ vx_IrBlock_deepTraverse(block, trav, block); } -void vx_opt_ll_inlineVars(vx_IrBlock *block) +void vx_opt_ll_inlineVars(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp* imm = block->first; imm; imm = imm->next) { diff --git a/ir/opt/join_compute.c b/ir/opt/join_compute.c index 72c6081..9d4b605 100644 --- a/ir/opt/join_compute.c +++ b/ir/opt/join_compute.c @@ -1,7 +1,8 @@ -#include "../opt.h" #include #include +#include "../passes.h" +// TODO: move to analysis static bool eq(vx_IrOp* a, vx_IrOp* b) { if (!( a->id == b->id @@ -25,6 +26,7 @@ static bool eq(vx_IrOp* a, vx_IrOp* b) return true; } +// TODO: move to analysis static vx_IrOp* findMatchingOutBefore(vx_IrBlock* block, vx_IrOp* before, vx_IrOp* cmp, bool stepIn, bool stepOut) { for (vx_IrOp* op = block->first; op && op != before; op = op->next) @@ -56,7 +58,7 @@ static vx_IrOp* findMatchingOutBefore(vx_IrBlock* block, vx_IrOp* before, vx_IrO /** * Find identical computations and join them */ -void vx_opt_join_compute(vx_IrBlock *block) +void vx_opt_join_compute(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp *op = block->first; op; op = op->next) { if (vx_IrOp_isVolatile(op) || vx_IrOp_hasSideEffect(op)) diff --git a/ir/opt/ll_binary.c b/ir/opt/ll_binary.c index 215f7ce..f1a6c12 100644 --- a/ir/opt/ll_binary.c +++ b/ir/opt/ll_binary.c @@ -1,6 +1,6 @@ -#include "../opt.h" +#include "../passes.h" -OPT_PASS void vx_opt_ll_binary(vx_IrBlock *block) { +void vx_opt_ll_binary(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp* op = block->first; op; op = op->next) { switch (op->id) { case VX_IR_OP_EQ: diff --git a/ir/opt/ll_jumps.c b/ir/opt/ll_jumps.c index 64f1af7..4d158b6 100644 --- a/ir/opt/ll_jumps.c +++ b/ir/opt/ll_jumps.c @@ -1,9 +1,9 @@ -#include "../opt.h" - +#include "../passes.h" // 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) { +static void part1(vx_IrBlock *block) +{ vx_IrBlock *root = vx_IrBlock_root(block); for (vx_IrOp *op = block->first; op; op = op->next) { @@ -34,7 +34,8 @@ static void part1(vx_IrBlock *block) { } // is the jump dest just another jump? optimize that -static void part2(vx_IrBlock *block) { +static void part2(vx_IrBlock *block) +{ vx_IrBlock *root = vx_IrBlock_root(block); for (vx_IrOp *op = block->first; op; op = op->next) { @@ -58,7 +59,8 @@ static void part2(vx_IrBlock *block) { } } -void vx_opt_ll_jumps(vx_IrBlock *block) { +void vx_opt_ll_jumps(vx_CU* cu, vx_IrBlock *block) +{ part1(block); part2(block); } diff --git a/ir/opt/ll_sched.c b/ir/opt/ll_sched.c index 72de819..c6c9625 100644 --- a/ir/opt/ll_sched.c +++ b/ir/opt/ll_sched.c @@ -1,4 +1,4 @@ -#include "../opt.h" +#include "../passes.h" struct Move { vx_IrOp* what; @@ -54,7 +54,8 @@ static void runSched(vx_IrBlock* block, struct Move **to_move, size_t *to_move_l } } -void vx_opt_ll_sched(vx_IrBlock *block) { +void vx_opt_ll_sched(vx_CU* cu, vx_IrBlock *block) +{ assert(block->is_root); struct Move* to_move = NULL; diff --git a/ir/opt/loop_simplify.c b/ir/opt/loop_simplify.c index fed8cbc..db2ab8c 100644 --- a/ir/opt/loop_simplify.c +++ b/ir/opt/loop_simplify.c @@ -1,6 +1,6 @@ -#include "../opt.h" +#include "../passes.h" -void vx_opt_loop_simplify(vx_IrBlock *block) +void vx_opt_loop_simplify(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp *op = block->first; op; op = op->next) { if (op->id != VX_IR_OP_FOR) diff --git a/ir/opt/reduce_if.c b/ir/opt/reduce_if.c index 495c6b1..c252bf4 100644 --- a/ir/opt/reduce_if.c +++ b/ir/opt/reduce_if.c @@ -1,6 +1,6 @@ -#include "../opt.h" +#include "../passes.h" -void vx_opt_reduce_if(vx_IrBlock *block) +void vx_opt_reduce_if(vx_CU* cu, vx_IrBlock *block) { vx_IrBlock *root = vx_IrBlock_root(block); diff --git a/ir/opt/reduce_loops.c b/ir/opt/reduce_loops.c index 3b22993..9db6b65 100644 --- a/ir/opt/reduce_loops.c +++ b/ir/opt/reduce_loops.c @@ -1,6 +1,5 @@ #include - -#include "../opt.h" +#include "../passes.h" /** * Detect: @@ -29,7 +28,7 @@ * * But when the condition is always true, we need to make it an infinite loop! */ -void vx_opt_reduce_loops(vx_IrBlock *block) +void vx_opt_reduce_loops(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp *op = block->first; op; op = op->next) { if (op->id != VX_IR_OP_IF) diff --git a/ir/opt/simple_patterns.c b/ir/opt/simple_patterns.c index b3a4ca5..282f783 100644 --- a/ir/opt/simple_patterns.c +++ b/ir/opt/simple_patterns.c @@ -1,6 +1,6 @@ -#include "../opt.h" +#include "../passes.h" -void vx_opt_simple_patterns(vx_IrBlock* block) +void vx_opt_simple_patterns(vx_CU* cu, vx_IrBlock* block) { vx_IrBlock* root = vx_IrBlock_root(block); diff --git a/ir/opt/swap_if_cases.c b/ir/opt/swap_if_cases.c index 2e90e19..081ad1f 100644 --- a/ir/opt/swap_if_cases.c +++ b/ir/opt/swap_if_cases.c @@ -1,6 +1,8 @@ -#include "../opt.h" +#include "../passes.h" -void vx_opt_if_swapCases(vx_IrBlock* block) +// if the else case only has one op, swap both cases + +void vx_opt_if_swapCases(vx_CU* cu, vx_IrBlock* block) { vx_IrBlock_dump(block, stdout, 0); @@ -41,6 +43,7 @@ void vx_opt_if_swapCases(vx_IrBlock* block) vx_IrOp* pred = vx_IrOp_predecessor(op); + // generate not op; optimized away by ther pass vx_IrOp* inv = vx_IrBlock_insertOpCreateAfter(block, pred, VX_IR_OP_NOT); vx_IrVar new = vx_IrBlock_newVar(block, inv); vx_IrOp_addOut(inv, new, vx_IrBlock_typeofVar(block, *cond)); diff --git a/ir/opt/tailcall.c b/ir/opt/tailcall.c index 0f8dc51..429d5e7 100644 --- a/ir/opt/tailcall.c +++ b/ir/opt/tailcall.c @@ -1,8 +1,8 @@ #include +#include "../passes.h" -#include "../opt.h" - -static bool trav(vx_IrOp *op, void *ignore) { +static bool trav(vx_IrOp *op, void *ignore) +{ (void) ignore; if (op->id == VX_IR_OP_CALL && vx_IrOp_isTail(op)) { op->id = VX_IR_OP_TAILCALL; @@ -10,11 +10,13 @@ static bool trav(vx_IrOp *op, void *ignore) { return false; } -void vx_opt_ll_tailcall(vx_IrBlock *block) { +void vx_opt_ll_tailcall(vx_CU* cu, vx_IrBlock *block) +{ vx_IrBlock_deepTraverse(block, trav, NULL); } -void vx_opt_ll_condtailcall(vx_IrBlock *block) { +void vx_opt_ll_condtailcall(vx_CU* cu, vx_IrBlock *block) +{ assert(block->is_root); for (vx_IrOp *op = block->first; op; op = op->next) { diff --git a/ir/opt/vars.c b/ir/opt/vars.c index a688d2b..bf01f7b 100644 --- a/ir/opt/vars.c +++ b/ir/opt/vars.c @@ -1,4 +1,6 @@ -#include "../opt.h" +#include "../passes.h" + +// removes unused ops static bool canForceRem(vx_IrOp* op) { @@ -11,7 +13,9 @@ static bool canForceRem(vx_IrOp* op) return false; } -void vx_opt_vars(vx_IrBlock *block) { +// TODO: rename to vx_opt_unused +void vx_opt_vars(vx_CU* cu, vx_IrBlock *block) +{ vx_IrBlock *root = vx_IrBlock_root(block); assert(root != NULL); assert(root->is_root); diff --git a/ir/passes.c b/ir/passes.c index 78b40bd..fcbf1c6 100644 --- a/ir/passes.c +++ b/ir/passes.c @@ -95,3 +95,82 @@ void vx_llir_prep_lower(vx_CU* cu, vx_IrBlock *block) { vx_opt_ll_binary(cu, block); vx_IrBlock_llir_fix_decl(cu, block); } + +void vx_CIrBlock_fix(vx_CU* cu, vx_IrBlock* block) { + vx_IrBlock* root = vx_IrBlock_root(block); + + for (size_t i = 0; i < block->ins_len; i ++) + vx_IrBlock_putVar(root, block->ins[i].var, NULL); + + for (vx_IrOp* op = block->first; op; op = op->next) { + for (size_t i = 0; i < op->outs_len; i ++) + vx_IrBlock_putVar(root, op->outs[i].var, op); + + FOR_INPUTS(op, inp, { + if (inp.type == VX_IR_VAL_BLOCK) + vx_CIrBlock_fix(cu, inp.block); + }); + } +} + +void vx_IrBlock_llir_compact(vx_CU* cu, vx_IrBlock *root) { + assert(root->is_root); + + for (vx_IrVar idx = 0; idx < root->as_root.vars_len; idx ++) { + if (root->as_root.vars[idx].ll_type == NULL) { + if (idx + 1 >= root->as_root.vars_len) break; + for (vx_IrVar after = idx + 1; after < root->as_root.vars_len; after ++) { + assert(root != NULL && root->is_root); + vx_IrBlock_renameVar(root, after, after - 1, VX_RENAME_VAR_BOTH); + } + } + } +} + +void vx_IrBlock_llir_fix_decl(vx_CU* cu, vx_IrBlock *root) { + assert(root->is_root); + + // TODO: WHY THE FUCK IS THIS EVEN REQUIRED???? + + memset(root->as_root.labels, 0, sizeof(*root->as_root.labels) * root->as_root.labels_len); + memset(root->as_root.vars, 0, sizeof(*root->as_root.vars) * root->as_root.vars_len); + + for (size_t i = 0; i < root->ins_len; i ++) { + vx_IrVar v = root->ins[i].var; + assert(v < root->as_root.vars_len); + root->as_root.vars[v].ll_type = root->ins[i].type; + } + + for (vx_IrOp *op = root->first; op; op = op->next) { + for (size_t j = 0; j < op->outs_len; j ++) { + vx_IrTypedVar out = op->outs[j]; + if (vx_IrType_size(out.type) == 0) { + fprintf(stderr, "size of type %s in 0", out.type->debugName); + exit(1); + } + assert(out.var < root->as_root.vars_len); + vx_IrOp **decl = &root->as_root.vars[out.var].decl; + if (*decl == NULL) { + *decl = op; + root->as_root.vars[out.var].ll_type = out.type; + } + } + + if (op->id == VX_IR_OP_LABEL) { + size_t id = vx_IrOp_param(op, VX_IR_NAME_ID)->id; + assert(id < root->as_root.labels_len); + vx_IrOp **decl = &root->as_root.labels[id].decl; + if (*decl == NULL) { + *decl = op; + } + } + } + + for (vx_IrOp* op = root->first; op; op = op->next) { + if (op->id == VX_IR_OP_PLACE) { + vx_IrValue val = *vx_IrOp_param(op, VX_IR_NAME_VAR); + assert(val.type == VX_IR_VAL_VAR && "inliner fucked up (VX_IR_OP_PLACE)"); + root->as_root.vars[val.var].ever_placed = true; + } + } +} diff --git a/ir/transform/cmov_expand.c b/ir/transform/cmov_expand.c index babc7b6..e23e370 100644 --- a/ir/transform/cmov_expand.c +++ b/ir/transform/cmov_expand.c @@ -1,7 +1,9 @@ -#include "../llir.h" +#include "../passes.h" -void vx_IrBlock_ll_cmov_expand(vx_IrBlock *block) { - for (vx_IrOp* op = block->first; op; op = op->next) { +void vx_IrBlock_ll_cmov_expand(vx_CU* cu, vx_IrBlock *block) +{ + for (vx_IrOp* op = block->first; op; op = op->next) + { if (op->id != VX_IR_OP_CMOV) continue; diff --git a/ir/transform/ll_finalize.c b/ir/transform/ll_finalize.c index 0c91327..f1dfa87 100644 --- a/ir/transform/ll_finalize.c +++ b/ir/transform/ll_finalize.c @@ -1,10 +1,10 @@ -#include "../llir.h" -#include "../opt.h" +#include "../passes.h" -void vx_IrBlock_ll_finalize(vx_IrBlock *block, bool needEpilog) { +void vx_IrBlock_ll_finalize(vx_CU* cu, vx_IrBlock *block, bool needEpilog) +{ if (needEpilog) return; - vx_opt_ll_tailcall(block); - vx_opt_ll_condtailcall(block); + vx_opt_ll_tailcall(cu, block); + vx_opt_ll_condtailcall(cu, block); } diff --git a/ir/transform/lower_loops.c b/ir/transform/lower_loops.c index a9f0e24..ba4089c 100644 --- a/ir/transform/lower_loops.c +++ b/ir/transform/lower_loops.c @@ -1,14 +1,14 @@ -#include "../llir.h" +#include "../passes.h" // while loop to infinite loop with conidtional break -void vx_IrBlock_llir_preLower_loops(vx_IrBlock *block) +void vx_IrBlock_llir_preLower_loops(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp* op = block->first; op; op = op->next) { FOR_INPUTS(op, inp, { if (inp.type == VX_IR_VAL_BLOCK) - vx_IrBlock_llir_preLower_loops(inp.block); + vx_IrBlock_llir_preLower_loops(cu, inp.block); }); if (op->id != VX_IR_OP_WHILE) continue; diff --git a/ir/transform/normalize.c b/ir/transform/normalize.c index 01d581d..ffb599c 100644 --- a/ir/transform/normalize.c +++ b/ir/transform/normalize.c @@ -1,11 +1,12 @@ #include #include -#include "../cir.h" +#include "../passes.h" -void vx_CIrBlock_normalize(vx_IrBlock *block) +void vx_CIrBlock_normalize(vx_CU* cu, vx_IrBlock *block) { - for (vx_IrOp *op = block->first; op; op = op->next) { + for (vx_IrOp *op = block->first; op; op = op->next) + { if (op->id == VX_IR_OP_CFOR) { vx_IrBlock *new = vx_IrBlock_initHeap(block, op); @@ -36,7 +37,7 @@ void vx_CIrBlock_normalize(vx_IrBlock *block) FOR_INPUTS(op, inp, { if (inp.type == VX_IR_VAL_BLOCK) - vx_CIrBlock_normalize(inp.block); + vx_CIrBlock_normalize(cu, inp.block); }); } } diff --git a/ir/transform/share_slots.c b/ir/transform/share_slots.c index 5e67098..8f5cd68 100644 --- a/ir/transform/share_slots.c +++ b/ir/transform/share_slots.c @@ -1,4 +1,6 @@ -#include "../llir.h" +#include "../passes.h" + +// TODO: move to common/ static bool boolArrOverlap(bool* a, bool* b, size_t len) { @@ -80,7 +82,8 @@ static size_t calcPriority(vx_IrBlock* block, vx_IrVar var) // TODO: second strategry that is configurable in config: // when the lifetimes do overlap, but one of them ends during the lt of the other, move other into dead lifetime -void vx_IrBlock_ll_share_slots(vx_IrBlock *block) { +void vx_IrBlock_ll_share_slots(vx_CU* cu, vx_IrBlock *block) +{ size_t blkInstLen = vx_IrBlock_countOps(block); size_t varsLen = block->as_root.vars_len; diff --git a/ir/transform/single_assign.c b/ir/transform/single_assign.c index ac4df34..411a0c3 100644 --- a/ir/transform/single_assign.c +++ b/ir/transform/single_assign.c @@ -1,4 +1,4 @@ -#include "../cir.h" +#include "../passes.h" /** * Go trough every unconditional assignement in the block, @@ -7,12 +7,14 @@ * * inside out! */ -void vx_CIrBlock_mksa_final(vx_IrBlock *block) +void vx_CIrBlock_mksa_final(vx_CU* cu, vx_IrBlock *block) { - for (vx_IrOp *op = block->first; op; op = op->next) { - for (size_t j = 0; j < op->params_len; j ++) - if (op->params[j].val.type == VX_IR_VAL_BLOCK) - vx_CIrBlock_mksa_final(op->params[j].val.block); + for (vx_IrOp *op = block->first; op; op = op->next) + { + FOR_INPUTS(op, inp, ({ + if (inp.type == VX_IR_VAL_BLOCK) + vx_CIrBlock_mksa_final(cu, inp.block); + })); for (size_t j = 0; j < op->outs_len; j ++) { vx_IrVar *var = &op->outs[j].var; diff --git a/ir/transform/single_assign_conditional.c b/ir/transform/single_assign_conditional.c index bdf8295..08c1b24 100644 --- a/ir/transform/single_assign_conditional.c +++ b/ir/transform/single_assign_conditional.c @@ -1,7 +1,5 @@ #include - -#include "../ir.h" -#include "../cir.h" +#include "../passes.h" /** * @param outer assignment of var that is closest to conditional @@ -65,7 +63,7 @@ static vx_IrVar megic(vx_IrBlock *outer, // call megic somehow // detect the patter from the inside out!! -vx_OptIrVar vx_CIrBlock_mksa_states(vx_IrBlock *block) +vx_OptIrVar vx_CIrBlock_mksa_states(vx_CU* cu, vx_IrBlock *block) { vx_IrBlock* root = vx_IrBlock_root(block); assert(root); vx_OptIrVar rvar = VX_IRVAR_OPT_NONE; @@ -75,7 +73,7 @@ vx_OptIrVar vx_CIrBlock_mksa_states(vx_IrBlock *block) // inside out: FOR_PARAMS(op, MKARR(VX_IR_NAME_COND_THEN, VX_IR_NAME_COND_ELSE), param, { vx_IrBlock *conditional = param.block; - vx_OptIrVar manip = vx_CIrBlock_mksa_states(conditional); + vx_OptIrVar manip = vx_CIrBlock_mksa_states(cu, conditional); // are we assigning any variable directly in that block that we also assign on the outside before the inst? for (vx_IrOp *condAssignOp = conditional->first; condAssignOp; condAssignOp = condAssignOp->next) { @@ -94,7 +92,7 @@ vx_OptIrVar vx_CIrBlock_mksa_states(vx_IrBlock *block) FOR_INPUTS(op, inp, { if (inp.type == VX_IR_VAL_BLOCK) - (void) vx_CIrBlock_mksa_states(inp.block); + (void) vx_CIrBlock_mksa_states(cu, inp.block); }); if (op->id == VX_IR_OP_WHILE) { diff --git a/ir/transform/ssair_llir_lower.c b/ir/transform/ssair_llir_lower.c index 532c58b..7a4f901 100644 --- a/ir/transform/ssair_llir_lower.c +++ b/ir/transform/ssair_llir_lower.c @@ -1,14 +1,14 @@ #include -#include "../llir.h" +#include "../passes.h" -void vx_IrBlock_llir_preLower_ifs(vx_IrBlock *block) +void vx_IrBlock_llir_preLower_ifs(vx_CU* cu, vx_IrBlock *block) { for (vx_IrOp* op = block->first; op; op = op->next) { FOR_INPUTS(op, inp, { if (inp.type == VX_IR_VAL_BLOCK) - vx_IrBlock_llir_preLower_ifs(inp.block); + vx_IrBlock_llir_preLower_ifs(cu, inp.block); }); if (op->id != VX_IR_OP_IF) @@ -303,7 +303,7 @@ static void lower_into(vx_IrBlock *old, vx_IrBlock *dest, vx_IrBlock *newParent, } } -void vx_IrBlock_llir_lower(vx_IrBlock *block) { +void vx_IrBlock_llir_lower(vx_CU* cu, vx_IrBlock *block) { puts("pre lower:"); vx_IrBlock_dump(block, stdout, 0); diff --git a/ir/verify_cir.c b/ir/verify_cir.c index d2b928f..5377c97 100644 --- a/ir/verify_cir.c +++ b/ir/verify_cir.c @@ -1,7 +1,7 @@ #include "verify.h" #include "passes.h" -vx_Errors vx_CIrBlock_verify(vx_IrBlock *block) +vx_Errors vx_CIrBlock_verify(vx_CU* cu, vx_IrBlock *block) { vx_Errors errors; errors.items = NULL;