Skip to content

Rollup of 29 pull requests #33610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 78 commits into from
Closed
Changes from 2 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
96b2288
trans: Always lower to `frem`
alexcrichton May 9, 2016
df572fc
Remove unused function `lower_opt_bounds`
jseyfried May 9, 2016
417fe6d
Refactor away method `LoweringContext::diagnostic`
jseyfried May 9, 2016
eed8d70
Give lowering functions mutable access to the lowering context
jseyfried May 9, 2016
8d5c578
Remove needless `pub`s
jseyfried May 10, 2016
0a38089
Copy more libraries from local Rust to stage0
antonblanchard May 10, 2016
946efcd
Refactor the `hir::lowering::lower_*` functions into methods of `Lowe…
jseyfried May 10, 2016
3927ff4
Make the remaining functions in `hir::lowering` methods of `LoweringC…
jseyfried May 10, 2016
33978b0
Refactor `hir::lowering` API
jseyfried May 10, 2016
66404f3
Simplify text
dns2utf8 May 10, 2016
9ac468b
Store a reference rather than a RefCell in LocalCrateReader.
Ms2ger May 10, 2016
8d3531d
Correct typo in LocalCrateReader::definitions.
Ms2ger May 10, 2016
e919f25
Delay wrapping Definitions into a RefCell around LocalCrateReader.
Ms2ger May 10, 2016
e5a91b7
mir: don't attempt to promote Unpromotable constant temps.
eddyb May 10, 2016
85e0242
Add error description for E0455
cristianoliveira May 4, 2016
7a9f4c2
Add E0500 error explanation
GuillaumeGomez May 10, 2016
5511e65
Hand ownership of the Definitions to map_crate.
Ms2ger May 10, 2016
c0e321a
Make LocalCrateReader private to creader.
Ms2ger May 10, 2016
00f6513
Only break critical edges where actually needed
dotdash May 10, 2016
5541fdf
Use symlink_metadata in tidy to avoid panicking on broken symlinks.
eddyb May 11, 2016
4e5a2e0
Remove unification despite ambiguity in projection
soltanmm-google May 11, 2016
c91b104
Export OnceState from libstd
Amanieu May 11, 2016
5cbfa12
Fix typo in std::sync::Once documentation
Amanieu May 11, 2016
49b2cdf
[MIR trans] Optimize trans for biased switches
dotdash May 11, 2016
fd70788
Do not use const Rib for associated constants
nagisa May 11, 2016
5af829b
Gen right parameter envirnoment for assoc consts
nagisa May 11, 2016
8628cce
Add inferred obligation storage to all Vtable variants and SelectionC…
soltanmm-google May 11, 2016
ec7c483
Don't mutate the inference context when assembling
soltanmm-google May 11, 2016
d3218fa
Check the constants’ parameter environment
nagisa May 11, 2016
f52b655
Plumb inference obligations through selection
soltanmm-google May 12, 2016
6458b04
Cleanup formatting and wording for `std::env::temp_dir` docs.
frewsxcv May 12, 2016
a7902b1
Tighten span for E0063
sanxiyn May 12, 2016
3c2ec13
rustc: use a simpler scheme for plugin registrar symbol names.
eddyb May 10, 2016
fc0872a
trans: remove unused symbol_names::exported_name_with_suffix.
eddyb May 10, 2016
06e00c4
trans: move exported_name's logic into symbol_names.
eddyb May 11, 2016
073f289
trans: force absolute item paths within symbols.
eddyb May 11, 2016
843b174
typeck: if a private field exists, also check for a public method
birkenfeld May 2, 2016
c331032
Better handling of tab in error
sanxiyn May 9, 2016
df4fe5f
update "reason" for fnbox feature gate
durka May 12, 2016
b9fce76
fix tidy
durka May 12, 2016
9393e52
Don't use env::current_exe with libbacktrace
sfackler May 8, 2016
f7362ca
trans: move exported_symbol to Instance::symbol_name.
eddyb May 12, 2016
ff3a1ce
trans: move the MSVC linker to compute symbols on-demand.
eddyb May 12, 2016
749494e
trans: remove item_symbols from metadata and CrateContext.
eddyb May 12, 2016
aa00e3a
re-introduce a cache for ast-ty-to-ty
nikomatsakis May 12, 2016
0eeb14e
Improve derived implementations for enums with lots of fieldless vari…
dotdash May 12, 2016
538de73
rustdoc: Fix missing type parameters on impls
ollie27 May 12, 2016
d4bff0c
doc: Fix comment in std::string::String example code
haikoschol May 12, 2016
adee551
trans: save metadata even with -Z no-trans.
eddyb May 12, 2016
8ad6d27
[MIR] Enhance the SimplifyCfg pass to merge consecutive blocks
dotdash Nov 14, 2015
bb7d0ce
Rollup merge of #33342 - birkenfeld:issue-26472, r=jseyfried
eddyb May 13, 2016
be92e9b
Rollup merge of #33393 - cristianoliveira:docs-error-explanation, r=s…
eddyb May 13, 2016
6859599
Rollup merge of #33508 - alexcrichton:always-lower-frem, r=nikomatsakis
eddyb May 13, 2016
82fd37c
Rollup merge of #33513 - sanxiyn:tab-in-error, r=nikomatsakis
eddyb May 13, 2016
5637db9
Rollup merge of #33517 - sanxiyn:tight-span, r=nagisa
eddyb May 13, 2016
673d686
Rollup merge of #33531 - antonblanchard:local_stage0_fix, r=alexcrichton
eddyb May 13, 2016
76794b6
Rollup merge of #33532 - jseyfried:mutable_lowering_context, r=nrc
eddyb May 13, 2016
e141d95
Rollup merge of #33533 - GuillaumeGomez:add_E0500, r=steveklabnik
eddyb May 13, 2016
dbf812f
Rollup merge of #33534 - dns2utf8:atomic_docs, r=GuillaumeGomez
eddyb May 13, 2016
b3ecd27
Rollup merge of #33538 - Ms2ger:LocalCrateReader, r=arielb1
eddyb May 13, 2016
5a48beb
Rollup merge of #33541 - eddyb:promote-only-temps, r=arielb1
eddyb May 13, 2016
96b6e8f
Rollup merge of #33544 - dotdash:baby_dont_break_me_no_more, r=Aatch
eddyb May 13, 2016
494bc14
Rollup merge of #33552 - dotdash:scfg, r=luqmana
eddyb May 13, 2016
bab9fa2
Rollup merge of #33554 - sfackler:no-current-exe, r=alexcrichton
eddyb May 13, 2016
c3e0529
Rollup merge of #33555 - soltanmm:ambiguous-nixon, r=nikomatsakis
eddyb May 13, 2016
bf535f3
Rollup merge of #33560 - eddyb:symtidy, r=alexcrichton
eddyb May 13, 2016
dc37d09
Rollup merge of #33563 - Amanieu:oncestate, r=alexcrichton
eddyb May 13, 2016
a8a491a
Rollup merge of #33565 - Amanieu:once_doc, r=GuillaumeGomez
eddyb May 13, 2016
8942994
Rollup merge of #33566 - dotdash:biased_switch, r=nagisa
eddyb May 13, 2016
1879aaa
Rollup merge of #33572 - nagisa:assoc-const-types, r=eddyb
eddyb May 13, 2016
2c55f77
Rollup merge of #33576 - soltanmm:vtable, r=nikomatsakis
eddyb May 13, 2016
88ecbc4
Rollup merge of #33580 - frewsxcv:temp-dir, r=alexcrichton
eddyb May 13, 2016
0018516
Rollup merge of #33590 - durka:patch-22, r=aturon
eddyb May 13, 2016
31d4b35
Rollup merge of #33593 - dotdash:smart_derive, r=brson
eddyb May 13, 2016
73f75cc
Rollup merge of #33596 - nikomatsakis:issue-33586-regr-assoc-type-pat…
eddyb May 13, 2016
d1ab5d2
Rollup merge of #33598 - haikoschol:master, r=alexcrichton
eddyb May 13, 2016
f657a30
Rollup merge of #33600 - ollie27:rustdoc_impl_params, r=alexcrichton
eddyb May 13, 2016
96297ea
Rollup merge of #33602 - eddyb:no-trans--check, r=michaelwoerister
eddyb May 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 124 additions & 59 deletions src/librustc_mir/transform/simplify_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,73 +8,155 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc_data_structures::bitvec::BitVector;
use rustc::middle::const_val::ConstVal;
use rustc::ty::TyCtxt;
use rustc::mir::repr::*;
use rustc::mir::transform::{MirPass, MirSource, Pass};
use pretty;
use std::mem;

