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

muirbuilder.rs 176 KB
Newer Older
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
1
// Copyright 2017 The Australian National University
qinsoon's avatar
qinsoon committed
2
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
3
4
5
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
qinsoon's avatar
qinsoon committed
6
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
7
//     http://www.apache.org/licenses/LICENSE-2.0
qinsoon's avatar
qinsoon committed
8
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
9
10
11
12
13
14
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

15
16
// RTMU this file needs many additions

17
use super::common::*;
Kunshan Wang's avatar
Kunshan Wang committed
18
use ast::inst::*;
19
20
21
22
use ast::op::*;
use std;
use utils::bit_utils::bits_ones;
use utils::math::align_up;
23
use utils::LinkedHashMap;
24
use utils::LinkedHashSet;
25

26
27
pub static mut VALIDATE_IR: bool = true;

28
macro_rules! assert_ir {
29
30
    ($ cond : expr ) => [{if unsafe{VALIDATE_IR} {assert!($cond)} }];
    ($ cond : expr , $ ( $ arg : tt ) + ) => [{if unsafe{VALIDATE_IR} {assert!($cond, $($arg)+)} }];
31
32
}

33
pub struct MuIRBuilder {
34
    /// ref to MuVM
35
    mvm: *const MuVM,
36

37
38
    /// Point to the C-visible CMuIRBuilder so that `load` and `abort` can
    /// deallocate itself.
39
40
    pub c_struct: *mut CMuIRBuilder,

41
42
    /// Map IDs to names. Items are inserted during `gen_sym`. MuIRBuilder is
    /// supposed to be used by one thread, so there is no need for locking.
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
43
44
45
46
    /// Note: names generated by Zebu internally may also be added to this map
    id_name_map: HashMap<MuID, MuName>,
    /// This maps all names given by the client (using gen_sym) to ids
    name_id_map: HashMap<MuName, MuID>,
47
    /// The "transient bundle" includes everything being built here.
48
    bundle: TransientBundle
49
50
}

51
pub type IdBMap<T> = HashMap<MuID, Box<T>>;
52

53
54
/// A transient bundle, i.e. the bundle being built, but not yet loaded into the
/// MuVM.
55
#[derive(Default)]
56
pub struct TransientBundle {
57
58
59
60
61
62
63
64
65
66
67
    types: IdBMap<NodeType>,
    sigs: IdBMap<NodeFuncSig>,
    consts: IdBMap<NodeConst>,
    globals: IdBMap<NodeGlobalCell>,
    funcs: IdBMap<NodeFunc>,
    expfuncs: IdBMap<NodeExpFunc>,
    funcvers: IdBMap<NodeFuncVer>,
    bbs: IdBMap<NodeBB>,
    insts: IdBMap<NodeInst>,
    dest_clauses: IdBMap<NodeDestClause>,
    exc_clauses: IdBMap<NodeExcClause>,
68
69
    cs_clauses: IdBMap<NodeCurrentStackClause>,
    ns_clauses: IdBMap<NodeNewStackClause>,
70
    ka_clauses: IdBMap<NodeKeepaliveClause>
71
72
}

