Skip to content

Commit

Permalink
cmove almost working again
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander.nutz committed Aug 7, 2024
1 parent 1ffee62 commit cd36201
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 44 deletions.
1 change: 1 addition & 0 deletions .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
shell: bash
- name: Try compile
run: |
git submodule update --init
chmod +x build.sh
./build.sh
shell: bash
9 changes: 9 additions & 0 deletions cg/x86_stupid/cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ static vx_IrOp* emiti(vx_IrOp *prev, vx_IrOp* op, FILE* file) {
case VX_IR_OP_SHR: // "a", "b"
{
Location* o = varData[op->outs[0].var].location;
assert(o);
Location* a = as_loc(o->bytesWidth, *vx_IrOp_param(op, VX_IR_NAME_OPERAND_A));
Location* b = as_loc(o->bytesWidth, *vx_IrOp_param(op, VX_IR_NAME_OPERAND_B));

Expand Down Expand Up @@ -698,6 +699,7 @@ static vx_IrOp* emiti(vx_IrOp *prev, vx_IrOp* op, FILE* file) {
case VX_IR_OP_BITWISE_NOT: // "val"
{
Location* o = varData[op->outs[0].var].location;
assert(o);
Location* v = as_loc(o->bytesWidth, *vx_IrOp_param(op, VX_IR_NAME_VALUE));
emiti_unary(v, o, "not", file);
} break;
Expand All @@ -712,6 +714,7 @@ static vx_IrOp* emiti(vx_IrOp *prev, vx_IrOp* op, FILE* file) {
{
vx_IrVar ov = op->outs[0].var;
Location* o = varData[ov].location;
assert(o);
Location* a = as_loc(o->bytesWidth, *vx_IrOp_param(op, VX_IR_NAME_OPERAND_A));
Location* b = as_loc(o->bytesWidth, *vx_IrOp_param(op, VX_IR_NAME_OPERAND_B));

Expand Down Expand Up @@ -917,6 +920,12 @@ void vx_cg_x86stupid_gen(vx_IrBlock* block, FILE* out) {
varData[val.var].heat ++;
}
}
for (size_t i = 0; i < op->params_len; i ++) {
vx_IrValue val = op->params[i].val;
if (val.type == VX_IR_VAL_VAR) {
varData[val.var].heat ++;
}
}
}

/* ======================== VAR ALLOC ===================== */
Expand Down
53 changes: 33 additions & 20 deletions ir/analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,20 @@ bool vx_IrBlock_vardecl_is_in_ins(vx_IrBlock *block, vx_IrVar var) {
// before
//
vx_IrOp *vx_IrBlock_vardecl_out_before(vx_IrBlock *block, vx_IrVar var, vx_IrOp *before) {
for (vx_IrOp *op = before->parent->first; op; op = op->next) {
if (before == NULL) {
before = vx_IrBlock_tail(block);
}

for (vx_IrOp* op = vx_IrOp_predecessor(before); op; op = vx_IrOp_predecessor(op)) {
for (size_t i = 0; i < op->outs_len; i ++)
if (op->outs[i].var == var)
return op;
}

if (op == before) {
if (before->parent->parent_op)
return vx_IrBlock_vardecl_out_before(block, var, before->parent->parent_op);
if (block->parent == NULL)
return NULL;

return NULL;
}
}
return NULL;
return vx_IrBlock_vardecl_out_before(block->parent, var, block->parent_op);
}

bool vx_IrOp_ends_flow(vx_IrOp *op) {
Expand Down Expand Up @@ -174,9 +175,9 @@ bool vx_IrBlock_is_volatile(vx_IrBlock *block)
return false;
}

vx_IrType *vx_IrBlock_typeof_var(vx_IrBlock *block, vx_IrVar var) {
if (block->as_root.vars[var].ll_type) {
return block->as_root.vars[var].ll_type;
static vx_IrType* typeofvar(vx_IrBlock* block, vx_IrVar var) {
if (!block) {
return NULL;
}

for (size_t i = 0; i < block->ins_len; i ++) {
Expand All @@ -185,19 +186,31 @@ vx_IrType *vx_IrBlock_typeof_var(vx_IrBlock *block, vx_IrVar var) {
}
}

vx_IrOp *decl = vx_IrBlock_root(block)->as_root.vars[var].decl;
if (decl == NULL)
goto warn;

for (size_t i = 0; i < decl->outs_len; i ++)
if (decl->outs[i].var == var)
return decl->outs[i].type;
for (vx_IrOp* op = block->first; op; op = op->next) {
for (size_t i = 0; i < op->outs_len; i ++)
if (op->outs[i].var == var)
return op->outs[i].type;

for (size_t i = 0; i < op->params_len; i ++) {
if (op->params[i].val.type == VX_IR_VAL_BLOCK) {
vx_IrType* ty = typeofvar(op->params[i].val.block, var);
if (ty) return ty;
}
}
}

warn:
fprintf(stderr, "VARIABLE %%%zu DECL ERROR (typeof_var)\n", var);
return NULL;
}

vx_IrType *vx_IrBlock_typeof_var(vx_IrBlock *block, vx_IrVar var) {
vx_IrBlock* root = vx_IrBlock_root(block);
if (root && root->is_root && root->as_root.vars[var].ll_type) {
return block->as_root.vars[var].ll_type;
}

return typeofvar(root, var);
}

static size_t cost_lut[VX_IR_OP____END] = {
[VX_IR_OP_IMM] = 1,
[VX_IR_OP_FLATTEN_PLEASE] = 0,
Expand Down
4 changes: 4 additions & 0 deletions ir/builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ static void root_block_put_var(vx_IrBlock *root, vx_IrVar var, vx_IrOp *decl) {
root->as_root.vars[var].decl = decl;
}

void vx_IrBlock_putVar(vx_IrBlock *root, vx_IrVar var, vx_IrOp *decl) {
root_block_put_var(root, var, decl);
}

static void root_block_put_label(vx_IrBlock *root, size_t label, vx_IrOp *decl) {
assert(root->is_root);
if (label >= root->as_root.labels_len) {
Expand Down
21 changes: 19 additions & 2 deletions ir/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ void vx_IrBlock_llir_compact(vx_IrBlock *root) {
}
}

/*
typedef struct {
vx_IrVar var;
vx_IrOp* decl;
Expand All @@ -45,9 +46,25 @@ bool vx_CIrBlock_fix_iter(vx_IrOp* op, void* param) {
}
}
return false;
}*/

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 (size_t i = 0; i < op->params_len; i ++)
if (op->params[i].val.type == VX_IR_VAL_BLOCK)
vx_CIrBlock_fix(op->params[i].val.block);
}
}

void vx_CIrBlock_fix(vx_IrBlock *root) {
/*void vx_CIrBlock_fix(vx_IrBlock *root) {
assert(root->is_root);
for (vx_IrVar var = 0; var < root->as_root.vars_len; var ++) {
Expand All @@ -59,7 +76,7 @@ void vx_CIrBlock_fix(vx_IrBlock *root) {
root->as_root.vars[var].decl = state.decl;
}
}
}*/

void vx_IrBlock_llir_fix_decl(vx_IrBlock *root) {
assert(root->is_root);
Expand Down
1 change: 1 addition & 0 deletions ir/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ void vx_IrBlock_swap_in_at(vx_IrBlock *block, size_t a, size_t b);
void vx_IrBlock_swap_out_at(vx_IrBlock *block, size_t a, size_t b);
void vx_IrBlock_remove_out_at(vx_IrBlock *block, size_t id);
size_t vx_IrBlock_append_label_op(vx_IrBlock *block);
void vx_IrBlock_putVar(vx_IrBlock *root, vx_IrVar var, vx_IrOp *decl);

static bool vx_IrBlock_empty(vx_IrBlock *block) {
if (!block)
Expand Down
21 changes: 8 additions & 13 deletions ir/opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ static void opt_pre(vx_IrBlock *block) {
}

void opt(vx_IrBlock *block) {
assert(block != NULL);

for (vx_IrOp *op = block->first; op; op = op->next)
for (size_t i = 0; i < op->params_len; i ++)
if (op->params[i].val.type == VX_IR_VAL_BLOCK)
Expand All @@ -37,20 +39,13 @@ void opt(vx_IrBlock *block) {
vx_opt_reduce_if(block);
}
vx_opt_cmov(block);
opt_pre(block);
if (vx_g_optconfig.loop_simplify) {
vx_opt_reduce_loops(block);
vx_opt_loop_simplify(block);
}
//opt_pre(block);
//if (vx_g_optconfig.loop_simplify) {
// vx_opt_reduce_loops(block);
// vx_opt_loop_simplify(block);
//}

vx_opt_tailcall(block);

for (vx_IrOp *op = block->first; op; op = op->next) {
if (op->id == VX_IR_OP_FLATTEN_PLEASE) {
vx_IrBlock *body = vx_IrOp_param(op, VX_IR_NAME_BLOCK)->block;
opt(body);
}
}
//vx_opt_tailcall(block);
}

void opt_ll(vx_IrBlock *block) {
Expand Down
14 changes: 10 additions & 4 deletions ir/opt/cmov.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include "../opt.h"

static vx_IrVar block_res_as_var(vx_IrBlock *parent, vx_IrBlock *block) {
vx_IrBlock* root = vx_IrBlock_root(parent);
vx_IrOp *op = vx_IrBlock_add_op_building(parent);
vx_IrOp_init(op, VX_IR_OP_FLATTEN_PLEASE, parent);
vx_IrVar dest = vx_IrBlock_new_var(parent, op);
vx_IrOp_add_param_s(op, VX_IR_NAME_BLOCK, (vx_IrValue) { .type = VX_IR_VAL_BLOCK, .block = block });
vx_IrOp_add_out(op, dest, vx_IrBlock_typeof_var(block, block->outs[0]));
vx_IrOp_add_out(op, dest, vx_IrBlock_typeof_var(root, block->outs[0]));
return dest;
}

Expand All @@ -27,6 +28,7 @@ static vx_IrVar block_res_as_var(vx_IrBlock *parent, vx_IrBlock *block) {

void vx_opt_cmov(vx_IrBlock *block)
{
vx_IrBlock* root = vx_IrBlock_root(block);
for (vx_IrOp *op = block->first; op; op = op->next) {
if (op->id != VX_IR_OP_IF)
continue;
Expand All @@ -42,20 +44,24 @@ void vx_opt_cmov(vx_IrBlock *block)
if (!pelse)
continue;

assert(pthen->type == VX_IR_VAL_BLOCK);
vx_IrBlock *then = pthen->block;
if (vx_IrBlock_is_volatile(then))
continue;

assert(pelse->type == VX_IR_VAL_BLOCK);
vx_IrBlock *els = pelse->block;
if (vx_IrBlock_is_volatile(els))
continue;

size_t total_cost = vx_IrBlock_inline_cost(then) + vx_IrBlock_inline_cost(els);
printf("cmov inline cost %zu\n", total_cost);
if (total_cost > vx_g_optconfig.max_total_cmov_inline_cost)
continue;

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

vx_IrValue condv = *vx_IrOp_param(op, VX_IR_NAME_COND);
assert(condv.type == VX_IR_VAL_BLOCK);
vx_IrBlock *cond = condv.block;

vx_IrBlock *body = vx_IrBlock_init_heap(block, op);

Expand All @@ -68,7 +74,7 @@ void vx_opt_cmov(vx_IrBlock *block)
vx_IrOp_add_param_s(cmov, VX_IR_NAME_COND, (vx_IrValue) { .type = VX_IR_VAL_BLOCK, .block = cond });
vx_IrOp_add_param_s(cmov, VX_IR_NAME_COND_THEN, (vx_IrValue) { .type = VX_IR_VAL_VAR, .var = v0 });
vx_IrOp_add_param_s(cmov, VX_IR_NAME_COND_ELSE, (vx_IrValue) { .type = VX_IR_VAL_VAR, .var = v1 });
vx_IrOp_add_out(cmov, dest, vx_IrBlock_typeof_var(then, then->outs[0]));
vx_IrOp_add_out(cmov, dest, vx_IrBlock_typeof_var(root, then->outs[0]));

vx_IrBlock_add_out(body, dest);

Expand Down
3 changes: 1 addition & 2 deletions ir/transform/single_assign_conditional.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ static vx_IrVar megic(vx_IrBlock *outer,
{
// stage 1
const vx_IrVar manipulate = vx_IrBlock_new_var(outer, ifOp);
printf("var: %zu\nmanipulate: %zu\n", var, manipulate);
{
vx_IrOp *oldstart = outer->first;
outer->first = orig_assign->next;
Expand Down Expand Up @@ -152,7 +151,7 @@ vx_OptIrVar vx_CIrBlock_mksa_states(vx_IrBlock *block)
for (size_t l = 0; l < condAssignOp->outs_len; l ++) {
vx_IrVar var = condAssignOp->outs[l].var;

vx_IrOp *alwaysAssignOp = vx_IrBlock_vardecl_out_before(block, var, condAssignOp);
vx_IrOp *alwaysAssignOp = vx_IrBlock_vardecl_out_before(block, var, ifOp);
if (alwaysAssignOp == NULL)
continue;
rvar = VX_IRVAR_OPT_SOME(megic(alwaysAssignOp->parent, alwaysAssignOp, conditional, condAssignOp, ifOp, var, manip));
Expand Down
8 changes: 5 additions & 3 deletions test.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static vx_IrBlock * build_test_cmov(void) {
vx_IrBlock_add_op(block, &op);
}

vx_IrBlock_make_root(block, 1);
vx_IrBlock_make_root(block, 2);

return block;
}
Expand Down Expand Up @@ -177,9 +177,9 @@ static int cir_test(vx_IrBlock *block) {
if (vx_cir_verify(block) != 0)
return 1;

vx_CIrBlock_mksa_states(block);
// vx_CIrBlock_mksa_final(block);
vx_CIrBlock_fix(block); // TODO: why...
vx_CIrBlock_mksa_states(block);
vx_CIrBlock_mksa_final(block);

printf("After C IR lower:\n");
vx_IrBlock_dump(block, stdout, 0);
Expand Down Expand Up @@ -227,6 +227,8 @@ static int cir_test(vx_IrBlock *block) {
}

int main(void) {
vx_g_optconfig.if_eval = false;

ty_int = vx_IrType_heap();
ty_int->debugName = "i32";
ty_int->kind = VX_IR_TYPE_KIND_BASE;
Expand Down

0 comments on commit cd36201

Please sign in to comment.