Skip to content

Commit

Permalink
refactor cond block to cond value in if blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander.nutz committed Feb 4, 2025
1 parent a72d8ac commit 9bf5a24
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 57 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ please do not currently change anything related to:
| 8. | lower fixed-point floats pass. configurable fixed-point floating point emulation | 100€ (~103$) | depends on 2, 9, 10 |
| 9. | lower mul/div pass. lowers {MUL, {U,S}DIV} that are not supported by backend | 100€ (~103$) | |
| 10. | add ops for more float math operations. add pass that lowers unsupported ones to libm calls | **200€** (~207$) | |
| 9. | loop (and if) - invariant code movement pass | 50€ (~ 51$) | |
| 11. | loop (and if statement) invariant code movement pass | 50€ (~ 51$) | |

## current optimizations
- variable inlining
Expand Down
1 change: 1 addition & 0 deletions build.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct CompileData ir_transform_files[] = {
SP(CT_C, "ir/transform/cmov_expand.c"),
SP(CT_C, "ir/transform/ll_finalize.c"),
SP(CT_C, "ir/transform/lower_loops.c"),
SP(CT_C, "ir/transform/ll_if_invert.c"),
};

struct CompileData ir_verify_files[] = {
Expand Down
39 changes: 39 additions & 0 deletions cli/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,49 @@ cmd_vs2vs(int argc, const char **argv)
return 0;
}

int
cmd_vs2asm(int argc, const char **argv)
{
const char *opath = "-";
const char *ipath = "-";
struct argparse_option options[] = {
OPT_HELP(),
OPT_STRING('i', "in", &ipath, "input file path", NULL, 0, 0),
OPT_STRING('o', "out", &opath, "output file path", NULL, 0, 0),
OPT_END(),
};
struct argparse argparse;
argparse_init(&argparse, options, usages, 0);
argc = argparse_parse(&argparse, argc, argv);

FILE* in = openfile(ipath, "r");
struct SNode* nd = snode_parse(in);
if (fgetc(in) != EOF && !feof(in)) {
fclose(in);
exit(1);
}
fclose(in);
if (!nd) {
exit(1);
}

vx_CU* cu = vx_CU_parseS(nd);
assert(cu);

FILE* out = openfile(opath, "w");
int cs = vx_CU_compile(cu, NULL, NULL, out, VX_BIN_ELF, NULL);
fclose(out);

snode_free(nd);

return cs;
}

static struct cmd_struct commands[] = {
{"sfmt", cmd_sfmt},
{"vs2h", cmd_vs2h},
{"vs2vs", cmd_vs2vs},
{"vs2asm",cmd_vs2asm},
};

int
Expand Down
2 changes: 0 additions & 2 deletions ir/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,6 @@ int vx_CU_compile(vx_CU * cu,

vx_llir_prep_lower(cu, block);
vx_IrBlock_llir_varsHeat(block);

vx_IrBlock_dump(block, stdout, 0);
});

