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, PassId};
14 use rustc::ty::steal::Steal;
15 use rustc::ty::TyCtxt;
16 use rustc::ty::maps::{Multi, Providers};
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;
32 pub mod interprocedural;
34 pub fn provide(providers: &mut Providers) {
35 self::qualify_consts::provide(providers);
36 *providers = Providers {
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();
49 fn mir_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
50 (suite, def_id): (MirSuite, DefId))
51 -> &'tcx Steal<Mir<'tcx>>
53 let passes = &tcx.mir_passes;
54 let len = passes.len_passes(suite);
55 assert!(len > 0, "no passes in {:?}", suite);
56 tcx.mir_pass((suite, MirPassIndex(len - 1), def_id))
59 fn mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
60 (suite, pass_num, def_id): (MirSuite, MirPassIndex, DefId))
61 -> Multi<PassId, &'tcx Steal<Mir<'tcx>>>
63 let passes = &tcx.mir_passes;
64 let pass = passes.pass(suite, pass_num);
65 let mir_ctxt = MirCtxtImpl { tcx, pass_num, suite, def_id };
67 for hook in passes.hooks() {
68 hook.on_mir_pass(&mir_ctxt, None);
71 let mir = pass.run_pass(&mir_ctxt);
73 let key = &(suite, pass_num, def_id);
74 for hook in passes.hooks() {
75 for (&(_, _, k), v) in mir.iter(key) {
77 hook.on_mir_pass(&mir_ctxt, Some((k, v)));
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.previous_mir(self.def_id).borrow()
118 fn steal_previous_mir(&self) -> Mir<'tcx> {
119 self.previous_mir(self.def_id).steal()
122 fn read_previous_mir_of(&self, def_id: DefId) -> Ref<'tcx, Mir<'tcx>> {
123 self.previous_mir(def_id).borrow()
126 fn steal_previous_mir_of(&self, def_id: DefId) -> Mir<'tcx> {
127 self.previous_mir(def_id).steal()
131 impl<'a, 'tcx> MirCtxtImpl<'a, 'tcx> {
132 fn previous_mir(&self, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
133 let MirSuite(suite) = self.suite;
134 let MirPassIndex(pass_num) = self.pass_num;
136 self.tcx.mir_pass((MirSuite(suite), MirPassIndex(pass_num - 1), def_id))
137 } else if suite > 0 {
138 self.tcx.mir_suite((MirSuite(suite - 1), def_id))
140 self.tcx.mir_build(def_id)