73
74
impl MuIRBuilder {
    pub fn new(mvm: *const MuVM) -> Box<MuIRBuilder> {
75
76
77
78
        Box::new(MuIRBuilder {
            mvm: mvm,
            c_struct: ptr::null_mut(),
            id_name_map: Default::default(),
79
            name_id_map: Default::default(),
80
            bundle: Default::default()
81
82
        })
    }
83

84
    #[inline(always)]
85
86
    fn get_mvm<'a, 'b>(&'a mut self) -> &'b MuVM {
        //self.mvm
qinsoon's avatar
qinsoon committed
87
        unsafe { &*self.mvm }
88
89
    }

90
91
    #[inline(always)]
    fn get_mvm_immutable<'a, 'b>(&'a self) -> &'b MuVM {
qinsoon's avatar
qinsoon committed
92
        unsafe { &*self.mvm }
93
94
    }

95
    #[inline(always)]
96
    fn get_vm<'a, 'b>(&'a mut self) -> &'b VM {
97
98
99
100
101
102
103
104
105
106
107
        &self.get_mvm().vm
    }

    #[inline(always)]
    fn next_id(&mut self) -> MuID {
        self.get_vm().next_id()
    }

    fn deallocate(&mut self) {
        let c_struct = self.c_struct;
        let b_ptr = self as *mut MuIRBuilder;
qinsoon's avatar
qinsoon committed
108
109
        debug!(
            "Deallocating MuIRBuilder {:?} and CMuIRBuilder {:?}...",
110
            b_ptr, c_struct
qinsoon's avatar
qinsoon committed
111
        );
112
113
114
115
        unsafe {
            Box::from_raw(c_struct);
            Box::from_raw(b_ptr);
        }
116
        trace!("Deallocation done!");
117
118
    }

119
120
121
    /// Get the Mu name of the `id`. This will consume the entry in the
    /// `id_name_map`. For this reason, this function is only called when
    /// the actual MuEntity that has this ID is created
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    /// (such as `new_type_int`).
    fn consume_name_of(&mut self, id: MuID) -> Option<MuName> {
        self.id_name_map.remove(&id)
    }

    pub fn load(&mut self) {
        load_bundle(self);
        self.deallocate();
    }

    pub fn abort(&mut self) {
        info!("Aborting boot image building...");
        self.deallocate();
    }

137
    pub fn gen_sym(&mut self, name: Option<MuName>) -> MuID {
138
139
        let my_id = self.next_id();

qinsoon's avatar
qinsoon committed
140
        trace!("gen_sym({:?}) -> {}", name, my_id);
141
142

        match name {
qinsoon's avatar
qinsoon committed
143
            None => {}
144
            Some(the_name) => {
145
146
147
                let old_name = self.id_name_map.insert(my_id, the_name.clone());
                let old_id = self.name_id_map.insert(the_name, my_id);
                assert_ir!(old_id.is_none());
qinsoon's avatar
qinsoon committed
148
                debug_assert!(
149
                    old_name.is_none(),
qinsoon's avatar
qinsoon committed
150
151
152
                    "ID already exists: {}, new name: {}, old name: {}",
                    my_id,
                    self.id_name_map.get(&my_id).unwrap(),
153
                    old_name.unwrap()
qinsoon's avatar
qinsoon committed
154
155
                );
            }
156
157
158
159
160
161
        };

        my_id
    }

    pub fn new_type_int(&mut self, id: MuID, len: c_int) {
qinsoon's avatar
qinsoon committed
162
163
164
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeInt { id: id, len: len }));
165
166
167
    }

    pub fn new_type_float(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
168
169
170
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeFloat { id: id }));
171
172
173
    }

    pub fn new_type_double(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
174
175
176
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeDouble { id: id }));
177
178
179
    }

    pub fn new_type_uptr(&mut self, id: MuID, ty: MuID) {
qinsoon's avatar
qinsoon committed
180
181
182
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeUPtr { id: id, ty: ty }));
183
184
185
    }

    pub fn new_type_ufuncptr(&mut self, id: MuID, sig: MuID) {
qinsoon's avatar
qinsoon committed
186
187
188
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeUFuncPtr { id: id, sig: sig }));
189
190
191
    }

    pub fn new_type_struct(&mut self, id: MuID, fieldtys: Vec<MuID>) {
qinsoon's avatar
qinsoon committed
192
193
194
195
        self.bundle.types.insert(
            id,
            Box::new(NodeType::TypeStruct {
                id: id,
196
197
                fieldtys: fieldtys
            })
qinsoon's avatar
qinsoon committed
198
        );
199
200
    }

201
202
203
204
205
206
    pub fn new_type_hybrid(
        &mut self,
        id: MuID,
        fixedtys: Vec<MuID>,
        varty: MuID
    ) {
qinsoon's avatar
qinsoon committed
207
208
209
210
211
        self.bundle.types.insert(
            id,
            Box::new(NodeType::TypeHybrid {
                id: id,
                fixedtys: fixedtys,
212
213
                varty: varty
            })
qinsoon's avatar
qinsoon committed
214
        );
215
216
217
    }

    pub fn new_type_array(&mut self, id: MuID, elemty: MuID, len: u64) {
qinsoon's avatar
qinsoon committed
218
219
220
221
222
        self.bundle.types.insert(
            id,
            Box::new(NodeType::TypeArray {
                id: id,
                elemty: elemty,
223
224
                len: len as usize
            })
qinsoon's avatar
qinsoon committed
225
        );
226
227
228
    }

    pub fn new_type_vector(&mut self, id: MuID, elemty: MuID, len: u64) {
qinsoon's avatar
qinsoon committed
229
230
231
232
233
        self.bundle.types.insert(
            id,
            Box::new(NodeType::TypeVector {
                id: id,
                elemty: elemty,
234
235
                len: len as usize
            })
qinsoon's avatar
qinsoon committed
236
        );
237
238
239
    }

    pub fn new_type_void(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
240
241
242
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeVoid { id: id }));
243
244
245
    }

    pub fn new_type_ref(&mut self, id: MuID, ty: MuID) {
qinsoon's avatar
qinsoon committed
246
247
248
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeRef { id: id, ty: ty }));
249
250
251
    }

    pub fn new_type_iref(&mut self, id: MuID, ty: MuID) {
qinsoon's avatar
qinsoon committed
252
253
254
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeIRef { id: id, ty: ty }));
255
256
257
    }

    pub fn new_type_weakref(&mut self, id: MuID, ty: MuID) {
qinsoon's avatar
qinsoon committed
258
259
260
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeWeakRef { id: id, ty: ty }));
261
262
263
    }

    pub fn new_type_funcref(&mut self, id: MuID, sig: MuID) {
qinsoon's avatar
qinsoon committed
264
265
266
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeFuncRef { id: id, sig: sig }));
267
268
269
    }

    pub fn new_type_tagref64(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
270
271
272
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeTagRef64 { id: id }));
273
274
275
    }

    pub fn new_type_threadref(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
276
277
278
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeThreadRef { id: id }));
279
280
281
    }

    pub fn new_type_stackref(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
282
283
284
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeStackRef { id: id }));
285
286
287
    }

    pub fn new_type_framecursorref(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
288
289
290
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeFrameCursorRef { id: id }));
291
292
293
    }

    pub fn new_type_irbuilderref(&mut self, id: MuID) {
qinsoon's avatar
qinsoon committed
294
295
296
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeIRBuilderRef { id: id }));
297
298
    }

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
    pub fn new_type_regionref(&mut self, id: MuID) {
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeRegionRef { id }));
    }

    pub fn new_type_attrref(&mut self, id: MuID) {
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeAttrRef { id }));
    }

    pub fn new_type_timerref(&mut self, id: MuID) {
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeTimerRef { id }));
    }

    pub fn new_type_futexref(&mut self, id: MuID) {
        self.bundle
            .types
            .insert(id, Box::new(NodeType::TypeFutexRef { id }));
    }

