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
113
114
115
116
117
118
119
120
121
122
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::rc::Rc;
use arret_runtime::intern;
use super::AnalysedFun;
use crate::mir::ops;
fn add_op_global_interned_names(names: &mut BTreeSet<Rc<str>>, op: &ops::Op) {
use ops::OpKind;
match op.kind() {
OpKind::ConstInternedSym(_, name) | OpKind::ConstBoxedSym(_, name) => {
if intern::InternedSym::try_from_inline_name(name).is_none() {
names.insert(name.clone());
}
}
OpKind::Cond(ops::CondOp {
true_ops,
false_ops,
..
}) => {
for op in true_ops.iter().rev().chain(false_ops.iter().rev()) {
add_op_global_interned_names(names, op);
}
}
_ => {}
}
}
fn add_fun_global_interned_names(fun: &ops::Fun, names: &mut BTreeSet<Rc<str>>) {
for op in fun.ops.iter() {
add_op_global_interned_names(names, op);
}
}
pub fn calc_program_global_interned_names(
private_funs: &HashMap<ops::PrivateFunId, AnalysedFun<'_>>,
entry_fun: &ops::Fun,
) -> BTreeMap<Rc<str>, intern::InternedSym> {
let mut names: BTreeSet<Rc<str>> = BTreeSet::new();
for fun in private_funs
.values()
.map(|af| af.ops_fun)
.chain(std::iter::once(entry_fun))
{
add_fun_global_interned_names(fun, &mut names);
}
names
.into_iter()
.enumerate()
.map(|(idx, name)| (name, intern::InternedSym::from_global_index(idx as u32)))
.collect()
}
#[cfg(test)]
mod test {
use super::*;
use arret_runtime::abitype::RetAbiType;
use arret_runtime::boxed;
use crate::source::EMPTY_SPAN;
#[test]
fn simple_global_interned_names() {
let param_reg = ops::RegId::alloc();
let inline_reg = ops::RegId::alloc();
let alpha_reg = ops::RegId::alloc();
let beta_reg = ops::RegId::alloc();
let gamma_reg = ops::RegId::alloc();
let test_fun = ops::Fun {
span: EMPTY_SPAN,
source_name: None,
abi: ops::OpsAbi {
call_conv: ops::CallConv::FastCc,
params: Box::new([boxed::TypeTag::Int.into()]),
ret: RetAbiType::Void,
},
param_regs: Box::new([]),
ops: Box::new([
ops::OpKind::ConstBoxedSym(inline_reg, "inline".into()).into(),
ops::OpKind::Cond(ops::CondOp {
reg_phi: None,
test_reg: param_reg,
true_ops: Box::new([ops::OpKind::ConstBoxedSym(
beta_reg,
"beta NOT INLINE".into(),
)
.into()]),
false_ops: Box::new([ops::OpKind::ConstInternedSym(
gamma_reg,
"gamma NOT INLINE".into(),
)
.into()]),
})
.into(),
ops::OpKind::ConstBoxedSym(alpha_reg, "alpha NOT INLINE".into()).into(),
]),
};
let global_interned_names = calc_program_global_interned_names(&HashMap::new(), &test_fun);
assert_eq!(
[
("alpha NOT INLINE", 0u32),
("beta NOT INLINE", 1u32),
("gamma NOT INLINE", 2u32)
]
.iter()
.map(|(name, idx)| ((*name).into(), intern::InternedSym::from_global_index(*idx)))
.collect::<BTreeMap<Rc<str>, _>>(),
global_interned_names
);
}
}