Skip to content

Commit

Permalink
Merge pull request #156 from nosba0957/master
Browse files Browse the repository at this point in the history
Implementation of  def-use chain
  • Loading branch information
jserv authored Nov 7, 2024
2 parents c0bbf58 + 6cc9f3f commit 005956a
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 39 deletions.
12 changes: 10 additions & 2 deletions src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ struct ref_block_list {

typedef struct ref_block_list ref_block_list_t;

typedef struct insn insn_t;

typedef struct use_chain_node {
insn_t *insn;
struct use_chain_node *next;
struct use_chain_node *prev;
} use_chain_t;

struct var {
char type_name[MAX_TYPE_LEN];
char var_name[MAX_VAR_LEN];
Expand All @@ -174,6 +182,8 @@ struct var {
int subscripts_idx;
rename_t rename;
ref_block_list_t ref_block_list; /* blocks which kill variable */
use_chain_t *users_head;
use_chain_t *users_tail;
struct insn *last_assign;
int consumed;
bool is_ternary_ret;
Expand Down Expand Up @@ -316,8 +326,6 @@ struct insn {
char str[64];
};

typedef struct insn insn_t;

typedef struct {
insn_t *head;
insn_t *tail;
Expand Down
141 changes: 104 additions & 37 deletions src/ssa.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,54 @@ void build_rdf()
free(args);
}

void use_chain_add_tail(insn_t *i, var_t *var)
{
use_chain_t *u = calloc(1, sizeof(use_chain_t));
if (!u) {
printf("calloc failed\n");
abort();
}

u->insn = i;
if (!var->users_head)
var->users_head = u;
else
var->users_tail->next = u;
u->prev = var->users_tail;
var->users_tail = u;
}

void use_chain_delete(use_chain_t *u, var_t *var)
{
if (u->prev)
u->prev->next = u->next;
else {
var->users_head = u->next;
u->next->prev = NULL;
}
if (u->next)
u->next->prev = u->prev;
else {
var->users_tail = u->prev;
u->prev->next = NULL;
}
free(u);
}

void use_chain_build()
{
for (fn_t *fn = FUNC_LIST.head; fn; fn = fn->next) {
for (basic_block_t *bb = fn->bbs; bb; bb = bb->rpo_next) {
for (insn_t *i = bb->insn_list.head; i; i = i->next) {
if (i->rs1)
use_chain_add_tail(i, i->rs1);
if (i->rs2)
use_chain_add_tail(i, i->rs2);
}
}
}
}

bool var_check_killed(var_t *var, basic_block_t *bb)
{
for (int i = 0; i < bb->live_kill_idx; i++) {
Expand Down Expand Up @@ -1170,63 +1218,80 @@ void ssa_build(int dump_ir)
}

/* Common Subexpression Elimination (CSE) */
/* TODO: simplify with def-use chain */
/* TODO: release detached insns node */
bool cse(insn_t *insn, basic_block_t *bb)
{
if (insn->opcode != OP_read)
return false;

insn_t *prev = insn->prev;

if (!prev)
return false;
if (prev->opcode != OP_add)
return false;
if (prev->rd != insn->rs1)
return false;

var_t *def = NULL, *base = prev->rs1, *idx = prev->rs2;
var_t *def = insn->rd, *base = prev->rs1, *idx = prev->rs2;
if (base->is_global || idx->is_global)
return false;

insn_t *i = prev;
for (basic_block_t *b = bb;; b = b->idom) {
if (!i)
i = b->insn_list.tail;

for (; i; i = i->prev) {
if (i == prev)
continue;
if (i->opcode != OP_add)
continue;
if (!i->next)
continue;
if (i->next->opcode != OP_read)
continue;
if (i->rs1 != base || i->rs2 != idx)
continue;
def = i->next->rd;
}
if (def)
break;
if (b->idom == b)
break;
}
use_chain_t *rs1_delete_user = NULL;
use_chain_t *rs2_delete_user = NULL;
for (use_chain_t *user = base->users_head; user; user = user->next) {
insn_t *i = user->insn;

if (!def)
return false;
/* Delete the use chain nodes found in the last loop */
if (rs1_delete_user) {
use_chain_delete(rs1_delete_user, rs1_delete_user->insn->rs1);
rs1_delete_user = NULL;
}
if (rs2_delete_user) {
use_chain_delete(rs2_delete_user, rs2_delete_user->insn->rs2);
rs2_delete_user = NULL;
}
if (i == prev)
continue;
if (i->opcode != OP_add)
continue;
if (!i->next)
continue;
if (i->next->opcode != OP_read)
continue;
if (i->rs1 != base || i->rs2 != idx)
continue;
basic_block_t *i_bb = i->belong_to;
bool check_dom = 0;
/* Check if the instructions are under the same dominate tree */
for (;; i_bb = i_bb->idom) {
if (i_bb == bb) {
check_dom = true;
break;
}
if (i_bb == i_bb->idom)
break;
}
if (!check_dom)
continue;

if (prev->prev) {
insn->prev = prev->prev;
prev->prev->next = insn;
} else {
bb->insn_list.head = insn;
insn->prev = NULL;
i->next->opcode = OP_assign;
i->next->rs1 = def;
if (i->prev) {
i->prev->next = i->next;
i->next->prev = i->prev;
} else {
i->belong_to->insn_list.head = i->next;
i->next->prev = NULL;
}
i->next->opcode = OP_assign;
i->next->rs1 = def;
/* Prepare information for deleting use chain nodes */
rs1_delete_user = user;
for (rs2_delete_user = i->rs2->users_head;
rs2_delete_user->insn != rs1_delete_user->insn;
rs2_delete_user = rs2_delete_user->next)
;
}

insn->opcode = OP_assign;
insn->rs1 = def;
return true;
}

Expand Down Expand Up @@ -1466,6 +1531,8 @@ void optimize()
build_rdom();
build_rdf();

use_chain_build();

for (fn_t *fn = FUNC_LIST.head; fn; fn = fn->next) {
/* basic block level (control flow) optimizations */

Expand Down

0 comments on commit 005956a

Please sign in to comment.