96 lines
2.0 KiB
V
96 lines
2.0 KiB
V
module optimize
|
|
|
|
import v3.ssa
|
|
|
|
fn arr_contains(arr []int, val int) bool {
|
|
for v in arr {
|
|
if v == val {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
fn build_cfg(mut m ssa.Module) {
|
|
n_blocks := m.blocks.len
|
|
n_values := m.values.len
|
|
|
|
for bi in 0 .. n_blocks {
|
|
mut blk := m.blocks[bi]
|
|
blk.succs = []
|
|
blk.preds = []
|
|
m.blocks[bi] = blk
|
|
}
|
|
|
|
for fi in 0 .. m.funcs.len {
|
|
for blk_id in m.funcs[fi].blocks {
|
|
blk := m.blocks[blk_id]
|
|
if blk.instrs.len == 0 {
|
|
continue
|
|
}
|
|
term_val_id := blk.instrs.last()
|
|
if term_val_id < 0 || term_val_id >= n_values {
|
|
continue
|
|
}
|
|
term_val := m.values[term_val_id]
|
|
if term_val.kind != .instruction {
|
|
continue
|
|
}
|
|
term := m.instrs[term_val.index]
|
|
|
|
match term.op {
|
|
.br {
|
|
if term.operands.len >= 3 {
|
|
for oi in 1 .. 3 {
|
|
s := int(term.operands[oi])
|
|
if s >= 0 && s < n_blocks && !arr_contains(m.blocks[blk_id].succs, s) {
|
|
mut b := m.blocks[blk_id]
|
|
b.succs << s
|
|
m.blocks[blk_id] = b
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.jmp {
|
|
if term.operands.len >= 1 {
|
|
s := int(term.operands[0])
|
|
if s >= 0 && s < n_blocks {
|
|
mut b := m.blocks[blk_id]
|
|
b.succs << s
|
|
m.blocks[blk_id] = b
|
|
}
|
|
}
|
|
}
|
|
.switch_ {
|
|
// switch_ cond, default_blk, [case_val, blk]...
|
|
if term.operands.len >= 2 {
|
|
s := int(term.operands[1])
|
|
if s >= 0 && s < n_blocks && !arr_contains(m.blocks[blk_id].succs, s) {
|
|
mut b := m.blocks[blk_id]
|
|
b.succs << s
|
|
m.blocks[blk_id] = b
|
|
}
|
|
for oi := 3; oi < term.operands.len; oi += 2 {
|
|
cs := int(term.operands[oi])
|
|
if cs >= 0 && cs < n_blocks && !arr_contains(m.blocks[blk_id].succs, cs) {
|
|
mut b := m.blocks[blk_id]
|
|
b.succs << cs
|
|
m.blocks[blk_id] = b
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {}
|
|
}
|
|
|
|
for s in m.blocks[blk_id].succs {
|
|
if s >= 0 && s < n_blocks && !arr_contains(m.blocks[s].preds, blk_id) {
|
|
mut b := m.blocks[s]
|
|
b.preds << blk_id
|
|
m.blocks[s] = b
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|