Skip to content

Commit

Permalink
things
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander.nutz committed May 23, 2024
1 parent fdff1c1 commit a9e5f11
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 15 deletions.
30 changes: 19 additions & 11 deletions ir/analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ vx_IrOp *vx_IrBlock_find_var_decl(const vx_IrBlock *block,
return NULL;
}

bool vx_IrOp_var_used(const vx_IrOp *op, vx_IrVar var) {
for (size_t j = 0; j < op->outs_len; j++)
if (op->outs[j].var == var)
return true;
for (size_t j = 0; j < op->params_len; j++) {
if (op->params[j].val.type == VX_IR_VAL_BLOCK) {
if (vx_IrBlock_var_used(op->params[j].val.block, var)) {
return true;
}
} else if (op->params[j].val.type == VX_IR_VAL_VAR) {
if (op->params[j].val.var == var) {
return true;
}
}
}
return false;
}

bool vx_IrBlock_var_used(const vx_IrBlock *block,
const vx_IrVar var)
Expand All @@ -54,17 +71,8 @@ bool vx_IrBlock_var_used(const vx_IrBlock *block,

for (long int i = block->ops_len - 1; i >= 0; i--) {
const vx_IrOp *op = &block->ops[i];
for (size_t j = 0; j < op->params_len; j++) {
if (op->params[j].val.type == VX_IR_VAL_BLOCK) {
if (vx_IrBlock_var_used(op->params[j].val.block, var)) {
return true;
}
} else if (op->params[j].val.type == VX_IR_VAL_VAR) {
if (op->params[j].val.var == var) {
return true;
}
}
}
if (vx_IrOp_var_used(op, var))
return true;
}

return false;
Expand Down
14 changes: 14 additions & 0 deletions ir/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ static vx_IrType* vx_IrType_heap(void) {
return (vx_IrType*) memset(malloc(sizeof(vx_IrType)), 0, sizeof(vx_IrType));
}

static bool vx_IrType_compatible(vx_IrType *a, vx_IrType *b) {
return a == b; // TODO
}

typedef struct {
vx_IrOp *first;
vx_IrOp *last;
} lifetime;

struct vx_IrBlock_s;
typedef struct vx_IrBlock_s vx_IrBlock;

Expand All @@ -82,6 +91,9 @@ struct vx_IrBlock_s {
struct {
struct {
vx_IrOp *decl;

lifetime ll_lifetime;
vx_IrType *ll_type;
} *vars;
size_t vars_len;

Expand Down Expand Up @@ -144,6 +156,7 @@ void vx_IrBlock_remove_out_at(vx_IrBlock *block, size_t id);
size_t vx_IrBlock_insert_label_op(vx_IrBlock *block);

bool vx_IrBlock_var_used(const vx_IrBlock *block, vx_IrVar var);
bool vx_IrOp_var_used(const vx_IrOp *op, vx_IrVar var);

void vx_IrBlock_dump(const vx_IrBlock *block, FILE *out, size_t indent);

Expand Down Expand Up @@ -313,6 +326,7 @@ struct vx_IrOp_s {
vx_IrNamedValue *params;
size_t params_len;

// TODO: TODO TODO MOST FNS IGNORE THAT!!!! BAD!!! (also rename)
vx_IrValue *states;
size_t states_len;

Expand Down
30 changes: 30 additions & 0 deletions ir/lifetimes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <assert.h>
#include "ir.h"
#include "llir.h"

/** only for root blocks */
void vx_IrBlock_lifetimes(vx_IrBlock *block) {
assert(block->is_root);

for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
// llir shouldn't be nested

vx_IrOp *start = (void*) -1;
vx_IrOp *end = 0;
for (size_t i = 0; i < block->ops_len; i ++) {
vx_IrOp *op = &block->ops[i];
if (vx_IrOp_var_used(op, var)) {
if (op > end)
end = op;
else if (op < start)
start = op;
}
}

lifetime lt;
lt.first = start;
lt.last = end;

block->as_root.vars[var].ll_lifetime = lt;
}
}
6 changes: 6 additions & 0 deletions ir/llir.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#include "ir.h"

void vx_IrBlock_llir_lower(vx_IrBlock *block);

/** block needs to be 100% fat */
void vx_IrBlock_lifetimes(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_IrBlock *block);
64 changes: 64 additions & 0 deletions ir/transform/share_slots.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "../llir.h"

// merge lifetimes based on when and their type (are compatible)
// can not merge two lifetimes where one of them was ever place() d because we have to keep the pointer till the end of the fn

// if start of lifetime A == end of lifetime B, we can still merge

// block needs to be 100% flat, decl of vars must be known, decl won't be known after this fn anymore
void vx_IrBlock_ll_share_slots(vx_IrBlock *block) {
for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
vx_IrView view = vx_IrView_of_all(block);
bool get_rid = false;
while (vx_IrView_find(&view, VX_IR_OP_PLACE)) {
const vx_IrOp *op = vx_IrView_take(view);

for (size_t i = 0; i < op->params_len; i ++) {
if (op->params[i].val.id == VX_IR_VAL_VAR && op->params[i].val.var == var) {
get_rid = true;
break;
}
}

if (get_rid)
break;

view = vx_IrView_drop(view, 1);
}

if (get_rid) {
block->as_root.vars[var].ll_lifetime = (lifetime){0};
}
}

for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
lifetime *lt = &block->as_root.vars[var].ll_lifetime;
vx_IrType *type = block->as_root.vars[var].ll_type;

if (lt->first == NULL)
continue;

for (vx_IrVar var2 = 0; var < block->as_root.vars_len; var ++) {
if (var == var2)
continue;

lifetime *lt2 = &block->as_root.vars[var].ll_lifetime;
if (lt2->first == NULL)
continue;

vx_IrType *type2 = block->as_root.vars[var].ll_type;

if (!vx_IrType_compatible(type2, type))
continue;

lifetime cmp_low = *lt;
lifetime cmp_high = *lt2;
if (cmp_low.first > cmp_high.first) {
cmp_low = *lt2;
cmp_high = *lt;
}

// TODO
}
}
}
5 changes: 4 additions & 1 deletion ir/verify_ssa.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ vx_Errors vx_IrBlock_verify(const vx_IrBlock *block, const vx_OpPath path) {
if (block->as_root.vars[i].decl == NULL)
continue;

/*
struct verify_vardecls_deeptraverse__data dat;
dat.var = i;
dat.declcount = 0;
vx_IrView_deep_traverse(vx_IrView_of_all(block), verify_vardecls_deeptraverse, &dat);
// TODO: NEED TO SEARCH FROM ROOT
assert(dat.declcount > 0 /* WE REMOVED VARIABLE DECLARATION WITHOUT REMOVING IT FROM DB!!! */);
assert(dat.declcount > 0); // WE REMOVED VAR DECL WITHOUT REMOVING IT FROM INDEX
if (dat.declcount > 1) {
static char buf[256];
Expand All @@ -56,6 +58,7 @@ vx_Errors vx_IrBlock_verify(const vx_IrBlock *block, const vx_OpPath path) {
};
vx_Errors_add(&errors, &error);
}
*/
}
}

