Skip to content

Commit cc4a18e

Browse files
committed
SSAify invariant 2: every use dominated by its definition
Complete 5/5 self-consistency invariants. Uses phx_dom_create/dominates to verify domination property for all non-phi uses.
1 parent 1bafc0a commit cc4a18e

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

Python/jit/hir/ssaify_verify.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,37 @@
77
#include "cinderx/Jit/hir/ssaify_c.h"
88
#include "cinderx/Jit/hir/hir_basic_block_c.h"
99
#include "cinderx/Jit/hir/hir_instr_c.h"
10+
#include "cinderx/Jit/hir/dominator_c.h"
1011
#include "cinderx/Common/log.h"
1112

1213
extern "C" void *hir_func_cfg(void *);
1314
extern "C" void *hir_reg_instr(void *);
1415

16+
struct DomCtx {
17+
PhxDominatorState *dom;
18+
void *use_instr;
19+
int ok;
20+
};
21+
22+
static int check_use_dominated(void **reg_slot, void *ctx_raw) {
23+
DomCtx *ctx = (DomCtx *)ctx_raw;
24+
void *reg = *reg_slot;
25+
if (!reg) return 1;
26+
void *def_instr = hir_reg_instr(reg);
27+
if (!def_instr) return 1;
28+
HirBasicBlock *def_block = (HirBasicBlock *)hir_c_block(def_instr);
29+
HirBasicBlock *use_block = (HirBasicBlock *)hir_c_block(ctx->use_instr);
30+
if (!def_block || !use_block) return 1;
31+
int def_id = hir_bb_id(def_block);
32+
int use_id = hir_bb_id(use_block);
33+
if (!phx_dom_dominates(ctx->dom, def_id, use_id)) {
34+
JIT_LOG("SSAify verify FAIL: use not dominated by definition");
35+
ctx->ok = 0;
36+
return 0;
37+
}
38+
return 1;
39+
}
40+
1541
extern "C" {
1642

1743
int hir_ssaify_verify(void *func_handle) {
@@ -25,6 +51,9 @@ int hir_ssaify_verify(void *func_handle) {
2551
return 0;
2652
}
2753

54+
/* Build dominator tree for invariant 2 */
55+
PhxDominatorState *dom = phx_dom_create(func_handle);
56+
2857
for (HirBasicBlock *bb = hir_cfg_first_block(cfg); bb;
2958
bb = hir_cfg_next_block(cfg, bb)) {
3059
size_t num_preds = hir_bb_in_edges_count(bb);
@@ -37,6 +66,20 @@ int hir_ssaify_verify(void *func_handle) {
3766
void *def_instr = hir_reg_instr(output);
3867
if (def_instr != instr) {
3968
JIT_LOG("SSAify verify FAIL: register has wrong defining instr");
69+
phx_dom_destroy(dom);
70+
return 0;
71+
}
72+
}
73+
74+
/* Invariant 2: Every use dominated by its definition */
75+
if (!hir_c_is_phi(instr)) {
76+
DomCtx ctx;
77+
ctx.dom = dom;
78+
ctx.use_instr = instr;
79+
ctx.ok = 1;
80+
hir_c_visit_uses(instr, check_use_dominated, &ctx);
81+
if (!ctx.ok) {
82+
phx_dom_destroy(dom);
4083
return 0;
4184
}
4285
}
@@ -49,6 +92,7 @@ int hir_ssaify_verify(void *func_handle) {
4992
JIT_LOG(
5093
"SSAify verify FAIL: phi has {} operands but block has {} preds",
5194
num_ops, num_preds);
95+
phx_dom_destroy(dom);
5296
return 0;
5397
}
5498

@@ -61,6 +105,7 @@ int hir_ssaify_verify(void *func_handle) {
61105
HirBasicBlock *pred_j = (HirBasicBlock *)edge_j->from;
62106
if (pred_i == pred_j) {
63107
JIT_LOG("SSAify verify FAIL: duplicate predecessor in phi");
108+
phx_dom_destroy(dom);
64109
return 0;
65110
}
66111
}
@@ -69,6 +114,7 @@ int hir_ssaify_verify(void *func_handle) {
69114
}
70115
}
71116

117+
phx_dom_destroy(dom);
72118
return 1;
73119
}
74120

0 commit comments

Comments
 (0)