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

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

9
10
use std::cell::RefCell;

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#[test]
#[allow(unused_variables)]
fn test_factorial() {
    let vm = factorial();
}

#[allow(unused_variables)]
pub fn factorial() -> VMContext {
    let mut vm = VMContext::new();
    
    // .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
28
29
30
31
32
33
34
    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)));
35
36
    
    // .const @int_64_1 <@int_64> = 1
37
    let const_def_int64_1 = vm.declare_const("int64_1", type_def_int64.clone(), Constant::Int(1));
38
39
40
41
42
    
    // .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()]);
    
    // .funcdef @fac VERSION @fac_v1 <@fac_sig>
43
    let mut func = MuFunction::new("fac", fac_sig.clone());
44
45
46
    
    // %blk_0(<@int_64> %n_3):
    let mut blk_0 = Block::new("blk_0");
qinsoon's avatar
qinsoon committed
47
    let blk_0_n_3 = func.new_ssa(0, "blk_0_n_3", type_def_int64.clone());
48
    let const_def_int64_1_local = func.new_value(const_def_int64_1.clone());
49
50
    
    //   %v48 = EQ <@int_64> %n_3 @int_64_1
qinsoon's avatar
qinsoon committed
51
    let blk_0_v48 = func.new_ssa(1, "blk_0_v48", type_def_int64.clone());
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    let blk_0_inst0 = TreeNode::new_inst(Instruction {
            value: Some(vec![blk_0_v48.clone()]),
            ops: RefCell::new(vec![blk_0_n_3.clone(), const_def_int64_1_local.clone()]),
            v: Instruction_::CmpOp(CmpOp::EQ, 0, 1)
    });    
    
    //   BRANCH2 %v48 %blk_2(@int_64_1) %blk_1(%n_3)
    let blk_0_term = TreeNode::new_inst(Instruction{
        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)]
            }
72
        }
qinsoon's avatar
qinsoon committed
73
    });
74
75
76
    
    let blk_0_content = BlockContent {
        args: vec![blk_0_n_3.clone()], 
77
        body: vec![blk_0_inst0, blk_0_term], 
78
79
        keepalives: None
    }; 
80
    blk_0.content = Some(blk_0_content);
81
82
83

    // %blk_2(<@int_64> %v53):
    let mut blk_2 = Block::new("blk_2");
qinsoon's avatar
qinsoon committed
84
    let blk_2_v53 = func.new_ssa(2, "blk_2_v53", type_def_int64.clone());
85
86
    
    //   RET %v53
87
88
89
90
91
    let blk_2_term = TreeNode::new_inst(Instruction{
        value: None,
        ops: RefCell::new(vec![blk_2_v53.clone()]),
        v: Instruction_::Return(vec![0])
    });
92
93
94
    
    let blk_2_content = BlockContent {
        args: vec![blk_2_v53.clone()], 
95
        body: vec![blk_2_term], 
96
97
        keepalives: None
    };
98
    blk_2.content = Some(blk_2_content);
99
100
101
    
    // %blk_1(<@int_64> %n_3):
    let mut blk_1 = Block::new("blk_1");
qinsoon's avatar
qinsoon committed
102
    let blk_1_n_3 = func.new_ssa(3, "blk_1_n_3", type_def_int64.clone());
103
104
    
    //   %v50 = SUB <@int_64> %n_3 @int_64_1
qinsoon's avatar
qinsoon committed
105
    let blk_1_v50 = func.new_ssa(4, "blk_1_v50", type_def_int64.clone());
106
107
108
109
110
    let blk_1_inst0 = TreeNode::new_inst(Instruction{
        value: Some(vec![blk_1_v50.clone()]),
        ops: RefCell::new(vec![blk_1_n_3.clone(), const_def_int64_1_local.clone()]),
        v: Instruction_::BinOp(BinOp::Sub, 0, 1)
    });
111
112
    
    //   %v51 = CALL <@fac_sig> @fac (%v50)
qinsoon's avatar
qinsoon committed
113
    let blk_1_v51 = func.new_ssa(5, "blk_1_v51", type_def_int64.clone());
114
115
116
117
118
119
120
121
122
123
124
    let blk_1_inst1 = TreeNode::new_inst(Instruction{
        value: Some(vec![blk_1_v51.clone()]),
        ops: RefCell::new(vec![func.new_ssa(6, "blk_1_fac", P(MuType::funcref(fac_sig.clone()))), blk_1_v50.clone()]),
        v: Instruction_::ExprCall {
            data: CallData {
                func: 0,
                args: vec![1],
                convention: CallConvention::Mu
            },
            is_abort: true
        }
qinsoon's avatar
qinsoon committed
125
    });
126
127
    
    //   %v52 = MUL <@int_64> %n_3 %v51
qinsoon's avatar
qinsoon committed
128
    let blk_1_v52 = func.new_ssa(7, "blk_1_v52", type_def_int64.clone());
129
130
131
132
    let blk_1_inst2 = TreeNode::new_inst(Instruction{
        value: Some(vec![blk_1_v52.clone()]),
        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
133
    });
134
    
135
136
137
138
139
140
141
142
    let blk_1_term = TreeNode::new_inst(Instruction{
        value: None,
        ops: RefCell::new(vec![blk_1_v52.clone()]),
        v: Instruction_::Branch1(Destination {
                target: "blk_2",
                args: vec![DestArg::Normal(0)]
           })
    });
143
    
144
145
146
    let blk_1_content = BlockContent {
        args: vec![blk_1_n_3.clone()], 
        body: vec![blk_1_inst0, blk_1_inst1, blk_1_inst2, blk_1_term],
147
148
        keepalives: None
    };
149
    blk_1.content = Some(blk_1_content);
150
151
    
    // wrap into a function
152
153
154
155
156
157
158
    func.define(FunctionContent{
            entry: "blk_0", 
            blocks: vec![
                ("blk_0", blk_0),
                ("blk_1", blk_1),
                ("blk_2", blk_2)
            ]}
159
160
    );
    
161
162
    vm.declare_func(func);
    
163
164
    vm
}