Remove -Zfuel.
This commit is contained in:
parent
f2abf827c1
commit
7fa021ad86
26 changed files with 19 additions and 281 deletions
|
@ -472,10 +472,6 @@ fn run_compiler(
|
||||||
linker.link(sess, codegen_backend)?
|
linker.link(sess, codegen_backend)?
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(fuel) = sess.opts.unstable_opts.print_fuel.as_deref() {
|
|
||||||
eprintln!("Fuel used by {}: {}", fuel, sess.print_fuel.load(Ordering::SeqCst));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -784,7 +784,6 @@ fn test_unstable_options_tracking_hash() {
|
||||||
tracked!(flatten_format_args, false);
|
tracked!(flatten_format_args, false);
|
||||||
tracked!(fmt_debug, FmtDebug::Shallow);
|
tracked!(fmt_debug, FmtDebug::Shallow);
|
||||||
tracked!(force_unstable_if_unmarked, true);
|
tracked!(force_unstable_if_unmarked, true);
|
||||||
tracked!(fuel, Some(("abc".to_string(), 99)));
|
|
||||||
tracked!(function_return, FunctionReturn::ThunkExtern);
|
tracked!(function_return, FunctionReturn::ThunkExtern);
|
||||||
tracked!(function_sections, Some(false));
|
tracked!(function_sections, Some(false));
|
||||||
tracked!(human_readable_cgu_names, true);
|
tracked!(human_readable_cgu_names, true);
|
||||||
|
@ -830,7 +829,6 @@ fn test_unstable_options_tracking_hash() {
|
||||||
tracked!(plt, Some(true));
|
tracked!(plt, Some(true));
|
||||||
tracked!(polonius, Polonius::Legacy);
|
tracked!(polonius, Polonius::Legacy);
|
||||||
tracked!(precise_enum_drop_elaboration, false);
|
tracked!(precise_enum_drop_elaboration, false);
|
||||||
tracked!(print_fuel, Some("abc".to_string()));
|
|
||||||
tracked!(profile_sample_use, Some(PathBuf::from("abc")));
|
tracked!(profile_sample_use, Some(PathBuf::from("abc")));
|
||||||
tracked!(profiler_runtime, "abc".to_string());
|
tracked!(profiler_runtime, "abc".to_string());
|
||||||
tracked!(regparm, Some(3));
|
tracked!(regparm, Some(3));
|
||||||
|
|
|
@ -1566,10 +1566,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
|
|
||||||
self.sess.consider_optimizing(|| self.crate_name(LOCAL_CRATE), msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Obtain all lang items of this crate and all dependencies (recursively)
|
/// Obtain all lang items of this crate and all dependencies (recursively)
|
||||||
pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
|
pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems {
|
||||||
self.get_lang_items(())
|
self.get_lang_items(())
|
||||||
|
|
|
@ -1558,10 +1558,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
|
let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
|
||||||
|
|
||||||
// This is here instead of layout because the choice must make it into metadata.
|
// This is here instead of layout because the choice must make it into metadata.
|
||||||
if is_box
|
if is_box {
|
||||||
|| !self
|
|
||||||
.consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did)))
|
|
||||||
{
|
|
||||||
flags.insert(ReprFlags::IS_LINEAR);
|
flags.insert(ReprFlags::IS_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,11 +217,6 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if !tcx.consider_optimizing(|| {
|
|
||||||
format!("{} round {}", tcx.def_path_str(def_id), round_count)
|
|
||||||
}) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace `src` by `dest` everywhere.
|
// Replace `src` by `dest` everywhere.
|
||||||
merges.insert(*src, *dest);
|
merges.insert(*src, *dest);
|
||||||
|
|
|
@ -108,10 +108,6 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
|
||||||
let parent = BasicBlock::from_usize(i);
|
let parent = BasicBlock::from_usize(i);
|
||||||
let Some(opt_data) = evaluate_candidate(tcx, body, parent) else { continue };
|
let Some(opt_data) = evaluate_candidate(tcx, body, parent) else { continue };
|
||||||
|
|
||||||
if !tcx.consider_optimizing(|| format!("EarlyOtherwiseBranch {opt_data:?}")) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
trace!("SUCCESS: found optimization possibility to apply: {opt_data:?}");
|
trace!("SUCCESS: found optimization possibility to apply: {opt_data:?}");
|
||||||
|
|
||||||
should_cleanup = true;
|
should_cleanup = true;
|
||||||
|
|
|
@ -210,12 +210,6 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?;
|
let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?;
|
||||||
self.check_mir_body(callsite, callee_body, callee_attrs, cross_crate_inlinable)?;
|
self.check_mir_body(callsite, callee_body, callee_attrs, cross_crate_inlinable)?;
|
||||||
|
|
||||||
if !self.tcx.consider_optimizing(|| {
|
|
||||||
format!("Inline {:?} into {:?}", callsite.callee, caller_body.source)
|
|
||||||
}) {
|
|
||||||
return Err("optimization fuel exhausted");
|
|
||||||
}
|
|
||||||
|
|
||||||
let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions(
|
let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
self.typing_env,
|
self.typing_env,
|
||||||
|
|
|
@ -7,8 +7,8 @@ use rustc_middle::bug;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::layout::ValidityRequirement;
|
use rustc_middle::ty::layout::ValidityRequirement;
|
||||||
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, layout};
|
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, layout};
|
||||||
use rustc_span::sym;
|
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
|
use rustc_span::{DUMMY_SP, sym};
|
||||||
|
|
||||||
use crate::simplify::simplify_duplicate_switch_targets;
|
use crate::simplify::simplify_duplicate_switch_targets;
|
||||||
use crate::take_array;
|
use crate::take_array;
|
||||||
|
@ -43,12 +43,12 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
|
||||||
match statement.kind {
|
match statement.kind {
|
||||||
StatementKind::Assign(box (_place, ref mut rvalue)) => {
|
StatementKind::Assign(box (_place, ref mut rvalue)) => {
|
||||||
if !preserve_ub_checks {
|
if !preserve_ub_checks {
|
||||||
ctx.simplify_ub_check(&statement.source_info, rvalue);
|
ctx.simplify_ub_check(rvalue);
|
||||||
}
|
}
|
||||||
ctx.simplify_bool_cmp(&statement.source_info, rvalue);
|
ctx.simplify_bool_cmp(rvalue);
|
||||||
ctx.simplify_ref_deref(&statement.source_info, rvalue);
|
ctx.simplify_ref_deref(rvalue);
|
||||||
ctx.simplify_len(&statement.source_info, rvalue);
|
ctx.simplify_len(rvalue);
|
||||||
ctx.simplify_ptr_aggregate(&statement.source_info, rvalue);
|
ctx.simplify_ptr_aggregate(rvalue);
|
||||||
ctx.simplify_cast(rvalue);
|
ctx.simplify_cast(rvalue);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -70,23 +70,8 @@ struct InstSimplifyContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||||
fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool {
|
|
||||||
self.should_simplify_custom(source_info, "Rvalue", rvalue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_simplify_custom(
|
|
||||||
&self,
|
|
||||||
source_info: &SourceInfo,
|
|
||||||
label: &str,
|
|
||||||
value: impl std::fmt::Debug,
|
|
||||||
) -> bool {
|
|
||||||
self.tcx.consider_optimizing(|| {
|
|
||||||
format!("InstSimplify - {label}: {value:?} SourceInfo: {source_info:?}")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transform boolean comparisons into logical operations.
|
/// Transform boolean comparisons into logical operations.
|
||||||
fn simplify_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
fn simplify_bool_cmp(&self, rvalue: &mut Rvalue<'tcx>) {
|
||||||
match rvalue {
|
match rvalue {
|
||||||
Rvalue::BinaryOp(op @ (BinOp::Eq | BinOp::Ne), box (a, b)) => {
|
Rvalue::BinaryOp(op @ (BinOp::Eq | BinOp::Ne), box (a, b)) => {
|
||||||
let new = match (op, self.try_eval_bool(a), self.try_eval_bool(b)) {
|
let new = match (op, self.try_eval_bool(a), self.try_eval_bool(b)) {
|
||||||
|
@ -117,9 +102,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(new) = new
|
if let Some(new) = new {
|
||||||
&& self.should_simplify(source_info, rvalue)
|
|
||||||
{
|
|
||||||
*rvalue = new;
|
*rvalue = new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,17 +117,13 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform `&(*a)` ==> `a`.
|
/// Transform `&(*a)` ==> `a`.
|
||||||
fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
fn simplify_ref_deref(&self, rvalue: &mut Rvalue<'tcx>) {
|
||||||
if let Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) = rvalue {
|
if let Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) = rvalue {
|
||||||
if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
|
if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
|
||||||
if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty {
|
if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.should_simplify(source_info, rvalue) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rvalue = Rvalue::Use(Operand::Copy(Place {
|
*rvalue = Rvalue::Use(Operand::Copy(Place {
|
||||||
local: base.local,
|
local: base.local,
|
||||||
projection: self.tcx.mk_place_elems(base.projection),
|
projection: self.tcx.mk_place_elems(base.projection),
|
||||||
|
@ -154,36 +133,24 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform `Len([_; N])` ==> `N`.
|
/// Transform `Len([_; N])` ==> `N`.
|
||||||
fn simplify_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) {
|
||||||
if let Rvalue::Len(ref place) = *rvalue {
|
if let Rvalue::Len(ref place) = *rvalue {
|
||||||
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
||||||
if let ty::Array(_, len) = *place_ty.kind() {
|
if let ty::Array(_, len) = *place_ty.kind() {
|
||||||
if !self.should_simplify(source_info, rvalue) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
|
let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
|
||||||
let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
|
let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
|
||||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
|
/// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
|
||||||
fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
|
||||||
if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
|
if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
|
||||||
{
|
{
|
||||||
let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx);
|
let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx);
|
||||||
if meta_ty.is_unit() {
|
if meta_ty.is_unit() {
|
||||||
// The mutable borrows we're holding prevent printing `rvalue` here
|
// The mutable borrows we're holding prevent printing `rvalue` here
|
||||||
if !self.should_simplify_custom(
|
|
||||||
source_info,
|
|
||||||
"Aggregate::RawPtr",
|
|
||||||
(&pointee_ty, *mutability, &fields),
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut fields = std::mem::take(fields);
|
let mut fields = std::mem::take(fields);
|
||||||
let _meta = fields.pop().unwrap();
|
let _meta = fields.pop().unwrap();
|
||||||
let data = fields.pop().unwrap();
|
let data = fields.pop().unwrap();
|
||||||
|
@ -193,10 +160,10 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
fn simplify_ub_check(&self, rvalue: &mut Rvalue<'tcx>) {
|
||||||
if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue {
|
if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue {
|
||||||
let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks());
|
let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks());
|
||||||
let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
|
let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
|
||||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,16 +251,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.tcx.consider_optimizing(|| {
|
|
||||||
format!(
|
|
||||||
"InstSimplify - Call: {:?} SourceInfo: {:?}",
|
|
||||||
(fn_def_id, fn_args),
|
|
||||||
terminator.source_info
|
|
||||||
)
|
|
||||||
}) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Ok([arg]) = take_array(args) else { return };
|
let Ok([arg]) = take_array(args) else { return };
|
||||||
let Some(arg_place) = arg.node.place() else { return };
|
let Some(arg_place) = arg.node.place() else { return };
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,11 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
let def_id = body.source.def_id();
|
|
||||||
let typing_env = body.typing_env(tcx);
|
let typing_env = body.typing_env(tcx);
|
||||||
let mut should_cleanup = false;
|
let mut should_cleanup = false;
|
||||||
for i in 0..body.basic_blocks.len() {
|
for i in 0..body.basic_blocks.len() {
|
||||||
let bbs = &*body.basic_blocks;
|
let bbs = &*body.basic_blocks;
|
||||||
let bb_idx = BasicBlock::from_usize(i);
|
let bb_idx = BasicBlock::from_usize(i);
|
||||||
if !tcx.consider_optimizing(|| format!("MatchBranchSimplification {def_id:?} ")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
match bbs[bb_idx].terminator().kind {
|
match bbs[bb_idx].terminator().kind {
|
||||||
TerminatorKind::SwitchInt {
|
TerminatorKind::SwitchInt {
|
||||||
discr: ref _discr @ (Operand::Copy(_) | Operand::Move(_)),
|
discr: ref _discr @ (Operand::Copy(_) | Operand::Move(_)),
|
||||||
|
|
|
@ -14,10 +14,9 @@ impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
|
||||||
sess.mir_opt_level() >= 4
|
sess.mir_opt_level() >= 4
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
// find basic blocks with no statement and a return terminator
|
// find basic blocks with no statement and a return terminator
|
||||||
let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks.len());
|
let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks.len());
|
||||||
let def_id = body.source.def_id();
|
|
||||||
let bbs = body.basic_blocks_mut();
|
let bbs = body.basic_blocks_mut();
|
||||||
for idx in bbs.indices() {
|
for idx in bbs.indices() {
|
||||||
if bbs[idx].statements.is_empty()
|
if bbs[idx].statements.is_empty()
|
||||||
|
@ -28,10 +27,6 @@ impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
|
||||||
}
|
}
|
||||||
|
|
||||||
for bb in bbs {
|
for bb in bbs {
|
||||||
if !tcx.consider_optimizing(|| format!("MultipleReturnTerminators {def_id:?} ")) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let TerminatorKind::Goto { target } = bb.terminator().kind {
|
if let TerminatorKind::Goto { target } = bb.terminator().kind {
|
||||||
if bbs_simple_returns.contains(target) {
|
if bbs_simple_returns.contains(target) {
|
||||||
bb.terminator_mut().kind = TerminatorKind::Return;
|
bb.terminator_mut().kind = TerminatorKind::Return;
|
||||||
|
|
|
@ -45,10 +45,6 @@ impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !tcx.consider_optimizing(|| format!("RenameReturnPlace {def_id:?}")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"`{:?}` was eligible for NRVO, making {:?} the return place",
|
"`{:?}` was eligible for NRVO, making {:?} the return place",
|
||||||
def_id, returned_local
|
def_id, returned_local
|
||||||
|
|
|
@ -26,11 +26,6 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
|
||||||
if ty.ty.needs_drop(tcx, typing_env) {
|
if ty.ty.needs_drop(tcx, typing_env) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !tcx.consider_optimizing(|| {
|
|
||||||
format!("RemoveUnneededDrops {:?}", body.source.def_id())
|
|
||||||
}) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
debug!("SUCCESS: replacing `drop` with goto({:?})", target);
|
debug!("SUCCESS: replacing `drop` with goto({:?})", target);
|
||||||
terminator.kind = TerminatorKind::Goto { target };
|
terminator.kind = TerminatorKind::Goto { target };
|
||||||
should_simplify = true;
|
should_simplify = true;
|
||||||
|
|
|
@ -17,10 +17,6 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveZsts {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tcx.consider_optimizing(|| format!("RemoveZsts - {:?}", body.source.def_id())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let typing_env = body.typing_env(tcx);
|
let typing_env = body.typing_env(tcx);
|
||||||
let local_decls = &body.local_decls;
|
let local_decls = &body.local_decls;
|
||||||
let mut replacer = Replacer { tcx, typing_env, local_decls };
|
let mut replacer = Replacer { tcx, typing_env, local_decls };
|
||||||
|
@ -94,16 +90,12 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
|
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) {
|
||||||
if let Operand::Constant(_) = operand {
|
if let Operand::Constant(_) = operand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let op_ty = operand.ty(self.local_decls, self.tcx);
|
let op_ty = operand.ty(self.local_decls, self.tcx);
|
||||||
if self.known_to_be_zst(op_ty)
|
if self.known_to_be_zst(op_ty) {
|
||||||
&& self.tcx.consider_optimizing(|| {
|
|
||||||
format!("RemoveZsts - Operand: {operand:?} Location: {loc:?}")
|
|
||||||
})
|
|
||||||
{
|
|
||||||
*operand = Operand::Constant(Box::new(self.make_zst(op_ty)))
|
*operand = Operand::Constant(Box::new(self.make_zst(op_ty)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,6 @@ impl crate::MirPass<'_> for UnreachablePropagation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tcx
|
|
||||||
.consider_optimizing(|| format!("UnreachablePropagation {:?} ", body.source.def_id()))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
patch.apply(body);
|
patch.apply(body);
|
||||||
|
|
||||||
// We do want do keep some unreachable blocks, but make them empty.
|
// We do want do keep some unreachable blocks, but make them empty.
|
||||||
|
|
|
@ -84,8 +84,6 @@ session_not_supported = not supported
|
||||||
|
|
||||||
session_octal_float_literal_not_supported = octal float literal is not supported
|
session_octal_float_literal_not_supported = octal float literal is not supported
|
||||||
|
|
||||||
session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg}
|
|
||||||
|
|
||||||
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist
|
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist
|
||||||
|
|
||||||
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist
|
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist
|
||||||
|
|
|
@ -2356,14 +2356,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||||
early_dcx.early_warn(format!("number of threads was capped at {}", parse::MAX_THREADS_CAP));
|
early_dcx.early_warn(format!("number of threads was capped at {}", parse::MAX_THREADS_CAP));
|
||||||
}
|
}
|
||||||
|
|
||||||
let fuel = unstable_opts.fuel.is_some() || unstable_opts.print_fuel.is_some();
|
|
||||||
if fuel && unstable_opts.threads > 1 {
|
|
||||||
early_dcx.early_fatal("optimization fuel is incompatible with multiple threads");
|
|
||||||
}
|
|
||||||
if fuel && cg.incremental.is_some() {
|
|
||||||
early_dcx.early_fatal("optimization fuel is incompatible with incremental compilation");
|
|
||||||
}
|
|
||||||
|
|
||||||
let incremental = cg.incremental.as_ref().map(PathBuf::from);
|
let incremental = cg.incremental.as_ref().map(PathBuf::from);
|
||||||
|
|
||||||
let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);
|
let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);
|
||||||
|
|
|
@ -463,12 +463,6 @@ pub fn report_lit_error(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(session_optimization_fuel_exhausted)]
|
|
||||||
pub(crate) struct OptimisationFuelExhausted {
|
|
||||||
pub(crate) msg: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(session_incompatible_linker_flavor)]
|
#[diag(session_incompatible_linker_flavor)]
|
||||||
#[note]
|
#[note]
|
||||||
|
|
|
@ -394,7 +394,6 @@ mod desc {
|
||||||
pub(crate) const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`";
|
pub(crate) const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`";
|
||||||
pub(crate) const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
|
pub(crate) const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
|
||||||
pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
|
pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
|
||||||
pub(crate) const parse_optimization_fuel: &str = "crate=integer";
|
|
||||||
pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
|
pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
|
||||||
pub(crate) const parse_instrument_coverage: &str = parse_bool;
|
pub(crate) const parse_instrument_coverage: &str = parse_bool;
|
||||||
pub(crate) const parse_coverage_options: &str =
|
pub(crate) const parse_coverage_options: &str =
|
||||||
|
@ -948,21 +947,6 @@ pub mod parse {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_optimization_fuel(
|
|
||||||
slot: &mut Option<(String, u64)>,
|
|
||||||
v: Option<&str>,
|
|
||||||
) -> bool {
|
|
||||||
match v {
|
|
||||||
None => false,
|
|
||||||
Some(s) => {
|
|
||||||
let [crate_name, fuel] = *s.split('=').collect::<Vec<_>>() else { return false };
|
|
||||||
let Ok(fuel) = fuel.parse::<u64>() else { return false };
|
|
||||||
*slot = Some((crate_name.to_string(), fuel));
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn parse_unpretty(slot: &mut Option<String>, v: Option<&str>) -> bool {
|
pub(crate) fn parse_unpretty(slot: &mut Option<String>, v: Option<&str>) -> bool {
|
||||||
match v {
|
match v {
|
||||||
None => false,
|
None => false,
|
||||||
|
@ -1794,8 +1778,6 @@ options! {
|
||||||
`shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"),
|
`shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"),
|
||||||
force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
|
force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
|
||||||
"force all crates to be `rustc_private` unstable (default: no)"),
|
"force all crates to be `rustc_private` unstable (default: no)"),
|
||||||
fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
|
|
||||||
"set the optimization fuel quota for a crate"),
|
|
||||||
function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED],
|
function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED],
|
||||||
"replace returns with jumps to `__x86_return_thunk` (default: `keep`)"),
|
"replace returns with jumps to `__x86_return_thunk` (default: `keep`)"),
|
||||||
function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||||
|
@ -1978,8 +1960,6 @@ options! {
|
||||||
#[rustc_lint_opt_deny_field_access("use `Session::print_codegen_stats` instead of this field")]
|
#[rustc_lint_opt_deny_field_access("use `Session::print_codegen_stats` instead of this field")]
|
||||||
print_codegen_stats: bool = (false, parse_bool, [UNTRACKED],
|
print_codegen_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"print codegen statistics (default: no)"),
|
"print codegen statistics (default: no)"),
|
||||||
print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
|
|
||||||
"make rustc print the total optimization fuel used by a crate"),
|
|
||||||
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
|
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"print the LLVM optimization passes being run (default: no)"),
|
"print the LLVM optimization passes being run (default: no)"),
|
||||||
print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
|
print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::atomic::Ordering::SeqCst;
|
|
||||||
use std::{env, fmt, io};
|
use std::{env, fmt, io};
|
||||||
|
|
||||||
use rustc_data_structures::flock;
|
use rustc_data_structures::flock;
|
||||||
|
@ -12,7 +11,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||||
use rustc_data_structures::jobserver::{self, Client};
|
use rustc_data_structures::jobserver::{self, Client};
|
||||||
use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
|
use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
|
||||||
use rustc_data_structures::sync::{
|
use rustc_data_structures::sync::{
|
||||||
AtomicU64, DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock,
|
DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock,
|
||||||
};
|
};
|
||||||
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
|
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
|
@ -49,13 +48,6 @@ use crate::parse::{ParseSess, add_feature_diagnostics};
|
||||||
use crate::search_paths::SearchPath;
|
use crate::search_paths::SearchPath;
|
||||||
use crate::{errors, filesearch, lint};
|
use crate::{errors, filesearch, lint};
|
||||||
|
|
||||||
struct OptimizationFuel {
|
|
||||||
/// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`.
|
|
||||||
remaining: u64,
|
|
||||||
/// We're rejecting all further optimizations.
|
|
||||||
out_of_fuel: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The behavior of the CTFE engine when an error occurs with regards to backtraces.
|
/// The behavior of the CTFE engine when an error occurs with regards to backtraces.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum CtfeBacktrace {
|
pub enum CtfeBacktrace {
|
||||||
|
@ -163,12 +155,6 @@ pub struct Session {
|
||||||
/// Data about code being compiled, gathered during compilation.
|
/// Data about code being compiled, gathered during compilation.
|
||||||
pub code_stats: CodeStats,
|
pub code_stats: CodeStats,
|
||||||
|
|
||||||
/// Tracks fuel info if `-zfuel=crate=n` is specified.
|
|
||||||
optimization_fuel: Lock<OptimizationFuel>,
|
|
||||||
|
|
||||||
/// Always set to zero and incremented so that we can print fuel expended by a crate.
|
|
||||||
pub print_fuel: AtomicU64,
|
|
||||||
|
|
||||||
/// Loaded up early on in the initialization of this `Session` to avoid
|
/// Loaded up early on in the initialization of this `Session` to avoid
|
||||||
/// false positives about a job server in our environment.
|
/// false positives about a job server in our environment.
|
||||||
pub jobserver: Client,
|
pub jobserver: Client,
|
||||||
|
@ -532,41 +518,6 @@ impl Session {
|
||||||
self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir())
|
self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n.
|
|
||||||
/// This expends fuel if applicable, and records fuel if applicable.
|
|
||||||
pub fn consider_optimizing(
|
|
||||||
&self,
|
|
||||||
get_crate_name: impl Fn() -> Symbol,
|
|
||||||
msg: impl Fn() -> String,
|
|
||||||
) -> bool {
|
|
||||||
let mut ret = true;
|
|
||||||
if let Some((ref c, _)) = self.opts.unstable_opts.fuel {
|
|
||||||
if c == get_crate_name().as_str() {
|
|
||||||
assert_eq!(self.threads(), 1);
|
|
||||||
let mut fuel = self.optimization_fuel.lock();
|
|
||||||
ret = fuel.remaining != 0;
|
|
||||||
if fuel.remaining == 0 && !fuel.out_of_fuel {
|
|
||||||
if self.dcx().can_emit_warnings() {
|
|
||||||
// We only call `msg` in case we can actually emit warnings.
|
|
||||||
// Otherwise, this could cause a `must_produce_diag` ICE
|
|
||||||
// (issue #79546).
|
|
||||||
self.dcx().emit_warn(errors::OptimisationFuelExhausted { msg: msg() });
|
|
||||||
}
|
|
||||||
fuel.out_of_fuel = true;
|
|
||||||
} else if fuel.remaining > 0 {
|
|
||||||
fuel.remaining -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(ref c) = self.opts.unstable_opts.print_fuel {
|
|
||||||
if c == get_crate_name().as_str() {
|
|
||||||
assert_eq!(self.threads(), 1);
|
|
||||||
self.print_fuel.fetch_add(1, SeqCst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Is this edition 2015?
|
/// Is this edition 2015?
|
||||||
pub fn is_rust_2015(&self) -> bool {
|
pub fn is_rust_2015(&self) -> bool {
|
||||||
self.edition().is_rust_2015()
|
self.edition().is_rust_2015()
|
||||||
|
@ -1097,12 +1048,6 @@ pub fn build_session(
|
||||||
Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
|
Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
|
||||||
};
|
};
|
||||||
|
|
||||||
let optimization_fuel = Lock::new(OptimizationFuel {
|
|
||||||
remaining: sopts.unstable_opts.fuel.as_ref().map_or(0, |&(_, i)| i),
|
|
||||||
out_of_fuel: false,
|
|
||||||
});
|
|
||||||
let print_fuel = AtomicU64::new(0);
|
|
||||||
|
|
||||||
let prof = SelfProfilerRef::new(
|
let prof = SelfProfilerRef::new(
|
||||||
self_profiler,
|
self_profiler,
|
||||||
sopts.unstable_opts.time_passes.then(|| sopts.unstable_opts.time_passes_format),
|
sopts.unstable_opts.time_passes.then(|| sopts.unstable_opts.time_passes_format),
|
||||||
|
@ -1130,8 +1075,6 @@ pub fn build_session(
|
||||||
incr_comp_session: RwLock::new(IncrCompSession::NotInitialized),
|
incr_comp_session: RwLock::new(IncrCompSession::NotInitialized),
|
||||||
prof,
|
prof,
|
||||||
code_stats: Default::default(),
|
code_stats: Default::default(),
|
||||||
optimization_fuel,
|
|
||||||
print_fuel,
|
|
||||||
jobserver: jobserver::client(),
|
jobserver: jobserver::client(),
|
||||||
lint_store: None,
|
lint_store: None,
|
||||||
registered_lints: false,
|
registered_lints: false,
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
//@ run-pass
|
|
||||||
|
|
||||||
#![crate_name="foo"]
|
|
||||||
|
|
||||||
use std::mem::size_of;
|
|
||||||
|
|
||||||
//@ compile-flags: -Z fuel=foo=0
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
struct S1(u8, u16, u8);
|
|
||||||
#[allow(dead_code)]
|
|
||||||
struct S2(u8, u16, u8);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
assert_eq!(size_of::<S1>(), 6);
|
|
||||||
assert_eq!(size_of::<S2>(), 6);
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
warning: optimization-fuel-exhausted: Reorder fields of "S1"
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
//@ run-pass
|
|
||||||
|
|
||||||
#![crate_name="foo"]
|
|
||||||
|
|
||||||
use std::mem::size_of;
|
|
||||||
|
|
||||||
//@ compile-flags: -Z fuel=foo=1
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
struct S1(u8, u16, u8);
|
|
||||||
#[allow(dead_code)]
|
|
||||||
struct S2(u8, u16, u8);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let optimized = (size_of::<S1>() == 4) as usize
|
|
||||||
+(size_of::<S2>() == 4) as usize;
|
|
||||||
assert_eq!(optimized, 1);
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
warning: optimization-fuel-exhausted: Reorder fields of "S2"
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#![crate_name="foo"]
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
// (#55495: The --error-format is to sidestep an issue in our test harness)
|
|
||||||
//@ compile-flags: -C opt-level=0 --error-format human -Z print-fuel=foo
|
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
struct S1(u8, u16, u8);
|
|
||||||
struct S2(u8, u16, u8);
|
|
||||||
struct S3(u8, u16, u8);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
Fuel used by foo: 3
|
|
|
@ -1,8 +0,0 @@
|
||||||
// Regression test for the ICE described in #79546.
|
|
||||||
|
|
||||||
//@ compile-flags: --cap-lints=allow -Zfuel=issue79546=0
|
|
||||||
//@ check-pass
|
|
||||||
#![crate_name="issue79546"]
|
|
||||||
|
|
||||||
struct S;
|
|
||||||
fn main() {}
|
|
Loading…
Add table
Add a link
Reference in a new issue