Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit aff4d3e

Browse files
committed
rustc_mir: run the MIR inlining Integrator on the whole callee body at once.
1 parent 9b21c50 commit aff4d3e

File tree

1 file changed

+65
-70
lines changed

1 file changed

+65
-70
lines changed

compiler/rustc_mir/src/transform/inline.rs

Lines changed: 65 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use rustc_attr as attr;
44
use rustc_index::bit_set::BitSet;
5-
use rustc_index::vec::{Idx, IndexVec};
5+
use rustc_index::vec::Idx;
66
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
77
use rustc_middle::mir::visit::*;
88
use rustc_middle::mir::*;
@@ -14,6 +14,7 @@ use super::simplify::{remove_dead_blocks, CfgSimplifier};
1414
use crate::transform::MirPass;
1515
use std::collections::VecDeque;
1616
use std::iter;
17+
use std::ops::RangeFrom;
1718

1819
const DEFAULT_THRESHOLD: usize = 50;
1920
const HINT_THRESHOLD: usize = 100;
@@ -477,26 +478,24 @@ impl Inliner<'tcx> {
477478
// Copy the arguments if needed.
478479
let args: Vec<_> = self.make_call_args(args, &callsite, caller_body, return_block);
479480

480-
let bb_len = caller_body.basic_blocks().len();
481481
let mut integrator = Integrator {
482-
block_idx: bb_len,
483482
args: &args,
484-
local_map: IndexVec::with_capacity(callee_body.local_decls.len()),
485-
scope_map: IndexVec::with_capacity(callee_body.source_scopes.len()),
483+
new_locals: Local::new(caller_body.local_decls.len())..,
484+
new_scopes: SourceScope::new(caller_body.source_scopes.len())..,
485+
new_blocks: BasicBlock::new(caller_body.basic_blocks().len())..,
486486
destination: dest,
487487
return_block,
488488
cleanup_block: cleanup,
489489
in_cleanup_block: false,
490490
tcx: self.tcx,
491491
};
492492

