Skip to content

Commit

Permalink
More accurate def-use list maintenance
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Mar 15, 2024
1 parent a37671d commit 66feedd
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 98 deletions.
22 changes: 16 additions & 6 deletions ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ void ir_init(ir_ctx *ctx, uint32_t flags, ir_ref consts_limit, ir_ref insns_limi
buf = ir_mem_malloc((consts_limit + insns_limit) * sizeof(ir_insn));
ctx->ir_base = buf + consts_limit;

ctx->ir_base[IR_UNUSED].optx = IR_NOP;
MAKE_NOP(&ctx->ir_base[IR_UNUSED]);
ctx->ir_base[IR_NULL].optx = IR_OPT(IR_C_ADDR, IR_ADDR);
ctx->ir_base[IR_NULL].val.u64 = 0;
ctx->ir_base[IR_FALSE].optx = IR_OPT(IR_C_BOOL, IR_BOOL);
Expand Down Expand Up @@ -1296,7 +1296,7 @@ void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref)
}
}

void ir_use_list_replace(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
{
ir_use_list *use_list = &ctx->use_lists[ref];
ir_ref i, n, *p;
Expand All @@ -1310,6 +1310,19 @@ void ir_use_list_replace(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
}
}

void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
{
ir_use_list *use_list = &ctx->use_lists[ref];
ir_ref i, n, *p;

n = use_list->count;
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
if (*p == use) {
*p = new_use;
}
}
}

bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref)
{
ir_use_list *use_list = &ctx->use_lists[to];
Expand Down Expand Up @@ -2679,10 +2692,7 @@ void _ir_STORE(ir_ctx *ctx, ir_ref addr, ir_ref val)
} else {
ctx->control = insn->op1;
}
insn->optx = IR_NOP;
insn->op1 = IR_NOP;
insn->op2 = IR_NOP;
insn->op3 = IR_NOP;
MAKE_NOP(insn);
}
break;
}
Expand Down
72 changes: 18 additions & 54 deletions ir_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,6 @@
#include "ir.h"
#include "ir_private.h"

#define MAKE_NOP(_insn) do { \
ir_insn *__insn = _insn; \
__insn->optx = IR_NOP; \
__insn->op1 = __insn->op2 = __insn->op3 = IR_UNUSED; \
} while (0)

#define CLEAR_USES(_ref) do { \
ir_use_list *__use_list = &ctx->use_lists[_ref]; \
__use_list->count = 0; \
__use_list->refs = 0; \
} while (0)

#define SWAP_REFS(_ref1, _ref2) do { \
ir_ref _tmp = _ref1; \
_ref1 = _ref2; \
_ref2 = _tmp; \
} while (0)

#define SWAP_INSNS(_insn1, _insn2) do { \
ir_insn *_tmp = _insn1; \
_insn1 = _insn2; \
_insn2 = _tmp; \
} while (0)

static void ir_get_true_false_refs(const ir_ctx *ctx, ir_ref if_ref, ir_ref *if_true_ref, ir_ref *if_false_ref)
{
ir_use_list *use_list = &ctx->use_lists[if_ref];
Expand All @@ -54,7 +30,6 @@ static ir_ref _ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin)
{
ir_ref prev, next;
ir_use_list *use_list;
ir_ref n, *p;

IR_ASSERT(ctx->ir_base[begin].op == IR_BEGIN);
IR_ASSERT(ctx->ir_base[end].op == IR_END);
Expand All @@ -68,23 +43,12 @@ static ir_ref _ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin)
next = ctx->use_edges[use_list->refs];

/* remove BEGIN and END */
ctx->ir_base[begin].op = IR_NOP;
ctx->ir_base[begin].op1 = IR_UNUSED;
ctx->use_lists[begin].count = 0;
ctx->ir_base[end].op = IR_NOP;
ctx->ir_base[end].op1 = IR_UNUSED;
ctx->use_lists[end].count = 0;
MAKE_NOP(&ctx->ir_base[begin]); CLEAR_USES(begin);
MAKE_NOP(&ctx->ir_base[end]); CLEAR_USES(end);

/* connect their predecessor and successor */
ctx->ir_base[next].op1 = prev;
use_list = &ctx->use_lists[prev];
n = use_list->count;
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
if (*p == end) {
*p = next;
}
}

ir_use_list_replace_all(ctx, prev, end, next);
return next;
}

Expand Down Expand Up @@ -141,7 +105,7 @@ static ir_ref ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn
IR_ASSERT(ctx->use_lists[start2_ref].count == 1);

next->op1 = root->op1;
ir_use_list_replace(ctx, root->op1, root_ref, next_ref);
ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref);
if (!IR_IS_CONST_REF(root->op2)) {
ir_use_list_remove_all(ctx, root->op2, root_ref);
}
Expand Down Expand Up @@ -189,7 +153,7 @@ static ir_ref ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn
ir_insn *root = &ctx->ir_base[root_ref];

next->op1 = root->op1;
ir_use_list_replace(ctx, root->op1, root_ref, next_ref);
ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref);
ir_use_list_remove_all(ctx, root->op2, root_ref);

MAKE_NOP(root); CLEAR_USES(root_ref);
Expand Down Expand Up @@ -303,7 +267,7 @@ static ir_ref ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_
insn->op3 = IR_UNUSED;

