v4 / vlib / v3 / ssa / optimize / cfg.v
97 lines · 90 sloc · 2.11 KB · 6c4d26f1f98c5464b012a375667ab345e462f7e0
Raw
1module optimize
2
3import v3.ssa
4
5// arr_contains reports whether arr contains applies in optimize.
6fn arr_contains(arr []int, val int) bool {
7 for v in arr {
8 if v == val {
9 return true
10 }
11 }
12 return false
13}
14
15// build_cfg builds cfg data for optimize.
16fn build_cfg(mut m ssa.Module) {
17 n_blocks := m.blocks.len
18 n_values := m.values.len
19
20 for bi in 0 .. n_blocks {
21 mut blk := m.blocks[bi]
22 blk.succs = []
23 blk.preds = []
24 m.blocks[bi] = blk
25 }
26
27 for fi in 0 .. m.funcs.len {
28 for blk_id in m.funcs[fi].blocks {
29 blk := m.blocks[blk_id]
30 if blk.instrs.len == 0 {
31 continue
32 }
33 term_val_id := blk.instrs.last()
34 if term_val_id < 0 || term_val_id >= n_values {
35 continue
36 }
37 term_val := m.values[term_val_id]
38 if term_val.kind != .instruction {
39 continue
40 }
41 term := m.instrs[term_val.index]
42
43 match term.op {
44 .br {
45 if term.operands.len >= 3 {
46 for oi in 1 .. 3 {
47 s := int(term.operands[oi])
48 if s >= 0 && s < n_blocks && !arr_contains(m.blocks[blk_id].succs, s) {
49 mut b := m.blocks[blk_id]
50 b.succs << s
51 m.blocks[blk_id] = b
52 }
53 }
54 }
55 }
56 .jmp {
57 if term.operands.len >= 1 {
58 s := int(term.operands[0])
59 if s >= 0 && s < n_blocks {
60 mut b := m.blocks[blk_id]
61 b.succs << s
62 m.blocks[blk_id] = b
63 }
64 }
65 }
66 .switch_ {
67 // switch_ cond, default_blk, [case_val, blk]...
68 if term.operands.len >= 2 {
69 s := int(term.operands[1])
70 if s >= 0 && s < n_blocks && !arr_contains(m.blocks[blk_id].succs, s) {
71 mut b := m.blocks[blk_id]
72 b.succs << s
73 m.blocks[blk_id] = b
74 }
75 for oi := 3; oi < term.operands.len; oi += 2 {
76 cs := int(term.operands[oi])
77 if cs >= 0 && cs < n_blocks && !arr_contains(m.blocks[blk_id].succs, cs) {
78 mut b := m.blocks[blk_id]
79 b.succs << cs
80 m.blocks[blk_id] = b
81 }
82 }
83 }
84 }
85 else {}
86 }
87
88 for s in m.blocks[blk_id].succs {
89 if s >= 0 && s < n_blocks && !arr_contains(m.blocks[s].preds, blk_id) {
90 mut b := m.blocks[s]
91 b.preds << blk_id
92 m.blocks[s] = b
93 }
94 }
95 }
96 }
97}
98