if (optionalAsm) {
Expand Down
6 changes: 4 additions & 2 deletions ir/ops.cdef
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# TODO: rewrite cdef in LSTS and make tables extensible (both extensible properties and extensible entries)

table vx_IrOpType (
debug str ;
args str ;
Expand Down Expand Up @@ -666,7 +668,7 @@ enum_entry_prefix "VX_IR_OP_"
sideEffect false
;

entry IF args "cond: ()->bool, then: ()->R, (else: ()->R)"
entry IF args "cond: bool, then: ()->R, (else: ()->R)"
debug "if"
descr "if"
inlineCost 3
Expand All @@ -677,7 +679,7 @@ enum_entry_prefix "VX_IR_OP_"
sideEffect false
;

entry CMOV args "cond: ()->bool, then: value, else: value"
entry CMOV args "cond: bool, then: value, else: value"
debug "cmov"
descr "conditional move"
inlineCost 2
Expand Down
1 change: 1 addition & 0 deletions ir/passes.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void vx_opt_preLower(vx_CU* cu, vx_IrBlock *block)
RecCallInOut(opt_pre, cu, block);
RecCallInOut(vx_opt_join_compute, cu, block);
RecCallInOut(vx_opt_if_swapCases, cu, block);
RecCallInOut(vx_IrBlock_ll_if_invert, cu, block);
RecCallInOut(vx_opt_comparisions, cu, block);
RecCallInOut(opt_pre, cu, block);
}
Expand Down
1 change: 1 addition & 0 deletions ir/passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void vx_IrBlock_lifetimes(vx_CU* cu,vx_IrBlock *block);
// block needs to be 100% flat, decl of vars must be known, decl won't be known after this fn anymore; adds type info to vars
void vx_IrBlock_ll_share_slots(vx_CU* cu,vx_IrBlock *block);
void vx_IrBlock_ll_cmov_expand(vx_CU* cu,vx_IrBlock *block);
void vx_IrBlock_ll_if_invert(vx_CU* cu, vx_IrBlock *block);
// called by the codegen after it knows if it needs epilog
void vx_IrBlock_ll_finalize(vx_CU* cu, vx_IrBlock *block, bool needEpilog);
void vx_llir_prep_lower(vx_CU* cu, vx_IrBlock *block);
Expand Down
44 changes: 44 additions & 0 deletions ir/transform/ll_if_invert.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "../passes.h"

// on the low level, it is better for if statements with only one case to only have an else body, not an if body.

void vx_IrBlock_ll_if_invert(vx_CU* cu, vx_IrBlock *block)
{
for (vx_IrOp* op = block->first; op; op = op->next)
{
if (op->id != VX_IR_OP_IF)
continue;

vx_IrBlock *then = NULL; {
vx_IrValue *val = vx_IrOp_param(op, VX_IR_NAME_COND_THEN);
if (val)
then = val->block;
}

vx_IrBlock *els = NULL; {
vx_IrValue *val = vx_IrOp_param(op, VX_IR_NAME_COND_ELSE);
if (val)
els = val->block;
}

vx_IrValue cond_val = *vx_IrOp_param(op, VX_IR_NAME_COND);
assert(cond_val.type = VX_IR_VAL_BLOCK);

if (then && !els)
{
// then => else and invert condition

vx_IrType* condType = vx_IrValue_type(cu, vx_IrBlock_root(block), cond_val);
assert(condType);
vx_IrOp* inv = vx_IrBlock_insertOpCreateAfter(block, vx_IrOp_predecessor(op), VX_IR_OP_NOT);
vx_IrVar invVar = vx_IrBlock_newVar(block, inv);
vx_IrOp_addOut(inv, invVar, condType);
vx_IrOp_addParam_s(inv, VX_IR_NAME_VALUE, cond_val);

*vx_IrOp_param(op, VX_IR_NAME_COND) = VX_IR_VALUE_VAR(invVar);

vx_IrOp_removeParam(op, VX_IR_NAME_COND_THEN);
vx_IrOp_addParam_s(op, VX_IR_NAME_COND_ELSE, VX_IR_VALUE_BLK(then));
}
}
}
9 changes: 2 additions & 7 deletions ir/transform/single_assign_conditional.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
* @param condOff the index of the assignment in conditional
* @param ifOp the if op that contains the conditional block
* @param var affected variable
* @param manipIn
*/
static vx_IrVar megic(vx_IrBlock *outer,
vx_IrOp *orig_assign,
vx_IrBlock *conditional,
vx_IrOp *cond_op,
vx_IrOp *ifOp,
const vx_IrVar var,
const vx_OptIrVar manipIn)
const vx_IrVar var)
{
vx_IrType *type = NULL;
for (size_t i = 0; i < orig_assign->outs_len; i ++) {
Expand Down Expand Up @@ -59,8 +57,6 @@ static vx_IrVar megic(vx_IrBlock *outer,
return manipulate;
}

// TODO: I don't think we need manip

// call megic somehow
// detect the patter from the inside out!!
vx_OptIrVar vx_CIrBlock_mksa_states(vx_CU* cu, vx_IrBlock *block)
Expand All @@ -73,7 +69,6 @@ vx_OptIrVar vx_CIrBlock_mksa_states(vx_CU* cu, 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(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) {
Expand All @@ -83,7 +78,7 @@ vx_OptIrVar vx_CIrBlock_mksa_states(vx_CU* cu, vx_IrBlock *block)
vx_IrOp *alwaysAssignOp = vx_IrBlock_vardeclOutBefore(block, var, op);
if (alwaysAssignOp == NULL)
continue;
rvar = VX_IRVAR_OPT_SOME(megic(alwaysAssignOp->parent, alwaysAssignOp, conditional, condAssignOp, op, var, manip));
rvar = VX_IRVAR_OPT_SOME(megic(alwaysAssignOp->parent, alwaysAssignOp, conditional, condAssignOp, op, var));
}
}
});
Expand Down
53 changes: 8 additions & 45 deletions ir/transform/ssair_llir_lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,7 @@ void vx_IrBlock_llir_preLower_ifs(vx_CU* cu, vx_IrBlock *block)
continue;