Expand Down
15 changes: 12 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ static vx_IrBlock *always_true_block(vx_IrBlock *parent, vx_IrVar temp_var) {
vx_IrBlock *block = vx_IrBlock_init_heap(parent, parent->ops_len);

vx_IrOp assign;
vx_IrOp_init(&assign, VX_IR_OP_IMM, block);
vx_IrOp_init(&assign, VX_IR_OP_LOAD_VOLATILE, block);
vx_IrOp_add_out(&assign, temp_var, ty_int);
vx_IrOp_add_param_s(&assign, VX_IR_NAME_VALUE, (vx_IrValue) { .type = VX_IR_VAL_IMM_INT, .imm_int = 1 });
vx_IrOp_add_param_s(&assign, VX_IR_NAME_ADDR, (vx_IrValue) { .type = VX_IR_VAL_IMM_INT, .imm_int = 0 });
vx_IrBlock_add_op(block, &assign);

vx_IrBlock_add_out(block, temp_var);
Expand Down Expand Up @@ -98,6 +98,16 @@ static int cir_test(void) {
printf("After C IR lower:\n");
vx_IrBlock_dump(block, stdout, 0);

if (vx_ir_verify(block) != 0)
return 1;

vx_opt_inline_vars(vx_IrView_of_all(block), block);
vx_opt_reduce_if(vx_IrView_of_all(block), block);
// opt(block);

printf("After SSA IR opt:\n");
vx_IrBlock_dump(block, stdout, 0);

if (vx_ir_verify(block) != 0)
return 1;

Expand All @@ -106,7 +116,6 @@ static int cir_test(void) {
printf("After SSA IR lower:\n");
vx_IrBlock_dump(block, stdout, 0);


opt_ll(block);

printf("After LL IR opt:\n");
Expand Down

0 comments on commit a9e5f11

Please sign in to comment.