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:
bors 2024-06-21 16:00:14 +00:00
commit 5ced3dad57
3 changed files with 22 additions and 24 deletions

View file

@ -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>,

View file

@ -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();

View file

@ -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 }