]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/transform/mod.rs
dc67c6f1ef45f168567d396245a5b653e6c476bb
[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::{MirPassIndex, MirSuite, MirSource, MIR_VALIDATED, MIR_OPTIMIZED};
14 use rustc::ty::{self, TyCtxt};
15 use rustc::ty::steal::Steal;
16 use rustc::ty::maps::Providers;
17 use syntax_pos::DUMMY_SP;
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 pub mod interprocedural;
33
34 pub fn provide(providers: &mut Providers) {
35     self::qualify_consts::provide(providers);
36     *providers = Providers {
37         optimized_mir,
38         mir_suite,
39         mir_pass,
40         ..*providers
41     };
42 }
43
44 fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Mir<'tcx> {
45     let mir = tcx.mir_suite((MIR_OPTIMIZED, def_id)).steal();
46     tcx.alloc_mir(mir)
47 }
48
49 fn mir_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
50                        (suite, def_id): (MirSuite, DefId))
51                        -> &'tcx Steal<Mir<'tcx>>
52 {
53     let passes = &tcx.mir_passes;
54
55     if suite == MIR_VALIDATED {
56         let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
57         let source = MirSource::from_node(tcx, id);
58         if let MirSource::Const(_) = source {
59             // Ensure that we compute the `mir_const_qualif` for
60             // constants at this point, before we do any further
61             // optimization (and before we steal the previous
62             // MIR). We don't directly need the result, so we can
63             // just force it.
64             ty::queries::mir_const_qualif::force(tcx, DUMMY_SP, def_id);
65         }
66     }
67
68     let len = passes.len_passes(suite);
69     assert!(len > 0, "no passes in {:?}", suite);
70     tcx.mir_pass((suite, MirPassIndex(len - 1), def_id))
71 }
72
73 fn mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
74                       (suite, pass_num, def_id): (MirSuite, MirPassIndex, DefId))
75                       -> &'tcx Steal<Mir<'tcx>>
76 {
77     let passes = &tcx.mir_passes;
78     let pass = passes.pass(suite, pass_num);
79
80     let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
81     let source = MirSource::from_node(tcx, id);
82
83     let mut mir = {
84         let MirSuite(suite) = suite;
85         let MirPassIndex(pass_num) = pass_num;
86         if pass_num > 0 {
87             tcx.mir_pass((MirSuite(suite), MirPassIndex(pass_num - 1), def_id)).steal()
88         } else if suite > 0 {
89             tcx.mir_suite((MirSuite(suite - 1), def_id)).steal()
90         } else {
91             tcx.mir_build(def_id).steal()
92         }
93     };
94
95     for hook in passes.hooks() {
96         hook.on_mir_pass(tcx, suite, pass_num, &pass.name(), source, &mir, false);
97     }
98
99     pass.run_pass(tcx, source, &mut mir);
100
101     for hook in passes.hooks() {
102         hook.on_mir_pass(tcx, suite, pass_num, &pass.name(), source, &mir, true);
103     }
104
105     tcx.alloc_steal_mir(mir)
106 }
107