WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

test_ir.rs 11.2 KB
Newer Older
1
2
3
4
extern crate mu;

use self::mu::ast::types::*;
use self::mu::ast::ir::*;
5
use self::mu::ast::inst::*;
6
use self::mu::ast::ptr::*;
qinsoon's avatar
qinsoon committed
7
use self::mu::ast::op::*;
8
9
use self::mu::vm::context::*;

10
use std::cell::RefCell;
11
use std::collections::HashMap;
12

13
14
15
16
17
18
#[test]
#[allow(unused_variables)]
fn test_factorial() {
    let vm = factorial();
}

qinsoon's avatar
qinsoon committed
19
20
21
22
23
24
25
#[test]
#[allow(unused_variables)]
fn test_sum() {
    let vm = sum();
}

pub fn sum() -> VMContext {
26
    let vm = VMContext::new();
27

qinsoon's avatar
qinsoon committed
28
29
30
    // .typedef @int_64 = int<64>
    let type_def_int64 = vm.declare_type("int_64", P(MuType::int(64)));
    let type_def_int1  = vm.declare_type("int_1", P(MuType::int(1)));
31

qinsoon's avatar
qinsoon committed
32
33
34
35
    // .const @int_64_0 <@int_64> = 0
    // .const @int_64_1 <@int_64> = 1
    let const_def_int64_0 = vm.declare_const("int64_0", type_def_int64.clone(), Constant::Int(0));
    let const_def_int64_1 = vm.declare_const("int64_1", type_def_int64.clone(), Constant::Int(1));
36

qinsoon's avatar
qinsoon committed
37
38
    // .funcsig @sum_sig = (@int_64) -> (@int_64)
    let sum_sig = vm.declare_func_sig("sum_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]);
39

40
41
42
43
44
45
    // .funcdecl @sum <@sum_sig>
    let func = MuFunction::new("sum", sum_sig.clone());
    vm.declare_func(func);

    // .funcdef @sum VERSION @sum_v1 <@sum_sig> 
    let mut func_ver = MuFunctionVersion::new("sum", "sum_v1", sum_sig.clone());
46

qinsoon's avatar
qinsoon committed
47
48
    // %entry(<@int_64> %n):
    let mut blk_entry = Block::new("entry");
49
50
51
    let blk_entry_n = func_ver.new_ssa("blk_entry_n", type_def_int64.clone());
    let const_def_int64_0_local = func_ver.new_constant(const_def_int64_0.clone()); // FIXME: why we need a local version?
    let const_def_int64_1_local = func_ver.new_constant(const_def_int64_1.clone());
52

qinsoon's avatar
qinsoon committed
53
    // BRANCH %head
54
    let blk_entry_term = func_ver.new_inst(Instruction {
qinsoon's avatar
qinsoon committed
55
56
57
58
59
60
61
        value: None,
        ops: RefCell::new(vec![blk_entry_n.clone(), const_def_int64_0_local.clone(), const_def_int64_0_local.clone()]),
        v: Instruction_::Branch1(Destination{
            target: "head",
            args: vec![DestArg::Normal(0), DestArg::Normal(1), DestArg::Normal(2)]
        })
    });
62

qinsoon's avatar
qinsoon committed
63
    let blk_entry_content = BlockContent {
64
        args: vec![blk_entry_n.clone_value()],
qinsoon's avatar
qinsoon committed
65
66
67
68
        body: vec![blk_entry_term],
        keepalives: None
    };
    blk_entry.content = Some(blk_entry_content);
69

qinsoon's avatar
qinsoon committed
70
71
    // %head(<@int_64> %n, <@int_64> %s, <@int_64> %i):
    let mut blk_head = Block::new("head");
72
73
74
    let blk_head_n = func_ver.new_ssa("blk_head_n", type_def_int64.clone());
    let blk_head_s = func_ver.new_ssa("blk_head_s", type_def_int64.clone());
    let blk_head_i = func_ver.new_ssa("blk_head_i", type_def_int64.clone());
75

qinsoon's avatar
qinsoon committed
76
    // %s2 = ADD %s %i
77
78
    let blk_head_s2 = func_ver.new_ssa("blk_head_s2", type_def_int64.clone());
    let blk_head_inst0 = func_ver.new_inst(Instruction {
qinsoon's avatar
qinsoon committed
79
        value: Some(vec![blk_head_s2.clone_value()]),
qinsoon's avatar
qinsoon committed
80
81
82
        ops: RefCell::new(vec![blk_head_s.clone(), blk_head_i.clone()]),
        v: Instruction_::BinOp(BinOp::Add, 0, 1)
    });
83

qinsoon's avatar
qinsoon committed
84
    // %i2 = ADD %i 1
85
86
    let blk_head_i2 = func_ver.new_ssa("blk_head_i2", type_def_int64.clone());
    let blk_head_inst1 = func_ver.new_inst(Instruction {
qinsoon's avatar
qinsoon committed
87
        value: Some(vec![blk_head_i2.clone_value()]),
qinsoon's avatar
qinsoon committed
88
89
90
        ops: RefCell::new(vec![blk_head_i.clone(), const_def_int64_1_local.clone()]),
        v: Instruction_::BinOp(BinOp::Add, 0, 1)
    });
91

qinsoon's avatar
qinsoon committed
92
    // %cond = UGT %i %n
93
94
    let blk_head_cond = func_ver.new_ssa("blk_head_cond", type_def_int1.clone());
    let blk_head_inst2 = func_ver.new_inst(Instruction {
qinsoon's avatar
qinsoon committed
95
        value: Some(vec![blk_head_cond.clone_value()]),
qinsoon's avatar
qinsoon committed
96
97
98
99
100
        ops: RefCell::new(vec![blk_head_i.clone(), blk_head_n.clone()]),
        v: Instruction_::CmpOp(CmpOp::UGT, 0, 1)
    });

    // BRANCH2 %cond %ret(%s2) %head(%n %s2 %i2)
101
    let blk_head_term = func_ver.new_inst(Instruction{
qinsoon's avatar
qinsoon committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
        value: None,
        ops: RefCell::new(vec![blk_head_cond.clone(), blk_head_n.clone(), blk_head_s2.clone(), blk_head_i2.clone()]),
        v: Instruction_::Branch2 {
            cond: 0,
            true_dest: Destination {
                target: "ret",
                args: vec![DestArg::Normal(2)]
            },
            false_dest: Destination {
                target: "head",
                args: vec![DestArg::Normal(1), DestArg::Normal(2), DestArg::Normal(3)]
            },
            true_prob: 0.6f32
        }
    });

    let blk_head_content = BlockContent {
119
        args: vec![blk_head_n.clone_value(), blk_head_s.clone_value(), blk_head_i.clone_value()],
qinsoon's avatar
qinsoon committed
120
121
122
123
        body: vec![blk_head_inst0, blk_head_inst1, blk_head_inst2, blk_head_term],
        keepalives: None
    };
    blk_head.content = Some(blk_head_content);
124

qinsoon's avatar
qinsoon committed
125
126
    // %ret(<@int_64> %s):
    let mut blk_ret = Block::new("ret");
127
    let blk_ret_s = func_ver.new_ssa("blk_ret_s", type_def_int64.clone());
128

qinsoon's avatar
qinsoon committed
129
    // RET %s
130
    let blk_ret_term = func_ver.new_inst(Instruction{
qinsoon's avatar
qinsoon committed
131
132
133
134
        value: None,
        ops: RefCell::new(vec![blk_ret_s.clone()]),
        v: Instruction_::Return(vec![0])
    });
135

qinsoon's avatar
qinsoon committed
136
    let blk_ret_content = BlockContent {
137
        args: vec![blk_ret_s.clone_value()],
qinsoon's avatar
qinsoon committed
138
139
140
141
142
143
        body: vec![blk_ret_term],
        keepalives: None
    };
    blk_ret.content = Some(blk_ret_content);

    // wrap into a function
144
    func_ver.define(FunctionContent{
145
            entry: "entry",
qinsoon's avatar
qinsoon committed
146
147
148
149
150
151
152
153
            blocks: {
                let mut blocks = HashMap::new();
                blocks.insert("entry", blk_entry);
                blocks.insert("head", blk_head);
                blocks.insert("ret", blk_ret);
                blocks
            }
    });
154

155
    vm.define_func_version(func_ver);
156

qinsoon's avatar
qinsoon committed
157
158
159
    vm
}

160
161
#[allow(unused_variables)]
pub fn factorial() -> VMContext {
162
    let vm = VMContext::new();
163

164
165
166
167
168
169
170
    // .typedef @int_64 = int<64>
    // .typedef @int_1 = int<1>
    // .typedef @float = float
    // .typedef @double = double
    // .typedef @void = void
    // .typedef @int_8 = int<8>
    // .typedef @int_32 = int<32>
qinsoon's avatar
qinsoon committed
171
172
173
174
175
176
177
    let type_def_int64 = vm.declare_type("int_64", P(MuType::int(64)));
    let type_def_int1  = vm.declare_type("int_1", P(MuType::int(1)));
    let type_def_float = vm.declare_type("float", P(MuType::float()));
    let type_def_double = vm.declare_type("double", P(MuType::double()));
    let type_def_void  = vm.declare_type("void", P(MuType::void()));
    let type_def_int8  = vm.declare_type("int8", P(MuType::int(8)));
    let type_def_int32 = vm.declare_type("int32", P(MuType::int(32)));
178

179
    // .const @int_64_1 <@int_64> = 1
180
    let const_def_int64_1 = vm.declare_const("int64_1", type_def_int64.clone(), Constant::Int(1));
181

182
183
    // .funcsig @fac_sig = (@int_64) -> (@int_64)
    let fac_sig = vm.declare_func_sig("fac_sig", vec![type_def_int64.clone()], vec![type_def_int64.clone()]);
184
    let type_def_funcref_fac = vm.declare_type("fac_sig", P(MuType::funcref(fac_sig.clone())));
185

186
187
188
189
    // .funcdecl @fac <@fac_sig>
    let func = MuFunction::new("fac", fac_sig.clone());
    vm.declare_func(func);

190
    // .funcdef @fac VERSION @fac_v1 <@fac_sig>
191
    let const_func_fac = vm.declare_const("fac", type_def_funcref_fac, Constant::FuncRef("fac"));
192
    let mut func_ver = MuFunctionVersion::new("fac", "fac_v1", fac_sig.clone());
193

194
195
    // %blk_0(<@int_64> %n_3):
    let mut blk_0 = Block::new("blk_0");
196
197
    let blk_0_n_3 = func_ver.new_ssa("blk_0_n_3", type_def_int64.clone());
    let const_def_int64_1_local = func_ver.new_constant(const_def_int64_1.clone());
198

199
    //   %v48 = EQ <@int_64> %n_3 @int_64_1
200
201
    let blk_0_v48 = func_ver.new_ssa("blk_0_v48", type_def_int64.clone());
    let blk_0_inst0 = func_ver.new_inst(Instruction {
qinsoon's avatar
qinsoon committed
202
            value: Some(vec![blk_0_v48.clone_value()]),
203
204
            ops: RefCell::new(vec![blk_0_n_3.clone(), const_def_int64_1_local.clone()]),
            v: Instruction_::CmpOp(CmpOp::EQ, 0, 1)
205
206
    });

207
    //   BRANCH2 %v48 %blk_2(@int_64_1) %blk_1(%n_3)
208
    let blk_0_term = func_ver.new_inst(Instruction{
209
210
211
212
213
214
215
216
217
218
219
        value: None,
        ops: RefCell::new(vec![blk_0_v48.clone(), const_def_int64_1_local.clone(), blk_0_n_3.clone()]),
        v: Instruction_::Branch2 {
            cond: 0,
            true_dest: Destination {
                target: "blk_2",
                args: vec![DestArg::Normal(1)]
            },
            false_dest: Destination {
                target: "blk_1",
                args: vec![DestArg::Normal(2)]
220
            },
221
            true_prob: 0.3f32
222
        }
qinsoon's avatar
qinsoon committed
223
    });
224

225
    let blk_0_content = BlockContent {
226
        args: vec![blk_0_n_3.clone_value()],
227
        body: vec![blk_0_inst0, blk_0_term],
228
        keepalives: None
229
    };
230
    blk_0.content = Some(blk_0_content);
231
232
233

    // %blk_2(<@int_64> %v53):
    let mut blk_2 = Block::new("blk_2");
234
    let blk_2_v53 = func_ver.new_ssa("blk_2_v53", type_def_int64.clone());
235

236
    //   RET %v53
237
    let blk_2_term = func_ver.new_inst(Instruction{
238
239
240
241
        value: None,
        ops: RefCell::new(vec![blk_2_v53.clone()]),
        v: Instruction_::Return(vec![0])
    });
242

243
    let blk_2_content = BlockContent {
244
        args: vec![blk_2_v53.clone_value()],
245
        body: vec![blk_2_term],
246
247
        keepalives: None
    };
248
    blk_2.content = Some(blk_2_content);
249

250
251
    // %blk_1(<@int_64> %n_3):
    let mut blk_1 = Block::new("blk_1");
252
    let blk_1_n_3 = func_ver.new_ssa("blk_1_n_3", type_def_int64.clone());
253

254
    //   %v50 = SUB <@int_64> %n_3 @int_64_1
255
256
    let blk_1_v50 = func_ver.new_ssa("blk_1_v50", type_def_int64.clone());
    let blk_1_inst0 = func_ver.new_inst(Instruction{
qinsoon's avatar
qinsoon committed
257
        value: Some(vec![blk_1_v50.clone_value()]),
258
259
260
        ops: RefCell::new(vec![blk_1_n_3.clone(), const_def_int64_1_local.clone()]),
        v: Instruction_::BinOp(BinOp::Sub, 0, 1)
    });
261

262
    //   %v51 = CALL <@fac_sig> @fac (%v50)
263
264
265
    let blk_1_v51 = func_ver.new_ssa("blk_1_v51", type_def_int64.clone());
    let blk_1_fac = func_ver.new_constant(const_func_fac.clone());
    let blk_1_inst1 = func_ver.new_inst(Instruction{
qinsoon's avatar
qinsoon committed
266
267
        value: Some(vec![blk_1_v51.clone_value()]),
        ops: RefCell::new(vec![blk_1_fac, blk_1_v50.clone()]),
268
269
270
271
272
273
274
275
        v: Instruction_::ExprCall {
            data: CallData {
                func: 0,
                args: vec![1],
                convention: CallConvention::Mu
            },
            is_abort: true
        }
qinsoon's avatar
qinsoon committed
276
    });
277

278
    //   %v52 = MUL <@int_64> %n_3 %v51
279
280
    let blk_1_v52 = func_ver.new_ssa("blk_1_v52", type_def_int64.clone());
    let blk_1_inst2 = func_ver.new_inst(Instruction{
qinsoon's avatar
qinsoon committed
281
        value: Some(vec![blk_1_v52.clone_value()]),
282
283
        ops: RefCell::new(vec![blk_1_n_3.clone(), blk_1_v51.clone()]),
        v: Instruction_::BinOp(BinOp::Mul, 0, 1)
qinsoon's avatar
qinsoon committed
284
    });
285

286
    // BRANCH blk_2 (%blk_1_v52)
287
    let blk_1_term = func_ver.new_inst(Instruction{
288
289
290
291
292
293
294
        value: None,
        ops: RefCell::new(vec![blk_1_v52.clone()]),
        v: Instruction_::Branch1(Destination {
                target: "blk_2",
                args: vec![DestArg::Normal(0)]
           })
    });
295

296
    let blk_1_content = BlockContent {
297
        args: vec![blk_1_n_3.clone_value()],
298
        body: vec![blk_1_inst0, blk_1_inst1, blk_1_inst2, blk_1_term],
299
300
        keepalives: None
    };
301
    blk_1.content = Some(blk_1_content);
302

303
    // wrap into a function
304
    func_ver.define(FunctionContent{
305
            entry: "blk_0",
306
307
308
309
310
311
312
313
            blocks: {
                let mut blocks = HashMap::new();
                blocks.insert("blk_0", blk_0);
                blocks.insert("blk_1", blk_1);
                blocks.insert("blk_2", blk_2);
                blocks
            }
    });
314

315
    vm.define_func_version(func_ver);
316

317
    vm
318
}