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
123
124
125
126
127
128
129
130
131
132
#[cfg(test)]
mod tests {
use crate::passes::Inlining;
use air_pass::Pass;
//use crate::graph::pretty;
//use crate::ConstantValue;
//use crate::ir2::Mir;
//use crate::MirGraph;
//use crate::MirType;
//use crate::MirValue;
//use crate::Node;
//use crate::NodeIndex;
//use crate::Operation;
//use crate::SpannedMirValue;
#[test]
fn test_inlining() {
// fn f0(x0: Felt) -> Felt {
// let x1 = x0 + x0;
// return x1;
// }
//
// fn f1() -> Felt {
// let x1 = f0(Felt(1);
// return x1;
// }
let mut original = MirGraph::new(vec![
// double definition
// x: Variable(Felt, 0, main)
Node {
// NodeIndex(0)
op: Operation::Value(SpannedMirValue {
span: Default::default(),
value: MirValue::Variable(
MirType::Felt,
0, // arg0
NodeIndex(3), // double.body
),
}),
},
// double.return: Variable(Felt, 1, double)
Node {
// NodeIndex(1)
op: Operation::Value(SpannedMirValue {
span: Default::default(),
value: MirValue::Variable(
MirType::Felt,
1, // return because double only has one argument
// TODO: Define a special type for return values or add it as the last argument
NodeIndex(3), // double.body
),
}),
},
// double.body:
Node {
// NodeIndex(2)
op: Operation::Add(NodeIndex(0), NodeIndex(0)),
},
// double.y:
// y = x + x
// return y
Node {
// NodeIndex(3)
op: Operation::Definition(
vec![NodeIndex(0)], // x
Some(NodeIndex(1)), // return variable
vec![NodeIndex(2)], // y = x + x
),
},
// fn main() -> Felt:
// x = 1
// y = double(x)
// return y
// main.return: Variable(Felt, 0, main)
Node {
// NodeIndex(4)
op: Operation::Value(SpannedMirValue {
span: Default::default(),
value: MirValue::Variable(
MirType::Felt,
0, // arg0
NodeIndex(0), // main.body
),
}),
},
// main.body:
// x = 1
// y = double(x)
// return y
// x = 1
Node {
// NodeIndex(5)
op: Operation::Value(SpannedMirValue {
span: Default::default(),
value: MirValue::Constant(ConstantValue::Felt(1)),
}),
},
// y = double(x)
Node {
// NodeIndex(6)
op: Operation::Call(NodeIndex(3), vec![NodeIndex(5)]),
},
//main.definition
Node {
// NodeIndex(7)
op: Operation::Definition(
vec![],
Some(NodeIndex(4)), // return variable
vec![NodeIndex(5), NodeIndex(6)], // y = double(x)
),
},
]);
let double = NodeIndex(3);
let main = NodeIndex(7);
original.integrity_constraints_roots.insert(main);
original.integrity_constraints_roots.insert(double);
println!("ORIGINAL:\n{}", pretty(&original, &[double, main]));
println!("ORIGINAL raw:\n{:?}", original);
println!("============= Inlining pass =============");
let mut inliner = Inlining::new();
let mut mir_original = Mir::default();
*mir_original.constraint_graph_mut() = original.clone();
let result = inliner.run(mir_original).unwrap();
println!("=========================================");
println!("INLINED raw:\n{:?}", result);
println!("INLINED:\n{}", pretty(&result.constraint_graph(), &[double, main]));
}
}