323
324
325
326
327
328
    pub fn new_funcsig(
        &mut self,
        id: MuID,
        paramtys: Vec<MuID>,
        rettys: Vec<MuID>
    ) {
qinsoon's avatar
qinsoon committed
329
330
331
332
333
        self.bundle.sigs.insert(
            id,
            Box::new(NodeFuncSig {
                id: id,
                paramtys: paramtys,
334
335
                rettys: rettys
            })
qinsoon's avatar
qinsoon committed
336
        );
337
338
339
    }

    pub fn new_const_int(&mut self, id: MuID, ty: MuID, value: u64) {
qinsoon's avatar
qinsoon committed
340
341
342
343
344
        self.bundle.consts.insert(
            id,
            Box::new(NodeConst::ConstInt {
                id: id,
                ty: ty,
345
346
                value: value
            })
qinsoon's avatar
qinsoon committed
347
        );
348
349
350
    }

    pub fn new_const_int_ex(&mut self, id: MuID, ty: MuID, values: &[u64]) {
qinsoon's avatar
qinsoon committed
351
352
353
354
355
        self.bundle.consts.insert(
            id,
            Box::new(NodeConst::ConstIntEx {
                id: id,
                ty: ty,
356
357
                value: values.to_vec()
            })
qinsoon's avatar
qinsoon committed
358
        );
359
360
361
    }

    pub fn new_const_float(&mut self, id: MuID, ty: MuID, value: f32) {
qinsoon's avatar
qinsoon committed
362
363
364
365
366
        self.bundle.consts.insert(
            id,
            Box::new(NodeConst::ConstFloat {
                id: id,
                ty: ty,
367
368
                value: value
            })
qinsoon's avatar
qinsoon committed
369
        );
370
371
372
    }

    pub fn new_const_double(&mut self, id: MuID, ty: MuID, value: f64) {
qinsoon's avatar
qinsoon committed
373
374
375
376
377
        self.bundle.consts.insert(
            id,
            Box::new(NodeConst::ConstDouble {
                id: id,
                ty: ty,
378
379
                value: value
            })
qinsoon's avatar
qinsoon committed
380
        );
381
382
383
    }

    pub fn new_const_null(&mut self, id: MuID, ty: MuID) {
qinsoon's avatar
qinsoon committed
384
385
386
        self.bundle
            .consts
            .insert(id, Box::new(NodeConst::ConstNull { id: id, ty: ty }));
387
388
389
    }

    pub fn new_const_seq(&mut self, id: MuID, ty: MuID, elems: Vec<MuID>) {
qinsoon's avatar
qinsoon committed
390
391
392
393
394
        self.bundle.consts.insert(
            id,
            Box::new(NodeConst::ConstSeq {
                id: id,
                ty: ty,
395
396
                elems: elems
            })
qinsoon's avatar
qinsoon committed
397
        );
398
399
    }

400
    pub fn new_const_extern(&mut self, id: MuID, ty: MuID, symbol: MuName) {
qinsoon's avatar
qinsoon committed
401
402
403
404
405
        self.bundle.consts.insert(
            id,
            Box::new(NodeConst::ConstExtern {
                id: id,
                ty: ty,
406
407
                symbol: symbol
            })
qinsoon's avatar
qinsoon committed
408
        );
409
410
411
    }

    pub fn new_global_cell(&mut self, id: MuID, ty: MuID) {
qinsoon's avatar
qinsoon committed
412
413
414
        self.bundle
            .globals
            .insert(id, Box::new(NodeGlobalCell { id: id, ty: ty }));
415
416
417
    }

    pub fn new_func(&mut self, id: MuID, sig: MuID) {
qinsoon's avatar
qinsoon committed
418
419
420
        self.bundle
            .funcs
            .insert(id, Box::new(NodeFunc { id: id, sig: sig }));
421
422
    }