vx_IrValue* cond = vx_IrOp_param(op, VX_IR_NAME_COND);

vx_IrBlock* condbl = cond->block;
*cond = VX_IR_VALUE_VAR(condbl->outs[0]);

if (condbl->first) {
for (vx_IrOp* i = condbl->first; i; i = i->next)
vx_IrOp_updateParent(i, block);

vx_IrOp* pred = vx_IrOp_predecessor(op);
if (pred)
pred->next = condbl->first;
else
block->first = condbl->first;
vx_IrBlock_tail(condbl)->next = op;
}
assert(cond->type != VX_IR_VAL_BLOCK);
}
}

Expand Down Expand Up @@ -129,8 +115,8 @@ static void lower_into(vx_IrBlock *old, vx_IrBlock *dest, vx_IrBlock *newParent,
continue;
}

vx_IrVar cond_var = vx_IrOp_param(op, VX_IR_NAME_COND)->var;
vx_IrType* cond_var_ty = vx_IrBlock_typeofVar(op->parent, cond_var);
vx_IrValue cond_val = *vx_IrOp_param(op, VX_IR_NAME_COND);
assert(cond_val.type = VX_IR_VAL_BLOCK);

// lower_into(cond, dest, newParent, continueLabel, breakLabel, loopOP);

Expand All @@ -144,7 +130,7 @@ static void lower_into(vx_IrBlock *old, vx_IrBlock *dest, vx_IrBlock *newParent,

vx_IrOp *jmp_cond = vx_IrBlock_addOpBuilding(dest);
vx_IrOp_init(jmp_cond, VX_IR_OP_COND, dest);
vx_IrOp_addParam_s(jmp_cond, VX_IR_NAME_COND, VX_IR_VALUE_VAR(cond_var));
vx_IrOp_addParam_s(jmp_cond, VX_IR_NAME_COND, cond_val);

into(els, op, dest, continueLabel, breakLabel, loopOP);

Expand All @@ -162,24 +148,8 @@ static void lower_into(vx_IrBlock *old, vx_IrBlock *dest, vx_IrBlock *newParent,
vx_IrOp_addParam_s(jmp_end, VX_IR_NAME_ID, VX_IR_VALUE_ID(label_end));
} else {
if (then) {
assert(!els);

// we only have a then block

// else <= then and cond_var = !cond_var

// TODO: move invert into higher level transform (because of constant eval and op opt)

vx_IrOp *inv = vx_IrBlock_addOpBuilding(dest);
vx_IrVar new = vx_IrBlock_newVar(dest, inv);
vx_IrBlock_markVarOrigin(dest, cond_var, new);
vx_IrOp_init(inv, VX_IR_OP_NOT, dest);
vx_IrOp_addOut(inv, new, cond_var_ty);
vx_IrOp_addParam_s(inv, VX_IR_NAME_COND, VX_IR_VALUE_VAR(cond_var));
cond_var = new;

els = then;
then = NULL;
fprintf(stderr, "you forgot to run ll_if_invert");
exit(1);
}

assert(!then);
Expand All @@ -189,7 +159,7 @@ static void lower_into(vx_IrBlock *old, vx_IrBlock *dest, vx_IrBlock *newParent,

vx_IrOp *jump = vx_IrBlock_addOpBuilding(dest);
vx_IrOp_init(jump, VX_IR_OP_COND, dest);
vx_IrOp_addParam_s(jump, VX_IR_NAME_COND, VX_IR_VALUE_VAR(cond_var));
vx_IrOp_addParam_s(jump, VX_IR_NAME_COND, cond_val);

into(els, op, dest, continueLabel, breakLabel, loopOP);

Expand All @@ -201,14 +171,7 @@ static void lower_into(vx_IrBlock *old, vx_IrBlock *dest, vx_IrBlock *newParent,
else if (op->id == VX_IR_OP_CMOV) {

vx_IrValue *pcond = vx_IrOp_param(op, VX_IR_NAME_COND);
vx_IrBlock *cond = pcond->block;

vx_IrVar cond_var = cond->outs[0];

lower_into(cond, dest, newParent, continueLabel, breakLabel, loopOP);

pcond->type = VX_IR_VAL_VAR;
pcond->var = cond_var;
assert(pcond->type != VX_IR_VAL_BLOCK);

vx_IrBlock_addOp(dest, op);
}
Expand Down

0 comments on commit 9bf5a24

Please sign in to comment.