use super::remove_dead_blocks::RemoveDeadBlocks;

use traversal;

pub struct SimplifyCfg;

impl SimplifyCfg {
pub fn new() -> SimplifyCfg {
SimplifyCfg
}
}

impl<'tcx> MirPass<'tcx> for SimplifyCfg {
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
simplify_branches(mir);
RemoveDeadBlocks.run_pass(tcx, src, mir);
merge_consecutive_blocks(mir);
RemoveDeadBlocks.run_pass(tcx, src, mir);
pretty::dump_mir(tcx, "simplify_cfg", &0, src, mir, None);

// FIXME: Should probably be moved into some kind of pass manager
mir.basic_blocks.shrink_to_fit();
}
}

impl Pass for SimplifyCfg {}

fn merge_consecutive_blocks(mir: &mut Mir) {
// Build the precedecessor map for the MIR
let mut pred_count = vec![0u32; mir.basic_blocks.len()];
for (_, data) in traversal::preorder(mir) {
if let Some(ref term) = data.terminator {
for &tgt in term.successors().iter() {
pred_count[tgt.index()] += 1;
}
}
}

loop {
let mut changed = false;
let mut seen = BitVector::new(mir.basic_blocks.len());
let mut worklist = vec![START_BLOCK];
while let Some(bb) = worklist.pop() {
// Temporarily take ownership of the terminator we're modifying to keep borrowck happy
let mut terminator = mir.basic_block_data_mut(bb).terminator.take()
.expect("invalid terminator state");

// See if we can merge the target block into this one
loop {
let mut inner_change = false;

fn remove_goto_chains(&self, mir: &mut Mir) -> bool {
// Find the target at the end of the jump chain, return None if there is a loop
fn final_target(mir: &Mir, mut target: BasicBlock) -> Option<BasicBlock> {
// Keep track of already seen blocks to detect loops
let mut seen: Vec<BasicBlock> = Vec::with_capacity(8);

while mir.basic_block_data(target).statements.is_empty() {
// NB -- terminator may have been swapped with `None`
// below, in which case we have a cycle and just want
// to stop
if let Some(ref terminator) = mir.basic_block_data(target).terminator {
match terminator.kind {
TerminatorKind::Goto { target: next } => {
if seen.contains(&next) {
return None;
if let TerminatorKind::Goto { target } = terminator.kind {
// Don't bother trying to merge a block into itself
if target == bb {
break;
}

let num_insts = mir.basic_block_data(target).statements.len();
match mir.basic_block_data(target).terminator().kind {
TerminatorKind::Goto { target: new_target } if num_insts == 0 => {
inner_change = true;
terminator.kind = TerminatorKind::Goto { target: new_target };
pred_count[target.index()] -= 1;
pred_count[new_target.index()] += 1;
}
_ if pred_count[target.index()] == 1 => {
inner_change = true;
let mut stmts = Vec::new();
{
let target_data = mir.basic_block_data_mut(target);
mem::swap(&mut stmts, &mut target_data.statements);
mem::swap(&mut terminator, target_data.terminator_mut());
}
seen.push(next);
target = next;

mir.basic_block_data_mut(bb).statements.append(&mut stmts);
}
_ => break
_ => {}
};
}

for target in terminator.successors_mut() {
let new_target = match final_target(mir, *target) {
Some(new_target) => new_target,
None if mir.basic_block_data(bb).statements.is_empty() => bb,
None => continue
};
if *target != new_target {
inner_change = true;
pred_count[target.index()] -= 1;
pred_count[new_target.index()] += 1;
*target = new_target;
}
} else {
break
}

changed |= inner_change;
if !inner_change {
break;
}
}

Some(target)
mir.basic_block_data_mut(bb).terminator = Some(terminator);

for succ in mir.basic_block_data(bb).terminator().successors().iter() {
if seen.insert(succ.index()) {
worklist.push(*succ);
}
}
}

let mut changed = false;
for bb in mir.all_basic_blocks() {
// Temporarily take ownership of the terminator we're modifying to keep borrowck happy
let mut terminator = mir.basic_block_data_mut(bb).terminator.take()
.expect("invalid terminator state");

debug!("remove_goto_chains: bb={:?} terminator={:?}", bb, terminator);

for target in terminator.successors_mut() {
let new_target = match final_target(mir, *target) {
Some(new_target) => new_target,
None if mir.basic_block_data(bb).statements.is_empty() => bb,
None => continue
};
changed |= *target != new_target;
*target = new_target;
if !changed {
break;
}
}
}

// Find the target at the end of the jump chain, return None if there is a loop
fn final_target(mir: &Mir, mut target: BasicBlock) -> Option<BasicBlock> {
// Keep track of already seen blocks to detect loops
let mut seen: Vec<BasicBlock> = Vec::with_capacity(8);

while mir.basic_block_data(target).statements.is_empty() {
// NB -- terminator may have been swapped with `None` in
// merge_consecutive_blocks, in which case we have a cycle and just want
// to stop
match mir.basic_block_data(target).terminator {
Some(Terminator { kind: TerminatorKind::Goto { target: next }, .. }) => {
if seen.contains(&next) {
return None;
}
seen.push(next);
target = next;
}
mir.basic_block_data_mut(bb).terminator = Some(terminator);
_ => break
}
changed
}

fn simplify_branches(&self, mir: &mut Mir) -> bool {
Some(target)
}

fn simplify_branches(mir: &mut Mir) {
loop {
let mut changed = false;

for bb in mir.all_basic_blocks() {
Expand Down Expand Up @@ -106,25 +188,8 @@ impl SimplifyCfg {
}
}

changed
}
}

impl<'tcx> MirPass<'tcx> for SimplifyCfg {
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, mir: &mut Mir<'tcx>) {
let mut counter = 0;
let mut changed = true;
while changed {
pretty::dump_mir(tcx, "simplify_cfg", &counter, src, mir, None);
counter += 1;
changed = self.simplify_branches(mir);
changed |= self.remove_goto_chains(mir);
RemoveDeadBlocks.run_pass(tcx, src, mir);
if !changed {
break;
}
// FIXME: Should probably be moved into some kind of pass manager
mir.basic_blocks.shrink_to_fit();
}
}

impl Pass for SimplifyCfg {}