423
424
425
426
427
428
429
    pub fn new_exp_func(
        &mut self,
        id: MuID,
        func: MuID,
        callconv: CMuCallConv,
        cookie: MuID
    ) {
430
431
432
433
        panic!("Not implemented")
    }

    pub fn new_func_ver(&mut self, id: MuID, func: MuID, bbs: Vec<MuID>) {
qinsoon's avatar
qinsoon committed
434
435
436
437
438
        self.bundle.funcvers.insert(
            id,
            Box::new(NodeFuncVer {
                id: id,
                func: func,
439
440
                bbs: bbs
            })
qinsoon's avatar
qinsoon committed
441
442
443
444
445
446
447
448
449
        );
    }

    pub fn new_bb(
        &mut self,
        id: MuID,
        nor_param_ids: Vec<MuID>,
        nor_param_types: Vec<MuID>,
        exc_param_id: Option<MuID>,
450
        insts: Vec<MuID>
qinsoon's avatar
qinsoon committed
451
452
453
454
455
456
457
458
    ) {
        self.bundle.bbs.insert(
            id,
            Box::new(NodeBB {
                id: id,
                nor_param_ids: nor_param_ids,
                nor_param_types: nor_param_types,
                exc_param_id: exc_param_id,
459
460
                insts: insts
            })
qinsoon's avatar
qinsoon committed
461
        );
462
463
464
    }

    pub fn new_dest_clause(&mut self, id: MuID, dest: MuID, vars: Vec<MuID>) {
qinsoon's avatar
qinsoon committed
465
466
467
468
469
        self.bundle.dest_clauses.insert(
            id,
            Box::new(NodeDestClause {
                id: id,
                dest: dest,
470
471
                vars: vars
            })
qinsoon's avatar
qinsoon committed
472
        );
473
474
475
    }

    pub fn new_exc_clause(&mut self, id: MuID, nor: MuID, exc: MuID) {
qinsoon's avatar
qinsoon committed
476
477
478
479
480
        self.bundle.exc_clauses.insert(
            id,
            Box::new(NodeExcClause {
                id: id,
                nor: nor,
481
482
                exc: exc
            })
qinsoon's avatar
qinsoon committed
483
        );
484
485
486
    }

    pub fn new_keepalive_clause(&mut self, id: MuID, vars: Vec<MuID>) {
qinsoon's avatar
qinsoon committed
487
488
489
        self.bundle
            .ka_clauses
            .insert(id, Box::new(NodeKeepaliveClause { id: id, vars: vars }));
490
491
492
    }

    pub fn new_csc_ret_with(&mut self, id: MuID, rettys: Vec<MuID>) {
493
494
        self.bundle.cs_clauses.insert(
            id,
495
            Box::new(NodeCurrentStackClause::RetWith {
496
                id: id,
497
498
                rettys: rettys
            })
499
        );
500
501
502
    }

    pub fn new_csc_kill_old(&mut self, id: MuID) {
503
504
505
        self.bundle
            .cs_clauses
            .insert(id, Box::new(NodeCurrentStackClause::KillOld { id: id }));
506
507
    }

508
509
510
511
512
513
    pub fn new_nsc_pass_values(
        &mut self,
        id: MuID,
        tys: Vec<MuID>,
        vars: Vec<MuID>
    ) {
514
515
        self.bundle.ns_clauses.insert(
            id,
516
            Box::new(NodeNewStackClause::PassValues {
517
518
                id: id,
                tys: tys,
519
520
                vars: vars
            })
521
        );
522
523
524
    }

    pub fn new_nsc_throw_exc(&mut self, id: MuID, exc: MuID) {
525
526
        self.bundle.ns_clauses.insert(
            id,
527
            Box::new(NodeNewStackClause::ThrowExc { id: id, exc: exc })
528
        );
529
530
    }

531
532
533
534
535
    #[inline(always)]
    fn add_inst(&mut self, id: MuID, inst: NodeInst) {
        self.bundle.insts.insert(id, Box::new(inst));
    }

