1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::inst::*;
use std;
use crate::ty::*;
use crate::unit::*;
use crate::value::*;
pub struct Block {
id: BlockRef,
name: Option<String>,
insts: Vec<InstRef>,
}
impl Block {
pub fn new(name: Option<String>) -> Block {
Block {
id: BlockRef::new(ValueId::alloc()),
name: name,
insts: Vec::new(),
}
}
pub fn as_ref(&self) -> BlockRef {
self.id
}
pub fn insts<'a>(&'a self, ctx: &'a UnitContext) -> InstIter<'a> {
InstIter::new(self.insts.iter(), ctx)
}
pub fn inst_refs(&self) -> std::slice::Iter<InstRef> {
self.insts.iter()
}
pub fn insert_inst(&mut self, inst: InstRef, pos: InstPosition) {
let index = match pos {
InstPosition::Begin => 0,
InstPosition::End => self.insts.len(),
InstPosition::Before(i) => self.inst_pos(i),
InstPosition::After(i) => self.inst_pos(i) + 1,
InstPosition::BlockBegin(b) => {
assert_eq!(self.id, b);
0
}
InstPosition::BlockEnd(b) => {
assert_eq!(self.id, b);
self.insts.len()
}
};
self.insts.insert(index, inst)
}
pub fn detach_inst(&mut self, inst: InstRef) {
let pos = self.inst_pos(inst);
self.insts.remove(pos);
}
fn inst_pos(&self, inst: InstRef) -> usize {
self.insts
.iter()
.position(|&i| i == inst)
.expect("basic block does not contain inst")
}
}
impl Value for Block {
fn id(&self) -> ValueId {
self.id.into()
}
fn ty(&self) -> Type {
void_ty()
}
fn name(&self) -> Option<&str> {
self.name.as_ref().map(|x| x as &str)
}
fn is_global(&self) -> bool {
false
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum BlockPosition {
Begin,
End,
Before(BlockRef),
After(BlockRef),
}