Auto merge of #107449 - saethlin:enable-copyprop, r=oli-obk
Enable CopyProp r? `@tmiasko` `@rustbot` label +A-mir-opt
This commit is contained in:
commit
639377ed73
18 changed files with 342 additions and 267 deletions
|
@ -22,7 +22,7 @@ pub struct CopyProp;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for CopyProp {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 4
|
||||
sess.mir_opt_level() >= 1
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, tcx, body))]
|
||||
|
@ -96,7 +96,7 @@ fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet<Local> {
|
|||
fully_moved
|
||||
}
|
||||
|
||||
/// Utility to help performing subtitution of `*pattern` by `target`.
|
||||
/// Utility to help performing substitution of `*pattern` by `target`.
|
||||
struct Replacer<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fully_moved: BitSet<Local>,
|
||||
|
|
|
@ -19,6 +19,33 @@ pub struct SsaLocals {
|
|||
copy_classes: IndexVec<Local, Local>,
|
||||
}
|
||||
|
||||
/// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to
|
||||
/// actually compute dominators, we can just compare block indices because bb0 is always the first
|
||||
/// block, and in any body all other blocks are always always dominated by bb0.
|
||||
struct SmallDominators {
|
||||
inner: Option<Dominators<BasicBlock>>,
|
||||
}
|
||||
|
||||
trait DomExt {
|
||||
fn dominates(self, _other: Self, dominators: &SmallDominators) -> bool;
|
||||
}
|
||||
|
||||
impl DomExt for Location {
|
||||
fn dominates(self, other: Location, dominators: &SmallDominators) -> bool {
|
||||
if self.block == other.block {
|
||||
self.statement_index <= other.statement_index
|
||||
} else {
|
||||
dominators.dominates(self.block, other.block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SmallDominators {
|
||||
fn dominates(&self, dom: BasicBlock, node: BasicBlock) -> bool {
|
||||
if let Some(inner) = &self.inner { inner.dominates(dom, node) } else { dom < node }
|
||||
}
|
||||
}
|
||||
|
||||
impl SsaLocals {
|
||||
pub fn new<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -29,7 +56,9 @@ impl SsaLocals {
|
|||
let assignment_order = Vec::new();
|
||||
|
||||
let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
|
||||
let dominators = body.basic_blocks.dominators();
|
||||
let dominators =
|
||||
if body.basic_blocks.len() > 2 { Some(body.basic_blocks.dominators()) } else { None };
|
||||
let dominators = SmallDominators { inner: dominators };
|
||||
let mut visitor = SsaVisitor { assignments, assignment_order, dominators };
|
||||
|
||||
for (local, decl) in body.local_decls.iter_enumerated() {
|
||||
|
@ -41,8 +70,14 @@ impl SsaLocals {
|
|||
}
|
||||
}
|
||||
|
||||
for (bb, data) in traversal::reverse_postorder(body) {
|
||||
visitor.visit_basic_block_data(bb, data);
|
||||
if body.basic_blocks.len() > 2 {
|
||||
for (bb, data) in traversal::reverse_postorder(body) {
|
||||
visitor.visit_basic_block_data(bb, data);
|
||||
}
|
||||
} else {
|
||||
for (bb, data) in body.basic_blocks.iter_enumerated() {
|
||||
visitor.visit_basic_block_data(bb, data);
|
||||
}
|
||||
}
|
||||
|
||||
for var_debug_info in &body.var_debug_info {
|
||||
|
@ -139,7 +174,7 @@ enum LocationExtended {
|
|||
}
|
||||
|
||||
struct SsaVisitor {
|
||||
dominators: Dominators<BasicBlock>,
|
||||
dominators: SmallDominators,
|
||||
assignments: IndexVec<Local, Set1<LocationExtended>>,
|
||||
assignment_order: Vec<Local>,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue