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.
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.
11 use rustc::hir::def_id::DefId;
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};
19 pub mod simplify_branches;
21 pub mod erase_regions;
22 pub mod no_landing_pads;
24 pub mod add_call_guards;
25 pub mod promote_consts;
26 pub mod qualify_consts;
33 pub fn provide(providers: &mut Providers) {
34 self::qualify_consts::provide(providers);
35 *providers = Providers {
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));
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());
53 fn mir_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
54 (suite, def_id): (MirSuite, DefId))
55 -> &'tcx RefCell<Mir<'tcx>>
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))
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>>
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 };
71 for hook in passes.hooks() {
72 hook.on_mir_pass(&mir_ctxt, None);
75 let mir = pass.run_pass(&mir_ctxt);
77 for hook in passes.hooks() {
78 hook.on_mir_pass(&mir_ctxt, Some(&mir.borrow()));
84 struct MirCtxtImpl<'a, 'tcx: 'a> {
85 tcx: TyCtxt<'a, 'tcx, 'tcx>,
86 pass_num: MirPassIndex,
91 impl<'a, 'tcx> MirCtxt<'a, 'tcx> for MirCtxtImpl<'a, 'tcx> {
92 fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
96 fn suite(&self) -> MirSuite {
100 fn pass_num(&self) -> MirPassIndex {
104 fn def_id(&self) -> DefId {
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)
114 fn read_previous_mir(&self) -> Ref<'tcx, Mir<'tcx>> {
115 self.steal_previous_mir().borrow()
118 fn steal_previous_mir(&self) -> &'tcx RefCell<Mir<'tcx>> {
119 let MirSuite(suite) = self.suite;
120 let MirPassIndex(pass_num) = self.pass_num;
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))
126 self.tcx.mir_build(self.def_id)