Skip to content

Commit 005956a

Browse files
authored
Merge pull request #156 from nosba0957/master
Implementation of def-use chain
2 parents c0bbf58 + 6cc9f3f commit 005956a

File tree

2 files changed

+114
-39
lines changed

2 files changed

+114
-39
lines changed

src/defs.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ struct ref_block_list {
157157

158158
typedef struct ref_block_list ref_block_list_t;
159159

160+
typedef struct insn insn_t;
161+
162+
typedef struct use_chain_node {
163+
insn_t *insn;
164+
struct use_chain_node *next;
165+
struct use_chain_node *prev;
166+
} use_chain_t;
167+
160168
struct var {
161169
char type_name[MAX_TYPE_LEN];
162170
char var_name[MAX_VAR_LEN];
@@ -174,6 +182,8 @@ struct var {
174182
int subscripts_idx;
175183
rename_t rename;
176184
ref_block_list_t ref_block_list; /* blocks which kill variable */
185+
use_chain_t *users_head;
186+
use_chain_t *users_tail;
177187
struct insn *last_assign;
178188
int consumed;
179189
bool is_ternary_ret;
@@ -316,8 +326,6 @@ struct insn {
316326
char str[64];
317327
};
318328

319-
typedef struct insn insn_t;
320-
321329
typedef struct {
322330
insn_t *head;
323331
insn_t *tail;

src/ssa.c

+104-37
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,54 @@ void build_rdf()
401401
free(args);
402402
}
403403

404+
void use_chain_add_tail(insn_t *i, var_t *var)
405+
{
406+
use_chain_t *u = calloc(1, sizeof(use_chain_t));
407+
if (!u) {
408+
printf("calloc failed\n");
409+
abort();
410+
}
411+
412+
u->insn = i;
413+
if (!var->users_head)
414+
var->users_head = u;
415+
else
416+
var->users_tail->next = u;
417+
u->prev = var->users_tail;
418+
var->users_tail = u;
419+
}
420+
421+
void use_chain_delete(use_chain_t *u, var_t *var)
422+
{
423+
if (u->prev)
424+
u->prev->next = u->next;
425+
else {
426+
var->users_head = u->next;
427+
u->next->prev = NULL;
428+
}
429+
if (u->next)
430+
u->next->prev = u->prev;
431+
else {
432+
var->users_tail = u->prev;
433+
u->prev->next = NULL;
434+
}
435+
free(u);
436+
}
437+
438+
void use_chain_build()
439+
{
440+
for (fn_t *fn = FUNC_LIST.head; fn; fn = fn->next) {
441+
for (basic_block_t *bb = fn->bbs; bb; bb = bb->rpo_next) {
442+
for (insn_t *i = bb->insn_list.head; i; i = i->next) {
443+
if (i->rs1)
444+
use_chain_add_tail(i, i->rs1);
445+
if (i->rs2)
446+
use_chain_add_tail(i, i->rs2);
447+
}
448+
}
449+
}
450+
}
451+
404452
bool var_check_killed(var_t *var, basic_block_t *bb)
405453
{
406454
for (int i = 0; i < bb->live_kill_idx; i++) {
@@ -1170,63 +1218,80 @@ void ssa_build(int dump_ir)
11701218
}
11711219

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

11801227
insn_t *prev = insn->prev;
1181-
11821228
if (!prev)
11831229
return false;
11841230
if (prev->opcode != OP_add)
11851231
return false;
11861232
if (prev->rd != insn->rs1)
11871233
return false;
11881234

1189-
var_t *def = NULL, *base = prev->rs1, *idx = prev->rs2;
1235+
var_t *def = insn->rd, *base = prev->rs1, *idx = prev->rs2;
11901236
if (base->is_global || idx->is_global)
11911237
return false;
11921238

1193-
insn_t *i = prev;
1194-
for (basic_block_t *b = bb;; b = b->idom) {
1195-
if (!i)
1196-
i = b->insn_list.tail;
1197-
1198-
for (; i; i = i->prev) {
1199-
if (i == prev)
1200-
continue;
1201-
if (i->opcode != OP_add)
1202-
continue;
1203-
if (!i->next)
1204-
continue;
1205-
if (i->next->opcode != OP_read)
1206-
continue;
1207-
if (i->rs1 != base || i->rs2 != idx)
1208-
continue;
1209-
def = i->next->rd;
1210-
}
1211-
if (def)
1212-
break;
1213-
if (b->idom == b)
1214-
break;
1215-
}
1239+
use_chain_t *rs1_delete_user = NULL;
1240+
use_chain_t *rs2_delete_user = NULL;
1241+
for (use_chain_t *user = base->users_head; user; user = user->next) {
1242+
insn_t *i = user->insn;
12161243

1217-
if (!def)
1218-
return false;
1244+
/* Delete the use chain nodes found in the last loop */
1245+
if (rs1_delete_user) {
1246+
use_chain_delete(rs1_delete_user, rs1_delete_user->insn->rs1);
1247+
rs1_delete_user = NULL;
1248+
}
1249+
if (rs2_delete_user) {
1250+
use_chain_delete(rs2_delete_user, rs2_delete_user->insn->rs2);
1251+
rs2_delete_user = NULL;
1252+
}
1253+
if (i == prev)
1254+
continue;
1255+
if (i->opcode != OP_add)
1256+
continue;
1257+
if (!i->next)
1258+
continue;
1259+
if (i->next->opcode != OP_read)
1260+
continue;
1261+
if (i->rs1 != base || i->rs2 != idx)
1262+
continue;
1263+
basic_block_t *i_bb = i->belong_to;
1264+
bool check_dom = 0;
1265+
/* Check if the instructions are under the same dominate tree */
1266+
for (;; i_bb = i_bb->idom) {
1267+
if (i_bb == bb) {
1268+
check_dom = true;
1269+
break;
1270+
}
1271+
if (i_bb == i_bb->idom)
1272+
break;
1273+
}
1274+
if (!check_dom)
1275+
continue;
12191276

1220-
if (prev->prev) {
1221-
insn->prev = prev->prev;
1222-
prev->prev->next = insn;
1223-
} else {
1224-
bb->insn_list.head = insn;
1225-
insn->prev = NULL;
1277+
i->next->opcode = OP_assign;
1278+
i->next->rs1 = def;
1279+
if (i->prev) {
1280+
i->prev->next = i->next;
1281+
i->next->prev = i->prev;
1282+
} else {
1283+
i->belong_to->insn_list.head = i->next;
1284+
i->next->prev = NULL;
1285+
}
1286+
i->next->opcode = OP_assign;
1287+
i->next->rs1 = def;
1288+
/* Prepare information for deleting use chain nodes */
1289+
rs1_delete_user = user;
1290+
for (rs2_delete_user = i->rs2->users_head;
1291+
rs2_delete_user->insn != rs1_delete_user->insn;
1292+
rs2_delete_user = rs2_delete_user->next)
1293+
;
12261294
}
1227-
1228-
insn->opcode = OP_assign;
1229-
insn->rs1 = def;
12301295
return true;
12311296
}
12321297

@@ -1466,6 +1531,8 @@ void optimize()
14661531
build_rdom();
14671532
build_rdf();
14681533

1534+
use_chain_build();
1535+
14691536
for (fn_t *fn = FUNC_LIST.head; fn; fn = fn->next) {
14701537
/* basic block level (control flow) optimizations */
14711538

0 commit comments

Comments
 (0)