]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/transform/mod.rs
rename `MirPassSet` to `MirSuite`
[rust.git] / src / librustc_mir / transform / mod.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use rustc::hir::def_id::DefId;
12 use rustc::mir::Mir;
13 use rustc::mir::transform::{MirCtxt, MirPassIndex, MirSuite, MirSource, MIR_OPTIMIZED};
14 use rustc::ty::TyCtxt;
15 use rustc::ty::maps::Providers;
16 use std::cell::{Ref, RefCell};
17 use std::mem;
18
19 pub mod simplify_branches;
20 pub mod simplify;
21 pub mod erase_regions;
22 pub mod no_landing_pads;
23 pub mod type_check;
24 pub mod add_call_guards;
25 pub mod promote_consts;
26 pub mod qualify_consts;
27 pub mod dump_mir;
28 pub mod deaggregator;
29 pub mod instcombine;
30 pub mod copy_prop;
31 pub mod inline;
32
33 pub fn provide(providers: &mut Providers) {
34     self::qualify_consts::provide(providers);
35     *providers = Providers {
36         optimized_mir,
37         mir_suite,
38         mir_pass,
39         ..*providers
40     };
41 }
42
43 fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx RefCell<Mir<'tcx>> {
44     let mir = tcx.mir_suite((MIR_OPTIMIZED, def_id));
45
46     // "lock" the ref cell into read mode; after this point,
47     // there ought to be no more changes to the MIR.
48     mem::drop(mir.borrow());
49
50     mir
51 }
52
53 fn mir_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
54                        (suite, def_id): (MirSuite, DefId))
55                        -> &'tcx RefCell<Mir<'tcx>>
56 {
57     let passes = &tcx.mir_passes;
58     let len = passes.len_passes(suite);
59     assert!(len > 0, "no passes in {:?}", suite);
60     tcx.mir_pass((suite, MirPassIndex(len - 1), def_id))
61 }
62
63 fn mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
64                       (suite, pass_num, def_id): (MirSuite, MirPassIndex, DefId))
65                       -> &'tcx RefCell<Mir<'tcx>>
66 {
67     let passes = &tcx.mir_passes;
68     let pass = passes.pass(suite, pass_num);
69     let mir_ctxt = MirCtxtImpl { tcx, pass_num, suite, def_id };
70
71     for hook in passes.hooks() {
72         hook.on_mir_pass(&mir_ctxt, None);
73     }
74
75     let mir = pass.run_pass(&mir_ctxt);
76
77     for hook in passes.hooks() {
78         hook.on_mir_pass(&mir_ctxt, Some(&mir.borrow()));
79     }
80
81     mir
82 }
83
84 struct MirCtxtImpl<'a, 'tcx: 'a> {
85     tcx: TyCtxt<'a, 'tcx, 'tcx>,
86     pass_num: MirPassIndex,
87     suite: MirSuite,
88     def_id: DefId
89 }
90
91 impl<'a, 'tcx> MirCtxt<'a, 'tcx> for MirCtxtImpl<'a, 'tcx> {
92     fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
93         self.tcx
94     }
95
96     fn suite(&self) -> MirSuite {
97         self.suite
98     }
99
100     fn pass_num(&self) -> MirPassIndex {
101         self.pass_num
102     }
103
104     fn def_id(&self) -> DefId {
105         self.def_id
106     }
107
108     fn source(&self) -> MirSource {
109         let id = self.tcx.hir.as_local_node_id(self.def_id)
110                              .expect("mir source requires local def-id");
111         MirSource::from_node(self.tcx, id)
112     }
113
114     fn read_previous_mir(&self) -> Ref<'tcx, Mir<'tcx>> {
115         self.steal_previous_mir().borrow()
116     }
117
118     fn steal_previous_mir(&self) -> &'tcx RefCell<Mir<'tcx>> {
119         let MirSuite(suite) = self.suite;
120         let MirPassIndex(pass_num) = self.pass_num;
121         if pass_num > 0 {
122             self.tcx.mir_pass((MirSuite(suite), MirPassIndex(pass_num - 1), self.def_id))
123         } else if suite > 0 {
124             self.tcx.mir_suite((MirSuite(suite - 1), self.def_id))
125         } else {
126             self.tcx.mir_build(self.def_id)
127         }
128     }
129 }