Auto merge of #125853 - tesuji:promote-fail-fast, r=cjgillot
promote_consts: some clean-up after experimenting This is some clean-up after experimenting in #125916, Prefer to review commit-by-commit.
This commit is contained in:
commit
5ced3dad57
@ -441,7 +441,7 @@ pub fn mplace_to_ref(
|
|||||||
|
|
||||||
/// Take an operand, representing a pointer, and dereference it to a place.
|
/// Take an operand, representing a pointer, and dereference it to a place.
|
||||||
/// Corresponds to the `*` operator in Rust.
|
/// Corresponds to the `*` operator in Rust.
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "trace")]
|
||||||
pub fn deref_pointer(
|
pub fn deref_pointer(
|
||||||
&self,
|
&self,
|
||||||
src: &impl Readable<'tcx, M::Provenance>,
|
src: &impl Readable<'tcx, M::Provenance>,
|
||||||
@ -533,7 +533,7 @@ pub fn local_to_place(
|
|||||||
|
|
||||||
/// Computes a place. You should only use this if you intend to write into this
|
/// Computes a place. You should only use this if you intend to write into this
|
||||||
/// place; for reading, a more efficient alternative is `eval_place_to_op`.
|
/// place; for reading, a more efficient alternative is `eval_place_to_op`.
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "trace")]
|
||||||
pub fn eval_place(
|
pub fn eval_place(
|
||||||
&self,
|
&self,
|
||||||
mir_place: mir::Place<'tcx>,
|
mir_place: mir::Place<'tcx>,
|
||||||
@ -570,7 +570,7 @@ pub fn eval_place(
|
|||||||
|
|
||||||
/// Write an immediate to a place
|
/// Write an immediate to a place
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "trace")]
|
||||||
pub fn write_immediate(
|
pub fn write_immediate(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: Immediate<M::Provenance>,
|
src: Immediate<M::Provenance>,
|
||||||
@ -808,7 +808,7 @@ pub fn copy_op(
|
|||||||
/// Copies the data from an operand to a place.
|
/// Copies the data from an operand to a place.
|
||||||
/// `allow_transmute` indicates whether the layouts may disagree.
|
/// `allow_transmute` indicates whether the layouts may disagree.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "trace")]
|
||||||
fn copy_op_inner(
|
fn copy_op_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: &impl Readable<'tcx, M::Provenance>,
|
src: &impl Readable<'tcx, M::Provenance>,
|
||||||
@ -837,7 +837,7 @@ fn copy_op_inner(
|
|||||||
/// `allow_transmute` indicates whether the layouts may disagree.
|
/// `allow_transmute` indicates whether the layouts may disagree.
|
||||||
/// Also, if you use this you are responsible for validating that things get copied at the
|
/// Also, if you use this you are responsible for validating that things get copied at the
|
||||||
/// right type.
|
/// right type.
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "trace")]
|
||||||
fn copy_op_no_validate(
|
fn copy_op_no_validate(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: &impl Readable<'tcx, M::Provenance>,
|
src: &impl Readable<'tcx, M::Provenance>,
|
||||||
@ -914,7 +914,7 @@ fn copy_op_no_validate(
|
|||||||
/// If the place currently refers to a local that doesn't yet have a matching allocation,
|
/// If the place currently refers to a local that doesn't yet have a matching allocation,
|
||||||
/// create such an allocation.
|
/// create such an allocation.
|
||||||
/// This is essentially `force_to_memplace`.
|
/// This is essentially `force_to_memplace`.
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "trace")]
|
||||||
pub fn force_allocation(
|
pub fn force_allocation(
|
||||||
&mut self,
|
&mut self,
|
||||||
place: &PlaceTy<'tcx, M::Provenance>,
|
place: &PlaceTy<'tcx, M::Provenance>,
|
||||||
|
@ -60,7 +60,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
let ccx = ConstCx::new(tcx, body);
|
let ccx = ConstCx::new(tcx, body);
|
||||||
let (mut temps, all_candidates) = collect_temps_and_candidates(&ccx);
|
let (mut temps, all_candidates) = collect_temps_and_candidates(&ccx);
|
||||||
|
|
||||||
let promotable_candidates = validate_candidates(&ccx, &mut temps, &all_candidates);
|
let promotable_candidates = validate_candidates(&ccx, &mut temps, all_candidates);
|
||||||
|
|
||||||
let promoted = promote_candidates(body, tcx, temps, promotable_candidates);
|
let promoted = promote_candidates(body, tcx, temps, promotable_candidates);
|
||||||
self.promoted_fragments.set(promoted);
|
self.promoted_fragments.set(promoted);
|
||||||
@ -98,8 +98,8 @@ struct Collector<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn visit_local(&mut self, index: Local, context: PlaceContext, location: Location) {
|
fn visit_local(&mut self, index: Local, context: PlaceContext, location: Location) {
|
||||||
debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location);
|
|
||||||
// We're only interested in temporaries and the return place
|
// We're only interested in temporaries and the return place
|
||||||
match self.ccx.body.local_kind(index) {
|
match self.ccx.body.local_kind(index) {
|
||||||
LocalKind::Arg => return,
|
LocalKind::Arg => return,
|
||||||
@ -111,20 +111,15 @@ fn visit_local(&mut self, index: Local, context: PlaceContext, location: Locatio
|
|||||||
// then it's constant and thus drop is noop.
|
// then it's constant and thus drop is noop.
|
||||||
// Non-uses are also irrelevant.
|
// Non-uses are also irrelevant.
|
||||||
if context.is_drop() || !context.is_use() {
|
if context.is_drop() || !context.is_use() {
|
||||||
debug!(
|
debug!(is_drop = context.is_drop(), is_use = context.is_use());
|
||||||
"visit_local: context.is_drop={:?} context.is_use={:?}",
|
|
||||||
context.is_drop(),
|
|
||||||
context.is_use(),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let temp = &mut self.temps[index];
|
let temp = &mut self.temps[index];
|
||||||
debug!("visit_local: temp={:?}", temp);
|
debug!(?temp);
|
||||||
*temp = match *temp {
|
*temp = match *temp {
|
||||||
TempState::Undefined => match context {
|
TempState::Undefined => match context {
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::Store)
|
PlaceContext::MutatingUse(MutatingUseContext::Store | MutatingUseContext::Call) => {
|
||||||
| PlaceContext::MutatingUse(MutatingUseContext::Call) => {
|
|
||||||
TempState::Defined { location, uses: 0, valid: Err(()) }
|
TempState::Defined { location, uses: 0, valid: Err(()) }
|
||||||
}
|
}
|
||||||
_ => TempState::Unpromotable,
|
_ => TempState::Unpromotable,
|
||||||
@ -137,7 +132,7 @@ fn visit_local(&mut self, index: Local, context: PlaceContext, location: Locatio
|
|||||||
| PlaceContext::NonMutatingUse(_) => true,
|
| PlaceContext::NonMutatingUse(_) => true,
|
||||||
PlaceContext::MutatingUse(_) | PlaceContext::NonUse(_) => false,
|
PlaceContext::MutatingUse(_) | PlaceContext::NonUse(_) => false,
|
||||||
};
|
};
|
||||||
debug!("visit_local: allowed_use={:?}", allowed_use);
|
debug!(?allowed_use);
|
||||||
if allowed_use {
|
if allowed_use {
|
||||||
*uses += 1;
|
*uses += 1;
|
||||||
return;
|
return;
|
||||||
@ -146,6 +141,7 @@ fn visit_local(&mut self, index: Local, context: PlaceContext, location: Locatio
|
|||||||
}
|
}
|
||||||
TempState::Unpromotable | TempState::PromotedOut => TempState::Unpromotable,
|
TempState::Unpromotable | TempState::PromotedOut => TempState::Unpromotable,
|
||||||
};
|
};
|
||||||
|
debug!(?temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||||
@ -695,15 +691,12 @@ fn validate_call(
|
|||||||
fn validate_candidates(
|
fn validate_candidates(
|
||||||
ccx: &ConstCx<'_, '_>,
|
ccx: &ConstCx<'_, '_>,
|
||||||
temps: &mut IndexSlice<Local, TempState>,
|
temps: &mut IndexSlice<Local, TempState>,
|
||||||
candidates: &[Candidate],
|
mut candidates: Vec<Candidate>,
|
||||||
) -> Vec<Candidate> {
|
) -> Vec<Candidate> {
|
||||||
let mut validator = Validator { ccx, temps, promotion_safe_blocks: None };
|
let mut validator = Validator { ccx, temps, promotion_safe_blocks: None };
|
||||||
|
|
||||||
|
candidates.retain(|&candidate| validator.validate_candidate(candidate).is_ok());
|
||||||
candidates
|
candidates
|
||||||
.iter()
|
|
||||||
.copied()
|
|
||||||
.filter(|&candidate| validator.validate_candidate(candidate).is_ok())
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Promoter<'a, 'tcx> {
|
struct Promoter<'a, 'tcx> {
|
||||||
@ -972,7 +965,12 @@ fn promote_candidates<'tcx>(
|
|||||||
candidates: Vec<Candidate>,
|
candidates: Vec<Candidate>,
|
||||||
) -> IndexVec<Promoted, Body<'tcx>> {
|
) -> IndexVec<Promoted, Body<'tcx>> {
|
||||||
// Visit candidates in reverse, in case they're nested.
|
// Visit candidates in reverse, in case they're nested.
|
||||||
debug!("promote_candidates({:?})", candidates);
|
debug!(promote_candidates = ?candidates);
|
||||||
|
|
||||||
|
// eagerly fail fast
|
||||||
|
if candidates.is_empty() {
|
||||||
|
return IndexVec::new();
|
||||||
|
}
|
||||||
|
|
||||||
let mut promotions = IndexVec::new();
|
let mut promotions = IndexVec::new();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ alloc = { path = "../alloc" }
|
|||||||
core = { path = "../core" }
|
core = { path = "../core" }
|
||||||
unwind = { path = "../unwind" }
|
unwind = { path = "../unwind" }
|
||||||
compiler_builtins = "0.1.0"
|
compiler_builtins = "0.1.0"
|
||||||
cfg-if = "1.0"
|
cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
|
||||||
|
|
||||||
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
|
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
|
||||||
libc = { version = "0.2", default-features = false }
|
libc = { version = "0.2", default-features = false }
|
||||||
|
Loading…
Reference in New Issue
Block a user