Differentiate between the availability of ctfe MIR and runtime MIR
This commit is contained in:
parent
cccd40f9b5
commit
1f5fb3e056
8 changed files with 38 additions and 29 deletions
|
@ -1160,9 +1160,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_ctfe_mir_available(&self, id: DefIndex) -> bool {
|
||||||
|
self.root.tables.mir_for_ctfe.get(self, id).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
fn is_item_mir_available(&self, id: DefIndex) -> bool {
|
fn is_item_mir_available(&self, id: DefIndex) -> bool {
|
||||||
self.root.tables.mir.get(self, id).is_some()
|
self.root.tables.mir.get(self, id).is_some()
|
||||||
|| self.root.tables.mir_for_ctfe.get(self, id).is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId {
|
fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId {
|
||||||
|
|
|
@ -146,6 +146,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
||||||
impl_parent => { cdata.get_parent_impl(def_id.index) }
|
impl_parent => { cdata.get_parent_impl(def_id.index) }
|
||||||
trait_of_item => { cdata.get_trait_of_item(def_id.index) }
|
trait_of_item => { cdata.get_trait_of_item(def_id.index) }
|
||||||
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
|
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
|
||||||
|
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
|
||||||
|
|
||||||
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
|
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
|
||||||
is_panic_runtime => { cdata.root.panic_runtime }
|
is_panic_runtime => { cdata.root.panic_runtime }
|
||||||
|
|
|
@ -444,7 +444,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
def: ty::WithOptConstParam<DefId>,
|
def: ty::WithOptConstParam<DefId>,
|
||||||
) -> &'tcx Body<'tcx> {
|
) -> &'tcx Body<'tcx> {
|
||||||
if let Some((did, param_did)) = def.as_const_arg() {
|
if let Some((did, param_did)) = def.as_const_arg() {
|
||||||
self.optimized_mir_of_const_arg((did, param_did))
|
self.mir_for_ctfe_of_const_arg((did, param_did))
|
||||||
} else {
|
} else {
|
||||||
self.optimized_mir(def.did)
|
self.optimized_mir(def.did)
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,15 +346,6 @@ rustc_queries! {
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: now that we have `mir_for_ctfe_of_const_arg` can we get
|
|
||||||
// rid of this query?
|
|
||||||
query optimized_mir_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
|
|
||||||
desc {
|
|
||||||
|tcx| "optimizing MIR for the const argument `{}`",
|
|
||||||
tcx.def_path_str(key.0.to_def_id())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns coverage summary info for a function, after executing the `InstrumentCoverage`
|
/// Returns coverage summary info for a function, after executing the `InstrumentCoverage`
|
||||||
/// MIR pass (assuming the -Zinstrument-coverage option is enabled).
|
/// MIR pass (assuming the -Zinstrument-coverage option is enabled).
|
||||||
query coverageinfo(key: DefId) -> mir::CoverageInfo {
|
query coverageinfo(key: DefId) -> mir::CoverageInfo {
|
||||||
|
@ -944,6 +935,10 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
Codegen {
|
Codegen {
|
||||||
|
// FIXME: remove after figuring out how to make miri able to detect non-Rust function calls
|
||||||
|
query is_ctfe_mir_available(key: DefId) -> bool {
|
||||||
|
desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) }
|
||||||
|
}
|
||||||
query is_mir_available(key: DefId) -> bool {
|
query is_mir_available(key: DefId) -> bool {
|
||||||
desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "checking if item has mir available: `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -3010,7 +3010,16 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
|
/// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
|
||||||
pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
|
pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
|
||||||
match instance {
|
match instance {
|
||||||
ty::InstanceDef::Item(def) => self.optimized_mir_opt_const_arg(def),
|
ty::InstanceDef::Item(def) => match self.def_kind(def.did) {
|
||||||
|
DefKind::Const
|
||||||
|
| DefKind::Static
|
||||||
|
| DefKind::AssocConst
|
||||||
|
| DefKind::Ctor(..)
|
||||||
|
| DefKind::AnonConst => self.mir_for_ctfe_opt_const_arg(def),
|
||||||
|
// If the caller wants `mir_for_ctfe` they should not be using `instance_mir`, so
|
||||||
|
// we'll assume const fn also wants the optimized version.
|
||||||
|
_ => self.optimized_mir_opt_const_arg(def),
|
||||||
|
},
|
||||||
ty::InstanceDef::VtableShim(..)
|
ty::InstanceDef::VtableShim(..)
|
||||||
| ty::InstanceDef::ReifyShim(..)
|
| ty::InstanceDef::ReifyShim(..)
|
||||||
| ty::InstanceDef::Intrinsic(..)
|
| ty::InstanceDef::Intrinsic(..)
|
||||||
|
|
|
@ -479,7 +479,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
}
|
}
|
||||||
match instance {
|
match instance {
|
||||||
ty::InstanceDef::Item(def) => {
|
ty::InstanceDef::Item(def) => {
|
||||||
if self.tcx.is_mir_available(def.did) {
|
if self.tcx.is_ctfe_mir_available(def.did) {
|
||||||
Ok(self.tcx.mir_for_ctfe_opt_const_arg(def))
|
Ok(self.tcx.mir_for_ctfe_opt_const_arg(def))
|
||||||
} else {
|
} else {
|
||||||
throw_unsup!(NoMirFor(def.did))
|
throw_unsup!(NoMirFor(def.did))
|
||||||
|
|
|
@ -54,10 +54,18 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit early when there is no MIR available.
|
// Exit early when there is no MIR available.
|
||||||
if !tcx.is_mir_available(def_id) {
|
let context = tcx.hir().body_const_context(def_id.expect_local());
|
||||||
|
match context {
|
||||||
|
None if !tcx.is_mir_available(def_id) => {
|
||||||
debug!("unused_generic_params: (no mir available) def_id={:?}", def_id);
|
debug!("unused_generic_params: (no mir available) def_id={:?}", def_id);
|
||||||
return FiniteBitSet::new_empty();
|
return FiniteBitSet::new_empty();
|
||||||
}
|
}
|
||||||
|
Some(_) if !tcx.is_ctfe_mir_available(def_id) => {
|
||||||
|
debug!("unused_generic_params: (no ctfe mir available) def_id={:?}", def_id);
|
||||||
|
return FiniteBitSet::new_empty();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
// Create a bitset with N rightmost ones for each parameter.
|
// Create a bitset with N rightmost ones for each parameter.
|
||||||
let generics_count: u32 =
|
let generics_count: u32 =
|
||||||
|
@ -69,8 +77,11 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
|
||||||
debug!("unused_generic_params: (after default) unused_parameters={:?}", unused_parameters);
|
debug!("unused_generic_params: (after default) unused_parameters={:?}", unused_parameters);
|
||||||
|
|
||||||
// Visit MIR and accumululate used generic parameters.
|
// Visit MIR and accumululate used generic parameters.
|
||||||
let body = match tcx.hir().body_const_context(def_id.expect_local()) {
|
let body = match context {
|
||||||
None => tcx.optimized_mir(def_id),
|
None => tcx.optimized_mir(def_id),
|
||||||
|
// FIXME(oli-obk): since this is solely used for codegen (I think?), should we keep using
|
||||||
|
// the optimized MIR for `const fn`? Need to adjust the above `is_mir_available` check
|
||||||
|
// in that case.
|
||||||
Some(_) => tcx.mir_for_ctfe(def_id),
|
Some(_) => tcx.mir_for_ctfe(def_id),
|
||||||
};
|
};
|
||||||
let mut vis = MarkUsedGenericParams { tcx, def_id, unused_parameters: &mut unused_parameters };
|
let mut vis = MarkUsedGenericParams { tcx, def_id, unused_parameters: &mut unused_parameters };
|
||||||
|
|
|
@ -74,8 +74,8 @@ pub(crate) fn provide(providers: &mut Providers) {
|
||||||
mir_for_ctfe,
|
mir_for_ctfe,
|
||||||
mir_for_ctfe_of_const_arg,
|
mir_for_ctfe_of_const_arg,
|
||||||
optimized_mir,
|
optimized_mir,
|
||||||
optimized_mir_of_const_arg,
|
|
||||||
is_mir_available,
|
is_mir_available,
|
||||||
|
is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did),
|
||||||
promoted_mir: |tcx, def_id| {
|
promoted_mir: |tcx, def_id| {
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||||
|
@ -518,22 +518,12 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx Body<'tcx> {
|
fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx Body<'tcx> {
|
||||||
let did = did.expect_local();
|
let did = did.expect_local();
|
||||||
if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) {
|
if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) {
|
||||||
tcx.optimized_mir_of_const_arg(def)
|
tcx.mir_for_ctfe_of_const_arg(def)
|
||||||
} else {
|
} else {
|
||||||
tcx.arena.alloc(inner_optimized_mir(tcx, ty::WithOptConstParam::unknown(did)))
|
tcx.arena.alloc(inner_optimized_mir(tcx, ty::WithOptConstParam::unknown(did)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn optimized_mir_of_const_arg<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
(did, param_did): (LocalDefId, DefId),
|
|
||||||
) -> &'tcx Body<'tcx> {
|
|
||||||
tcx.arena.alloc(inner_optimized_mir(
|
|
||||||
tcx,
|
|
||||||
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inner_optimized_mir(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
fn inner_optimized_mir(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
||||||
if tcx.is_constructor(def.did.to_def_id()) {
|
if tcx.is_constructor(def.did.to_def_id()) {
|
||||||
// There's no reason to run all of the MIR passes on constructors when
|
// There's no reason to run all of the MIR passes on constructors when
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue