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
1213extern " C" void *hir_func_cfg (void *);
1314extern " 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+
1541extern " C" {
1642
1743int 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