qinsoon's avatar
qinsoon committed
536
537
538
539
540
541
542
543
    pub fn new_binop(
        &mut self,
        id: MuID,
        result_id: MuID,
        optr: CMuBinOptr,
        ty: MuID,
        opnd1: MuID,
        opnd2: MuID,
544
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
545
    ) {
546
        trace!("new_binop");
qinsoon's avatar
qinsoon committed
547
548
549
550
551
552
553
554
555
556
557
        self.add_inst(
            id,
            NodeInst::NodeBinOp {
                id: id,
                result_id: result_id,
                status_result_ids: vec![],
                optr: optr,
                flags: 0,
                ty: ty,
                opnd1: opnd1,
                opnd2: opnd2,
558
559
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
560
561
562
563
564
565
566
567
568
569
570
571
572
        );
    }

    pub fn new_binop_with_status(
        &mut self,
        id: MuID,
        result_id: MuID,
        status_result_ids: Vec<MuID>,
        optr: CMuBinOptr,
        status_flags: CMuBinOpStatus,
        ty: MuID,
        opnd1: MuID,
        opnd2: MuID,
573
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
574
    ) {
575
        trace!("new_binop_with_status");
qinsoon's avatar
qinsoon committed
576
577
578
579
580
581
582
583
584
585
586
        self.add_inst(
            id,
            NodeInst::NodeBinOp {
                id: id,
                result_id: result_id,
                status_result_ids: status_result_ids,
                optr: optr,
                flags: status_flags,
                ty: ty,
                opnd1: opnd1,
                opnd2: opnd2,
587
588
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
589
590
591
592
593
594
595
596
597
598
        )
    }

    pub fn new_cmp(
        &mut self,
        id: MuID,
        result_id: MuID,
        optr: CMuCmpOptr,
        ty: MuID,
        opnd1: MuID,
599
        opnd2: MuID
qinsoon's avatar
qinsoon committed
600
    ) {
601
        trace!("new_cmp");
qinsoon's avatar
qinsoon committed
602
603
604
605
606
607
608
609
        self.add_inst(
            id,
            NodeInst::NodeCmp {
                id: id,
                result_id: result_id,
                optr: optr,
                ty: ty,
                opnd1: opnd1,
610
611
                opnd2: opnd2
            }
qinsoon's avatar
qinsoon committed
612
613
614
615
616
617
618
619
620
621
        );
    }

    pub fn new_conv(
        &mut self,
        id: MuID,
        result_id: MuID,
        optr: CMuConvOptr,
        from_ty: MuID,
        to_ty: MuID,
622
        opnd: MuID
qinsoon's avatar
qinsoon committed
623
    ) {
624
        trace!("new_conv");
qinsoon's avatar
qinsoon committed
625
626
627
628
629
630
631
632
        self.add_inst(
            id,
            NodeInst::NodeConv {
                id: id,
                result_id: result_id,
                optr: optr,
                from_ty: from_ty,
                to_ty: to_ty,
633
634
                opnd: opnd
            }
qinsoon's avatar
qinsoon committed
635
636
637
638
639
640
641
642
643
644
645
        );
    }

    pub fn new_select(
        &mut self,
        id: MuID,
        result_id: MuID,
        cond_ty: MuID,
        opnd_ty: MuID,
        cond: MuID,
        if_true: MuID,
646
        if_false: MuID
qinsoon's avatar
qinsoon committed
647
    ) {
648
        trace!("new_select");
qinsoon's avatar
qinsoon committed
649
650
651
652
653
654
655
656
657
        self.add_inst(
            id,
            NodeInst::NodeSelect {
                id: id,
                result_id: result_id,
                cond_ty: cond_ty,
                opnd_ty: opnd_ty,
                cond: cond,
                if_true: if_true,
658
659
                if_false: if_false
            }
qinsoon's avatar
qinsoon committed
660
        );
661
662
663
    }

    pub fn new_branch(&mut self, id: MuID, dest: MuID) {
664
        trace!("muirbuilder.rs new_branch");
qinsoon's avatar
qinsoon committed
665
        self.add_inst(id, NodeInst::NodeBranch { id: id, dest: dest });
666
        trace!("muirbuilder.rs built new_branch");
667
668
    }

669
670
671
672
673
674
675
    pub fn new_branch2(
        &mut self,
        id: MuID,
        cond: MuID,
        if_true: MuID,
        if_false: MuID
    ) {
676
        trace!("new_branch2");
qinsoon's avatar
qinsoon committed
677
678
679
680
681
682
        self.add_inst(
            id,
            NodeInst::NodeBranch2 {
                id: id,
                cond: cond,
                if_true: if_true,
683
684
                if_false: if_false
            }
qinsoon's avatar
qinsoon committed
685
686
687
688
689
690
691
692
693
694
        );
    }

    pub fn new_switch(
        &mut self,
        id: MuID,
        opnd_ty: MuID,
        opnd: MuID,
        default_dest: MuID,
        cases: Vec<MuID>,
695
        dests: Vec<MuID>
qinsoon's avatar
qinsoon committed
696
    ) {
697
        trace!("new_switch");
qinsoon's avatar
qinsoon committed
698
699
700
701
702
703
704
705
        self.add_inst(
            id,
            NodeInst::NodeSwitch {
                id: id,
                opnd_ty: opnd_ty,
                opnd: opnd,
                default_dest: default_dest,
                cases: cases,
706
707
                dests: dests
            }
qinsoon's avatar
qinsoon committed
708
709
710
711
712
713
714
715
716
717
718
        );
    }

    pub fn new_call(
        &mut self,
        id: MuID,
        result_ids: Vec<MuID>,
        sig: MuID,
        callee: MuID,
        args: Vec<MuID>,
        exc_clause: Option<MuID>,
719
        keepalive_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
720
    ) {
721
        trace!("new_call");
qinsoon's avatar
qinsoon committed
722
723
724
725
726
727
728
729
730
        self.add_inst(
            id,
            NodeInst::NodeCall {
                id: id,
                result_ids: result_ids,
                sig: sig,
                callee: callee,
                args: args,
                exc_clause: exc_clause,
731
732
                keepalive_clause: keepalive_clause
            }
qinsoon's avatar
qinsoon committed
733
        );
734
735
    }

736
737
738
739
740
741
742
    pub fn new_tailcall(
        &mut self,
        id: MuID,
        sig: MuID,
        callee: MuID,
        args: Vec<MuID>
    ) {
743
        trace!("new_tailcall");
qinsoon's avatar
qinsoon committed
744
745
746
747
748
749
        self.add_inst(
            id,
            NodeInst::NodeTailCall {
                id: id,
                sig: sig,
                callee: callee,
750
751
                args: args
            }
qinsoon's avatar
qinsoon committed
752
        );
753
754
755
    }

    pub fn new_ret(&mut self, id: MuID, rvs: Vec<MuID>) {
756
        trace!("new_ret");
qinsoon's avatar
qinsoon committed
757
        self.add_inst(id, NodeInst::NodeRet { id: id, rvs: rvs });
758
759
760
    }

    pub fn new_throw(&mut self, id: MuID, exc: MuID) {
761
        trace!("new_throw");
qinsoon's avatar
qinsoon committed
762
763
764
765
766
767
768
769
770
        self.add_inst(id, NodeInst::NodeThrow { id: id, exc: exc });
    }

    pub fn new_extractvalue(
        &mut self,
        id: MuID,
        result_id: MuID,
        strty: MuID,
        index: c_int,
771
        opnd: MuID
qinsoon's avatar
qinsoon committed
772
    ) {
773
        trace!("new_extractvalue");
qinsoon's avatar
qinsoon committed
774
775
776
777
778
779
780
        self.add_inst(
            id,
            NodeInst::NodeExtractValue {
                id: id,
                result_id: result_id,
                strty: strty,
                index: index,
781
782
                opnd: opnd
            }
qinsoon's avatar
qinsoon committed
783
784
785
786
787
788
789
790
791
792
        );
    }

    pub fn new_insertvalue(
        &mut self,
        id: MuID,
        result_id: MuID,
        strty: MuID,
        index: c_int,
        opnd: MuID,
793
        newval: MuID
qinsoon's avatar
qinsoon committed
794
    ) {
795
        trace!("new_insertvalue");
qinsoon's avatar
qinsoon committed
796
797
798
799
800
801
802
803
        self.add_inst(
            id,
            NodeInst::NodeInsertValue {
                id: id,
                result_id: result_id,
                strty: strty,
                index: index,
                opnd: opnd,
804
805
                newval: newval
            }
qinsoon's avatar
qinsoon committed
806
807
808
809
810
811
812
813
814
815
        );
    }

    pub fn new_extractelement(
        &mut self,
        id: MuID,
        result_id: MuID,
        seqty: MuID,
        indty: MuID,
        opnd: MuID,
816
        index: MuID
qinsoon's avatar
qinsoon committed
817
    ) {
818
        trace!("new_extractelement");
qinsoon's avatar
qinsoon committed
819
820
821
822
823
824
825
826
        self.add_inst(
            id,
            NodeInst::NodeExtractElement {
                id: id,
                result_id: result_id,
                seqty: seqty,
                indty: indty,
                opnd: opnd,
827
828
                index: index
            }
qinsoon's avatar
qinsoon committed
829
830
831
832
833
834
835
836
837
838
839
        );
    }

    pub fn new_insertelement(
        &mut self,
        id: MuID,
        result_id: MuID,
        seqty: MuID,
        indty: MuID,
        opnd: MuID,
        index: MuID,
840
        newval: MuID
qinsoon's avatar
qinsoon committed
841
    ) {
842
        trace!("new_insertelement");
qinsoon's avatar
qinsoon committed
843
844
845
846
847
848
849
850
851
        self.add_inst(
            id,
            NodeInst::NodeInsertElement {
                id: id,
                result_id: result_id,
                seqty: seqty,
                indty: indty,
                opnd: opnd,
                index: index,
852
853
                newval: newval
            }
qinsoon's avatar
qinsoon committed
854
855
856
857
858
859
860
861
862
863
864
        );
    }

    pub fn new_shufflevector(
        &mut self,
        id: MuID,
        result_id: MuID,
        vecty: MuID,
        maskty: MuID,
        vec1: MuID,
        vec2: MuID,
865
        mask: MuID
qinsoon's avatar
qinsoon committed
866
    ) {
867
        trace!("new_shufflevector");
qinsoon's avatar
qinsoon committed
868
869
870
871
872
873
874
875
876
        self.add_inst(
            id,
            NodeInst::NodeShuffleVector {
                id: id,
                result_id: result_id,
                vecty: vecty,
                maskty: maskty,
                vec1: vec1,
                vec2: vec2,
877
878
                mask: mask
            }
qinsoon's avatar
qinsoon committed
879
        );
880
881
    }

882
883
884
885
886
887
888
    pub fn new_new(
        &mut self,
        id: MuID,
        result_id: MuID,
        allocty: MuID,
        exc_clause: Option<MuID>
    ) {
889
        trace!("new_new");
qinsoon's avatar
qinsoon committed
890
891
892
893
894
895
        self.add_inst(
            id,
            NodeInst::NodeNew {
                id: id,
                result_id: result_id,
                allocty: allocty,
896
897
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
898
899
900
901
902
903
904
905
906
907
        );
    }

    pub fn new_newhybrid(
        &mut self,
        id: MuID,
        result_id: MuID,
        allocty: MuID,
        lenty: MuID,
        length: MuID,
908
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
909
    ) {
910
        trace!("new_newhybrid");
qinsoon's avatar
qinsoon committed
911
912
913
914
915
916
917
918
        self.add_inst(
            id,
            NodeInst::NodeNewHybrid {
                id: id,
                result_id: result_id,
                allocty: allocty,
                lenty: lenty,
                length: length,
919
920
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
921
922
923
924
925
926
927
928
        );
    }

    pub fn new_alloca(
        &mut self,
        id: MuID,
        result_id: MuID,
        allocty: MuID,
929
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
930
    ) {
931
        trace!("new_alloca");
qinsoon's avatar
qinsoon committed
932
933
934
935
936
937
        self.add_inst(
            id,
            NodeInst::NodeAlloca {
                id: id,
                result_id: result_id,
                allocty: allocty,
938
939
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
940
941
942
943
944
945
946
947
948
949
        );
    }

    pub fn new_allocahybrid(
        &mut self,
        id: MuID,
        result_id: MuID,
        allocty: MuID,
        lenty: MuID,
        length: MuID,
950
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
951
    ) {
952
        trace!("new_allocahybrid");
qinsoon's avatar
qinsoon committed
953
954
955
956
957
958
959
960
        self.add_inst(
            id,
            NodeInst::NodeAllocaHybrid {
                id: id,
                result_id: result_id,
                allocty: allocty,
                lenty: lenty,
                length: length,
961
962
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
963
        );
964
965
    }

966
967
968
969
970
971
972
    pub fn new_getiref(
        &mut self,
        id: MuID,
        result_id: MuID,
        refty: MuID,
        opnd: MuID
    ) {
973
        trace!("new_getiref");
qinsoon's avatar
qinsoon committed
974
975
976
977
978
979
        self.add_inst(
            id,
            NodeInst::NodeGetIRef {
                id: id,
                result_id: result_id,
                refty: refty,
980
981
                opnd: opnd
            }
qinsoon's avatar
qinsoon committed
982
983
984
985
986
987
988
989
990
991
        );
    }

    pub fn new_getfieldiref(
        &mut self,
        id: MuID,
        result_id: MuID,
        is_ptr: bool,
        refty: MuID,
        index: c_int,
992
        opnd: MuID
qinsoon's avatar
qinsoon committed
993
    ) {
994
        trace!("new_getfieldiref");
qinsoon's avatar
qinsoon committed
995
996
997
998
999
1000
1001
1002
        self.add_inst(
            id,
            NodeInst::NodeGetFieldIRef {
                id: id,
                result_id: result_id,
                is_ptr: is_ptr,
                refty: refty,
                index: index,
1003
1004
                opnd: opnd
            }
qinsoon's avatar
qinsoon committed
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
        );
    }

    pub fn new_getelemiref(
        &mut self,
        id: MuID,
        result_id: MuID,
        is_ptr: bool,
        refty: MuID,
        indty: MuID,
        opnd: MuID,
1016
        index: MuID
qinsoon's avatar
qinsoon committed
1017
    ) {
1018
        trace!("new_getelemiref");
qinsoon's avatar
qinsoon committed
1019
1020
1021
1022
1023
1024
1025
1026
1027
        self.add_inst(
            id,
            NodeInst::NodeGetElemIRef {
                id: id,
                result_id: result_id,
                is_ptr: is_ptr,
                refty: refty,
                indty: indty,
                opnd: opnd,
1028
1029
                index: index
            }
qinsoon's avatar
qinsoon committed
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
        );
    }

    pub fn new_shiftiref(
        &mut self,
        id: MuID,
        result_id: MuID,
        is_ptr: bool,
        refty: MuID,
        offty: MuID,
        opnd: MuID,
1041
        offset: MuID
qinsoon's avatar
qinsoon committed
1042
    ) {
1043
        trace!("new_shiftiref");
qinsoon's avatar
qinsoon committed
1044
1045
1046
1047
1048
1049
1050
1051
1052
        self.add_inst(
            id,
            NodeInst::NodeShiftIRef {
                id: id,
                result_id: result_id,
                is_ptr: is_ptr,
                refty: refty,
                offty: offty,
                opnd: opnd,
1053
1054
                offset: offset
            }
qinsoon's avatar
qinsoon committed
1055
1056
1057
1058
1059
1060
1061
1062
1063
        );
    }

    pub fn new_getvarpartiref(
        &mut self,
        id: MuID,
        result_id: MuID,
        is_ptr: bool,
        refty: MuID,
1064
        opnd: MuID
qinsoon's avatar
qinsoon committed
1065
    ) {
1066
        trace!("new_getvarpartiref");
qinsoon's avatar
qinsoon committed
1067
1068
1069
1070
1071
1072
1073
        self.add_inst(
            id,
            NodeInst::NodeGetVarPartIRef {
                id: id,
                result_id: result_id,
                is_ptr: is_ptr,
                refty: refty,
1074
1075
                opnd: opnd
            }
qinsoon's avatar
qinsoon committed
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
        );
    }

    pub fn new_load(
        &mut self,
        id: MuID,
        result_id: MuID,
        is_ptr: bool,
        ord: CMuMemOrd,
        refty: MuID,
        loc: MuID,
1087
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
1088
    ) {
1089
        trace!("new_load");
qinsoon's avatar
qinsoon committed
1090
1091
1092
1093
1094
1095
1096
1097
1098
        self.add_inst(
            id,
            NodeInst::NodeLoad {
                id: id,
                result_id: result_id,
                is_ptr: is_ptr,
                ord: ord,
                refty: refty,
                loc: loc,
1099
1100
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
        );
    }

    pub fn new_store(
        &mut self,
        id: MuID,
        is_ptr: bool,
        ord: CMuMemOrd,
        refty: MuID,
        loc: MuID,
        newval: MuID,
1112
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
1113
    ) {
1114
        trace!("new_store");
qinsoon's avatar
qinsoon committed
1115
1116
1117
1118
1119
1120
1121
1122
1123
        self.add_inst(
            id,
            NodeInst::NodeStore {
                id: id,
                is_ptr: is_ptr,
                ord: ord,
                refty: refty,
                loc: loc,
                newval: newval,
1124
1125
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
        );
    }

    pub fn new_cmpxchg(
        &mut self,
        id: MuID,
        value_result_id: MuID,
        succ_result_id: MuID,
        is_ptr: bool,
        is_weak: bool,
        ord_succ: CMuMemOrd,
        ord_fail: CMuMemOrd,
        refty: MuID,
        loc: MuID,
        expected: MuID,
        desired: MuID,
1142
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
1143
    ) {
1144
        trace!("new_cmpxchg");
qinsoon's avatar
qinsoon committed
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
        self.add_inst(
            id,
            NodeInst::NodeCmpXchg {
                id: id,
                value_result_id: value_result_id,
                succ_result_id: succ_result_id,
                is_ptr: is_ptr,
                is_weak: is_weak,
                ord_succ: ord_succ,
                ord_fail: ord_fail,
                refty: refty,
                loc: loc,
                expected: expected,
                desired: desired,
1159
1160
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
        );
    }

    pub fn new_atomicrmw(
        &mut self,
        id: MuID,
        result_id: MuID,
        is_ptr: bool,
        ord: CMuMemOrd,
        optr: CMuAtomicRMWOptr,
        ref_ty: MuID,
        loc: MuID,
        opnd: MuID,
1174
        exc_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
1175
    ) {
1176
        trace!("new_atomicrmw");
qinsoon's avatar
qinsoon committed
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
        self.add_inst(
            id,
            NodeInst::NodeAtomicRMW {
                id: id,
                result_id: result_id,
                is_ptr: is_ptr,
                ord: ord,
                optr: optr,
                ref_ty: ref_ty,
                loc: loc,
                opnd: opnd,
1188
1189
                exc_clause: exc_clause
            }
qinsoon's avatar
qinsoon committed
1190
        );
1191
1192
1193
    }

    pub fn new_fence(&mut self, id: MuID, ord: CMuMemOrd) {
1194
        trace!("new_fence");
qinsoon's avatar
qinsoon committed
1195
1196
1197
1198
1199
1200
1201
1202
1203
        self.add_inst(id, NodeInst::NodeFence { id: id, ord: ord });
    }

    pub fn new_trap(
        &mut self,
        id: MuID,
        result_ids: Vec<MuID>,
        rettys: Vec<MuID>,
        exc_clause: Option<MuID>,
1204
        keepalive_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
1205
    ) {
1206
        trace!("new_trap");
qinsoon's avatar
qinsoon committed
1207
1208
1209
1210
1211
1212
1213
        self.add_inst(
            id,
            NodeInst::NodeTrap {
                id: id,
                result_ids: result_ids,
                rettys: rettys,
                exc_clause: exc_clause,
1214
1215
                keepalive_clause: keepalive_clause
            }
qinsoon's avatar
qinsoon committed
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
        );
    }

    pub fn new_watchpoint(
        &mut self,
        id: MuID,
        wpid: CMuWPID,
        result_ids: Vec<MuID>,
        rettys: Vec<MuID>,
        dis: MuID,
        ena: MuID,
        exc: Option<MuID>,
1228
        keepalive_clause: Option<MuID>
qinsoon's avatar
qinsoon committed
1229
    ) {
1230
        trace!("new_watchpoint");
qinsoon's avatar
qinsoon committed
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
        self.add_inst(
            id,
            NodeInst::NodeWatchPoint {
                id: id,
                wpid: wpid as MuID,
                result_ids: result_ids,
                rettys: rettys,
                dis: dis,
                ena: ena,
                exc: exc,
1241
1242
                keepalive_clause: keepalive_clause
            }
qinsoon's avatar
qinsoon committed
1243
        );
1244
1245
    }

1246
1247
1248
1249
1250
1251
1252
    pub fn new_wpbranch(
        &mut self,
        id: MuID,
        wpid: CMuWPID,
        dis: MuID,
        ena: MuID
    ) {
1253
        trace!("new_wpbranch");