// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use rustc::mir::repr::*; /// Update basic block ids in all terminators using the given replacements, /// useful e.g. after removal of several basic blocks to update all terminators /// in a single pass pub fn update_basic_block_ids(mir: &mut Mir, replacements: &[BasicBlock]) { for bb in mir.all_basic_blocks() { for target in mir.basic_block_data_mut(bb).terminator_mut().successors_mut() { *target = replacements[target.index()]; } } } /// Mass removal of basic blocks to keep the ID-remapping cheap. pub fn retain_basic_blocks(mir: &mut Mir, keep: &[bool]) { let num_blocks = mir.basic_blocks.len(); // Check that we have a usage flag for every block assert_eq!(num_blocks, keep.len()); let first_dead = match keep.iter().position(|&k| !k) { None => return, Some(first_dead) => first_dead, }; // `replacements` maps the old block ids to the new ones let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect(); let mut dead = 0; for i in first_dead..num_blocks { if keep[i] { replacements[i] = BasicBlock::new(i - dead); mir.basic_blocks.swap(i, i - dead); } else { dead += 1; } } mir.basic_blocks.truncate(num_blocks - dead); update_basic_block_ids(mir, &replacements); }