next->op1 = root->op1;
ir_use_list_replace(ctx, root->op1, root_ref, next_ref);
ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref);
ir_use_list_remove_all(ctx, root->op2, root_ref);
if (!IR_IS_CONST_REF(insn->op1)) {
ir_use_list_remove_all(ctx, insn->op1, cond_ref);
Expand Down Expand Up @@ -384,7 +348,7 @@ static ir_ref ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_
insn->op3 = IR_UNUSED;

next->op1 = root->op1;
ir_use_list_replace(ctx, root->op1, root_ref, next_ref);
ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref);
ir_use_list_remove_all(ctx, root->op2, root_ref);
if (!IR_IS_CONST_REF(insn->op1)) {
ir_use_list_remove_all(ctx, insn->op1, cond_ref);
Expand Down Expand Up @@ -440,8 +404,8 @@ static ir_ref ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_
}

next->op1 = root->op1;
ir_use_list_replace(ctx, cond_ref, root_ref, ref);
ir_use_list_replace(ctx, root->op1, root_ref, next_ref);
ir_use_list_replace_one(ctx, cond_ref, root_ref, ref);
ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref);
ir_use_list_remove_all(ctx, root->op2, root_ref);

MAKE_NOP(root); CLEAR_USES(root_ref);
Expand Down Expand Up @@ -619,9 +583,9 @@ static ir_ref ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
ir_use_list_remove_all(ctx, merge_ref, cond_ref);
ir_use_list_remove_all(ctx, ref, if_true_ref);
if (!IR_IS_CONST_REF(cond->op3)) {
ir_use_list_replace(ctx, cond->op3, cond_ref, end2_ref);
ir_use_list_replace_one(ctx, cond->op3, cond_ref, end2_ref);
}
ir_use_list_replace(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_add(ctx, end2_ref, if_true_ref);

end2->optx = IR_OPTX(IR_IF, IR_VOID, 2);
Expand Down Expand Up @@ -722,8 +686,8 @@ static ir_ref ir_try_split_if_cmp(ir_ctx *ctx, ir_worklist *worklist, ir_ref ref
* | |
*/

ir_use_list_replace(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_replace(ctx, end2_ref, merge_ref, if_true_ref);
ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_replace_one(ctx, end2_ref, merge_ref, if_true_ref);

MAKE_NOP(merge); CLEAR_USES(merge_ref);
MAKE_NOP(phi); CLEAR_USES(phi_ref);
Expand Down Expand Up @@ -762,8 +726,8 @@ static ir_ref ir_try_split_if_cmp(ir_ctx *ctx, ir_worklist *worklist, ir_ref ref
* | |
*/

ir_use_list_replace(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_replace(ctx, end2_ref, merge_ref, if_false_ref);
ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_replace_one(ctx, end2_ref, merge_ref, if_false_ref);

MAKE_NOP(merge); CLEAR_USES(merge_ref);
MAKE_NOP(phi); CLEAR_USES(phi_ref);
Expand Down Expand Up @@ -809,10 +773,10 @@ static ir_ref ir_try_split_if_cmp(ir_ctx *ctx, ir_worklist *worklist, ir_ref ref
ir_use_list_remove_all(ctx, merge_ref, phi_ref);
ir_use_list_remove_all(ctx, ref, if_true_ref);
if (!IR_IS_CONST_REF(phi->op3)) {
ir_use_list_replace(ctx, phi->op3, phi_ref, insn->op2);
ir_use_list_replace_one(ctx, phi->op3, phi_ref, insn->op2);
}
ir_use_list_replace(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_replace(ctx, cond_ref, ref, end2_ref);
ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref);
ir_use_list_replace_one(ctx, cond_ref, ref, end2_ref);
ir_use_list_add(ctx, end2_ref, if_true_ref);

end2->optx = IR_OPTX(IR_IF, IR_VOID, 2);
Expand Down
27 changes: 26 additions & 1 deletion ir_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -923,9 +923,34 @@ struct _ir_use_list {

void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref use);
void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref use);
void ir_use_list_replace(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use);
void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use);
void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use);
bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref new_use);

/*** Modification helpers ***/
#define MAKE_NOP(_insn) do { \
ir_insn *__insn = _insn; \
__insn->optx = IR_NOP; \
__insn->op1 = __insn->op2 = __insn->op3 = IR_UNUSED; \
} while (0)

#define CLEAR_USES(_ref) do { \
ir_use_list *__use_list = &ctx->use_lists[_ref]; \
__use_list->count = 0; \
} while (0)

#define SWAP_REFS(_ref1, _ref2) do { \
ir_ref _tmp = _ref1; \
_ref1 = _ref2; \
_ref2 = _tmp; \
} while (0)

#define SWAP_INSNS(_insn1, _insn2) do { \
ir_insn *_tmp = _insn1; \
_insn1 = _insn2; \
_insn2 = _tmp; \
} while (0)

/*** IR Basic Blocks info ***/
#define IR_IS_BB_START(op) \
((ir_op_flags[op] & IR_OP_FLAG_BB_START) != 0)
Expand Down
Loading

0 comments on commit 66feedd

Please sign in to comment.