providers.mir_shims = make_shim;
}
-fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
+fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx BodyCache<'tcx> {
debug!("make_shim({:?})", instance);
let mut result = match instance {
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
}
};
- debug!("make_shim({:?}) = untransformed {:?}", instance, result);
+ debug!("make_shim({:?}) = untransformed {:?}", instance, result.body());
run_passes(tcx, &mut result, instance, None, MirPhase::Const, &[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
&add_call_guards::CriticalCallEdges,
]);
- debug!("make_shim({:?}) = {:?}", instance, result);
+ debug!("make_shim({:?}) = {:?}", instance, result.body());
+ result.ensure_predecessors();
tcx.arena.alloc(result)
}
.collect()
}
-fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) -> Body<'tcx> {
+fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) -> BodyCache<'tcx> {
debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty);
// Check if this is a generator, if so, return the drop glue for it
block(&mut blocks, TerminatorKind::Goto { target: return_block });
block(&mut blocks, TerminatorKind::Return);
- let mut body = Body::new(
+ let mut body = new_body(
blocks,
- IndexVec::from_elem_n(
- SourceScopeData { span: span, parent_scope: None }, 1
- ),
- ClearCrossCrate::Clear,
local_decls_for_sig(&sig, span),
- IndexVec::new(),
sig.inputs().len(),
- vec![],
- span,
- vec![],
- None,
- );
+ span);
+
+ let mut body_cache = BodyCache::new(body);
if let Some(..) = ty {
// The first argument (index 0), but add 1 for the return value.
let dropee_ptr = Place::from(Local::new(1+0));
if tcx.sess.opts.debugging_opts.mir_emit_retag {
// Function arguments should be retagged, and we make this one raw.
- body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
+ body_cache.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
source_info,
kind: StatementKind::Retag(RetagKind::Raw, box(dropee_ptr.clone())),
});
let patch = {
let param_env = tcx.param_env(def_id).with_reveal_all();
let mut elaborator = DropShimElaborator {
- body: &body,
- patch: MirPatch::new(&body),
+ body: body_cache.body(),
+ patch: MirPatch::new(body_cache.body()),
tcx,
param_env
};
);
elaborator.patch
};
- patch.apply(&mut body);
+ patch.apply(&mut body_cache);
}
- body
+ body_cache
+}
+
+fn new_body<'tcx>(
+ basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
+ local_decls: IndexVec<Local, LocalDecl<'tcx>>,
+ arg_count: usize,
+ span: Span,
+) -> Body<'tcx> {
+ Body::new(
+ basic_blocks,
+ IndexVec::from_elem_n(
+ SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
+ 1,
+ ),
+ local_decls,
+ IndexVec::new(),
+ arg_count,
+ vec![],
+ span,
+ vec![],
+ None,
+ )
}
pub struct DropShimElaborator<'a, 'tcx> {
}
/// Builds a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`.
-fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
+fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> BodyCache<'tcx> {
debug!("build_clone_shim(def_id={:?})", def_id);
let param_env = tcx.param_env(def_id);
}
};
- builder.into_mir()
+ BodyCache::new(builder.into_mir())
}
struct CloneShimBuilder<'tcx> {
}
fn into_mir(self) -> Body<'tcx> {
- Body::new(
+ new_body(
self.blocks,
- IndexVec::from_elem_n(
- SourceScopeData { span: self.span, parent_scope: None }, 1
- ),
- ClearCrossCrate::Clear,
self.local_decls,
- IndexVec::new(),
self.sig.inputs().len(),
- vec![],
self.span,
- vec![],
- None,
)
}
rcvr_adjustment: Adjustment,
call_kind: CallKind,
untuple_args: Option<&[Ty<'tcx>]>,
-) -> Body<'tcx> {
+) -> BodyCache<'tcx> {
debug!("build_call_shim(def_id={:?}, rcvr_adjustment={:?}, \
call_kind={:?}, untuple_args={:?})",
def_id, rcvr_adjustment, call_kind, untuple_args);
block(&mut blocks, vec![], TerminatorKind::Resume, true);
}
- let mut body = Body::new(
+ let mut body = new_body(
blocks,
- IndexVec::from_elem_n(
- SourceScopeData { span: span, parent_scope: None }, 1
- ),
- ClearCrossCrate::Clear,
local_decls,
- IndexVec::new(),
sig.inputs().len(),
- vec![],
span,
- vec![],
- None,
);
+
if let Abi::RustCall = sig.abi {
body.spread_arg = Some(Local::new(sig.inputs().len()));
}
- body
+ BodyCache::new(body)
}
-pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
+pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &BodyCache<'_> {
debug_assert!(tcx.is_constructor(ctor_id));
let span = tcx.hir().span_if_local(ctor_id)
is_cleanup: false
};
- let body = Body::new(
+ let mut body = new_body(
IndexVec::from_elem_n(start_block, 1),
- IndexVec::from_elem_n(
- SourceScopeData { span: span, parent_scope: None }, 1
- ),
- ClearCrossCrate::Clear,
local_decls,
- IndexVec::new(),
sig.inputs().len(),
- vec![],
span,
- vec![],
- None,
);
crate::util::dump_mir(
|_, _| Ok(()),
);
- tcx.arena.alloc(body)
+ let mut body_cache = BodyCache::new(body);
+ body_cache.ensure_predecessors();
+ tcx.arena.alloc(body_cache)
}