Skip to content

Commit

Permalink
new opt pass
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander.nutz committed Sep 18, 2024
1 parent 4f54892 commit 554d2c3
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct CompileData target_lib_files[] = {
SP(CT_C, "ir/opt/ll_binary.c"),
SP(CT_C, "ir/opt/simple_patterns.c"),
SP(CT_C, "ir/opt/ll_sched.c"),
SP(CT_C, "ir/opt/if_opts.c"),

DIR("build/ir/transform"),
SP(CT_C, "ir/transform/single_assign_conditional.c"),
Expand Down
6 changes: 6 additions & 0 deletions ir/analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ bool vx_IrOpType_hasEffect(vx_IrOpType type)

bool vx_IrOp_endsFlow(vx_IrOp *op)
{
if (op->id == VX_IR_OP_IF)
{
vx_IrBlock* pthen = vx_IrOp_param(op, VX_IR_NAME_COND_THEN)->block;
vx_IrBlock* pelse = vx_IrOp_param(op, VX_IR_NAME_COND_ELSE)->block;
return vx_IrBlock_endsFlow(pthen) && vx_IrBlock_endsFlow(pelse);
}
return vx_IrOpType__entries[op->id].endsFlow.a;
}

Expand Down
1 change: 1 addition & 0 deletions ir/opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void opt(vx_IrBlock *block) {
vx_opt_join_compute(block);
if (vx_g_optconfig.if_eval) {
vx_opt_reduce_if(block);
vx_opt_if_opts(block);
}
vx_opt_cmov(block);
opt_pre(block);
Expand Down
1 change: 1 addition & 0 deletions ir/opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ OPT_PASS void vx_opt_cmov(vx_IrBlock *block);
OPT_PASS void vx_opt_vars(vx_IrBlock *block);
OPT_PASS void vx_opt_ll_jumps(vx_IrBlock *block);
OPT_PASS void vx_opt_simple_patterns(vx_IrBlock* block);
OPT_PASS void vx_opt_if_opts(vx_IrBlock* block);

OPT_PASS void vx_opt_ll_dce(vx_IrBlock *block);
OPT_PASS void vx_opt_ll_condtailcall(vx_IrBlock *block);
Expand Down
95 changes: 95 additions & 0 deletions ir/opt/if_opts.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "../opt.h"

// TODO: move to ir/transform.c
static vx_IrVar genIntoVar(vx_IrBlock* block, vx_IrValue val)
{
vx_IrOp* op = vx_IrBlock_addOpBuilding(block);
vx_IrOp_init(op, VX_IR_OP_IMM, block);
vx_IrBlock* root = vx_IrBlock_root(block);
vx_IrVar var = vx_IrBlock_newVar(root, op);
vx_IrTypeRef ty = vx_IrValue_type(root, val);
vx_IrOp_addOut(op, var, ty.ptr);
vx_IrTypeRef_drop(ty);
vx_IrOp_addParam_s(op, VX_IR_NAME_VALUE, val);
return var;
}

void vx_opt_if_opts(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)
{
if (op->id != VX_IR_OP_IF)
continue;

vx_IrBlock* bthen = vx_IrOp_param(op, VX_IR_NAME_COND_THEN)->block; assert(bthen);
vx_IrBlock* belse = vx_IrOp_param(op, VX_IR_NAME_COND_ELSE)->block; assert(belse);

bool thenEnds = vx_IrBlock_endsFlow(bthen);
bool elseEnds = vx_IrBlock_endsFlow(belse);

if (thenEnds == elseEnds)
continue;

vx_IrBlock* notEndingBlk = thenEnds ? belse : bthen;

vx_IrOp* next = op->next;
op->next = NULL;

for (vx_IrOp* o = next; o; o = o->next)
o->parent = notEndingBlk;

{
vx_IrOp* tail = vx_IrBlock_tail(notEndingBlk);
if (tail == NULL) {
notEndingBlk->first = next;
} else {
tail->next = next;
}
}

for (size_t i = 0; i < op->outs_len; i ++)
vx_IrBlock_renameVar(notEndingBlk, op->outs[i].var, notEndingBlk->outs[i]);

break; // there is no next anymore
}

vx_opt_ll_dce(block); // it says ll but also works in ssa

for (vx_IrOp* op = block->first; op; op = op->next)
{
if (op->id != VX_IR_OP_IF)
continue;

vx_IrBlock* bthen = vx_IrOp_param(op, VX_IR_NAME_COND_THEN)->block;
vx_IrBlock* belse = vx_IrOp_param(op, VX_IR_NAME_COND_ELSE)->block;

vx_IrOp* thenLast = vx_IrBlock_tail(bthen);
vx_IrOp* elseLast = vx_IrBlock_tail(belse);

if (!thenLast) continue;
if (!elseLast) continue;
if (thenLast->id != VX_IR_OP_RETURN) continue;
if (elseLast->id != VX_IR_OP_RETURN) continue;

vx_IrOp* retInst = vx_IrBlock_insertOpBuildingAfter(op);
vx_IrOp_init(retInst, VX_IR_OP_RETURN, block);

vx_IrBlock* root = vx_IrBlock_root(block);
size_t numRets = root->outs_len;
for (size_t i = 0; i < numRets; i ++)
{
vx_IrBlock_addOut(bthen, genIntoVar(bthen, thenLast->args[i]));
vx_IrBlock_addOut(belse, genIntoVar(belse, elseLast->args[i]));

vx_IrVar va = vx_IrBlock_newVar(root, op);
vx_IrOp_addOut(op, va, vx_IrBlock_typeofVar(root, root->outs[i]));
vx_IrOp_addArg(retInst, VX_IR_VALUE_VAR(va));
}

vx_IrOp_remove(thenLast);
vx_IrOp_remove(elseLast);

break; // the next op is going to be the return we just inserted
}
}

0 comments on commit 554d2c3

Please sign in to comment.