493-
for mut scope in callee_body.source_scopes.iter().cloned() {
494-
// Map the callee scopes into the caller.
495-
// FIXME(eddyb) this may ICE if the scopes are out of order.
496-
scope.parent_scope = scope.parent_scope.map(|s| integrator.scope_map[s]);
497-
scope.inlined_parent_scope =
498-
scope.inlined_parent_scope.map(|s| integrator.scope_map[s]);
493+
// Map all `Local`s, `SourceScope`s and `BasicBlock`s to new ones
494+
// (or existing ones, in a few special cases) in the caller.
495+
integrator.visit_body(&mut callee_body);
499496

497+
for scope in &mut callee_body.source_scopes {
498+
// FIXME(eddyb) move this into a `fn visit_scope_data` in `Integrator`.
500499
if scope.parent_scope.is_none() {
501500
let callsite_scope = &caller_body.source_scopes[callsite.source_info.scope];
502501

@@ -516,38 +515,26 @@ impl Inliner<'tcx> {
516515
} else if scope.inlined_parent_scope.is_none() {
517516
// Make it easy to find the scope with `inlined` set above.
518517
scope.inlined_parent_scope =
519-
Some(integrator.scope_map[OUTERMOST_SOURCE_SCOPE]);
518+
Some(integrator.map_scope(OUTERMOST_SOURCE_SCOPE));
520519
}
521-
522-
let idx = caller_body.source_scopes.push(scope);
523-
integrator.scope_map.push(idx);
524-
}
525-
526-
for loc in callee_body.vars_and_temps_iter() {
527-
let mut local = callee_body.local_decls[loc].clone();
528-
529-
local.source_info.scope = integrator.scope_map[local.source_info.scope];
530-
531-
let idx = caller_body.local_decls.push(local);
532-
integrator.local_map.push(idx);
533-
}
534-
535-
for mut var_debug_info in callee_body.var_debug_info.drain(..) {
536-
integrator.visit_var_debug_info(&mut var_debug_info);
537-
caller_body.var_debug_info.push(var_debug_info);
538520
}
539521

540-
for (bb, mut block) in callee_body.basic_blocks_mut().drain_enumerated(..) {
541-
integrator.visit_basic_block_data(bb, &mut block);
542-
caller_body.basic_blocks_mut().push(block);
543-
}
522+
// Insert all of the (mapped) parts of the callee body into the caller.
523+
caller_body.local_decls.extend(
524+
// FIXME(eddyb) make `Range<Local>` iterable so that we can use
525+
// `callee_body.local_decls.drain(callee_body.vars_and_temps())`
526+
callee_body
527+
.vars_and_temps_iter()
528+
.map(|local| callee_body.local_decls[local].clone()),
529+
);
530+
caller_body.source_scopes.extend(callee_body.source_scopes.drain(..));
531+
caller_body.var_debug_info.extend(callee_body.var_debug_info.drain(..));
532+
caller_body.basic_blocks_mut().extend(callee_body.basic_blocks_mut().drain(..));
544533

545-
let terminator = Terminator {
534+
caller_body[callsite.bb].terminator = Some(Terminator {
546535
source_info: callsite.source_info,
547-
kind: TerminatorKind::Goto { target: BasicBlock::new(bb_len) },
548-
};
549-
550-
caller_body[callsite.bb].terminator = Some(terminator);
536+
kind: TerminatorKind::Goto { target: integrator.map_block(START_BLOCK) },
537+
});
551538

552539
true
553540
}
@@ -703,10 +690,10 @@ fn type_size_of<'tcx>(
703690
* stuff.
704691
*/
705692
struct Integrator<'a, 'tcx> {
706-
block_idx: usize,
707693
args: &'a [Local],
708-
local_map: IndexVec<Local, Local>,
709-
scope_map: IndexVec<SourceScope, SourceScope>,
694+
new_locals: RangeFrom<Local>,
695+
new_scopes: RangeFrom<SourceScope>,
696+
new_blocks: RangeFrom<BasicBlock>,
710697
destination: Place<'tcx>,
711698
return_block: BasicBlock,
712699
cleanup_block: Option<BasicBlock>,
@@ -715,23 +702,31 @@ struct Integrator<'a, 'tcx> {
715702
}
716703

717704
impl<'a, 'tcx> Integrator<'a, 'tcx> {
718-
fn update_target(&self, tgt: BasicBlock) -> BasicBlock {
719-
let new = BasicBlock::new(tgt.index() + self.block_idx);
720-
debug!("updating target `{:?}`, new: `{:?}`", tgt, new);
705+
fn map_local(&self, local: Local) -> Local {
706+
let new = if local == RETURN_PLACE {
707+
self.destination.local
708+
} else {
709+
let idx = local.index() - 1;
710+
if idx < self.args.len() {
711+
self.args[idx]
712+
} else {
713+
Local::new(self.new_locals.start.index() + (idx - self.args.len()))
714+
}
715+
};
716+
debug!("mapping local `{:?}` to `{:?}`", local, new);
721717
new
722718
}
723719

724-
fn make_integrate_local(&self, local: Local) -> Local {
725-
if local == RETURN_PLACE {
726-
return self.destination.local;
727-
}
728-
729-
let idx = local.index() - 1;
730-
if idx < self.args.len() {
731-
return self.args[idx];
732-
}
720+
fn map_scope(&self, scope: SourceScope) -> SourceScope {
721+
let new = SourceScope::new(self.new_scopes.start.index() + scope.index());
722+
debug!("mapping scope `{:?}` to `{:?}`", scope, new);
723+
new
724+
}
733725

734-
self.local_map[Local::new(idx - self.args.len())]
726+
fn map_block(&self, block: BasicBlock) -> BasicBlock {
727+
let new = BasicBlock::new(self.new_blocks.start.index() + block.index());
728+
debug!("mapping block `{:?}` to `{:?}`", block, new);
729+
new
735730
}
736731
}
737732

@@ -741,7 +736,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
741736
}
742737

743738
fn visit_local(&mut self, local: &mut Local, _ctxt: PlaceContext, _location: Location) {
744-
*local = self.make_integrate_local(*local);
739+
*local = self.map_local(*local);
740+
}
741+
742+
fn visit_source_scope(&mut self, scope: &mut SourceScope) {
743+
*scope = self.map_scope(*scope);
745744
}
746745

747746
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
@@ -785,18 +784,18 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
785784
match terminator.kind {
786785
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => bug!(),
787786
TerminatorKind::Goto { ref mut target } => {
788-
*target = self.update_target(*target);
787+
*target = self.map_block(*target);
789788
}
790789
TerminatorKind::SwitchInt { ref mut targets, .. } => {
791790
for tgt in targets.all_targets_mut() {
792-
*tgt = self.update_target(*tgt);
791+
*tgt = self.map_block(*tgt);
793792
}
794793
}
795794
TerminatorKind::Drop { ref mut target, ref mut unwind, .. }
796795
| TerminatorKind::DropAndReplace { ref mut target, ref mut unwind, .. } => {
797-
*target = self.update_target(*target);
796+
*target = self.map_block(*target);
798797
if let Some(tgt) = *unwind {
799-
*unwind = Some(self.update_target(tgt));
798+
*unwind = Some(self.map_block(tgt));
800799
} else if !self.in_cleanup_block {
801800
// Unless this drop is in a cleanup block, add an unwind edge to
802801
// the original call's cleanup block
@@ -805,20 +804,20 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
805804
}
806805
TerminatorKind::Call { ref mut destination, ref mut cleanup, .. } => {
807806
if let Some((_, ref mut tgt)) = *destination {
808-
*tgt = self.update_target(*tgt);
807+
*tgt = self.map_block(*tgt);
809808
}
810809
if let Some(tgt) = *cleanup {
811-
*cleanup = Some(self.update_target(tgt));
810+
*cleanup = Some(self.map_block(tgt));
812811
} else if !self.in_cleanup_block {
813812
// Unless this call is in a cleanup block, add an unwind edge to
814813
// the original call's cleanup block
815814
*cleanup = self.cleanup_block;
816815
}
817816
}
818817
TerminatorKind::Assert { ref mut target, ref mut cleanup, .. } => {
819-
*target = self.update_target(*target);
818+
*target = self.map_block(*target);
820819
if let Some(tgt) = *cleanup {
821-
*cleanup = Some(self.update_target(tgt));
820+
*cleanup = Some(self.map_block(tgt));
822821
} else if !self.in_cleanup_block {
823822
// Unless this assert is in a cleanup block, add an unwind edge to
824823
// the original call's cleanup block
@@ -836,8 +835,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
836835
TerminatorKind::Abort => {}
837836
TerminatorKind::Unreachable => {}
838837
TerminatorKind::FalseEdge { ref mut real_target, ref mut imaginary_target } => {
839-
*real_target = self.update_target(*real_target);
840-
*imaginary_target = self.update_target(*imaginary_target);
838+
*real_target = self.map_block(*real_target);
839+
*imaginary_target = self.map_block(*imaginary_target);
841840
}
842841
TerminatorKind::FalseUnwind { real_target: _, unwind: _ } =>
843842
// see the ordering of passes in the optimized_mir query.
@@ -846,13 +845,9 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
846845
}
847846
TerminatorKind::InlineAsm { ref mut destination, .. } => {
848847
if let Some(ref mut tgt) = *destination {
849-
*tgt = self.update_target(*tgt);
848+
*tgt = self.map_block(*tgt);
850849
}
851850
}
852851
}
853852
}
854-
855-
fn visit_source_scope(&mut self, scope: &mut SourceScope) {
856-
*scope = self.scope_map[*scope];
857-
}
858853
}

0 commit comments

Comments
 (0)