Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump optimization from mir_opt_level 2 to 3 and 3 to 4 and make "release" be level 2 by default #82736

Merged
merged 12 commits into from
Mar 6, 2021
Merged
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(link_only, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(mir_emit_retag, true);
tracked!(mir_opt_level, 3);
tracked!(mir_opt_level, Some(4));
tracked!(mutable_noalias, true);
tracked!(new_llvm_pass_manager, true);
tracked!(no_codegen, true);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/const_goto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct ConstGoto;

impl<'tcx> MirPass<'tcx> for ConstGoto {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
if tcx.sess.mir_opt_level() < 4 {
return;
}
trace!("Running ConstGoto on {:?}", body.source);
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_mir/src/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None;
}

if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 {
if self.tcx.sess.mir_opt_level() >= 4 {
self.eval_rvalue_with_identities(rvalue, place)
} else {
self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place))
Expand Down Expand Up @@ -903,7 +903,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {

/// Returns `true` if and only if this `op` should be const-propagated into.
fn should_const_prop(&mut self, op: &OpTy<'tcx>) -> bool {
let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level;
let mir_opt_level = self.tcx.sess.mir_opt_level();

if mir_opt_level == 0 {
return false;
Expand Down Expand Up @@ -1071,9 +1071,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
self.super_operand(operand, location);

// Only const prop copies and moves on `mir_opt_level=2` as doing so
// Only const prop copies and moves on `mir_opt_level=3` as doing so
// currently slightly increases compile time in some cases.
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
if self.tcx.sess.mir_opt_level() >= 3 {
self.propagate_operand(operand)
}
}
Expand Down Expand Up @@ -1253,7 +1253,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
TerminatorKind::SwitchInt { ref mut discr, .. } => {
// FIXME: This is currently redundant with `visit_operand`, but sadly
// always visiting operands currently causes a perf regression in LLVM codegen, so
// `visit_operand` currently only runs for propagates places for `mir_opt_level=3`.
// `visit_operand` currently only runs for propagates places for `mir_opt_level=4`.
self.propagate_operand(discr)
}
// None of these have Operands to const-propagate.
Expand All @@ -1272,7 +1272,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
// Every argument in our function calls have already been propagated in `visit_operand`.
//
// NOTE: because LLVM codegen gives slight performance regressions with it, so this is
// gated on `mir_opt_level=2`.
// gated on `mir_opt_level=3`.
TerminatorKind::Call { .. } => {}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/deduplicate_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct DeduplicateBlocks;

impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
if tcx.sess.mir_opt_level() < 4 {
return;
}
debug!("Running DeduplicateBlocks on `{:?}`", body.source);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir/src/transform/dest_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ pub struct DestinationPropagation;

impl<'tcx> MirPass<'tcx> for DestinationPropagation {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove
// Only run at mir-opt-level=3 or higher for now (we don't fix up debuginfo and remove
// storage statements at the moment).
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
if tcx.sess.mir_opt_level() < 3 {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/early_otherwise_branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct EarlyOtherwiseBranch;

impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 2 {
if tcx.sess.mir_opt_level() < 3 {
return;
}
trace!("running EarlyOtherwiseBranch on {:?}", body.source);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ crate fn is_enabled(tcx: TyCtxt<'_>) -> bool {
return enabled;
}

tcx.sess.opts.debugging_opts.mir_opt_level >= 2
tcx.sess.mir_opt_level() >= 3
}

impl<'tcx> MirPass<'tcx> for Inline {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/match_branches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub struct MatchBranchSimplification;

impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
if tcx.sess.mir_opt_level() < 3 {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
}

fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level;
let mir_opt_level = tcx.sess.mir_opt_level();

// Lowering generator control-flow and variables has to happen before we do anything else
// to them. We run some optimizations before that, because they may be harder to do on the state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct MultipleReturnTerminators;

impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
if tcx.sess.mir_opt_level() < 4 {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/nrvo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct RenameReturnPlace;

impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
if tcx.sess.mir_opt_level() == 0 {
return;
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir/src/transform/unreachable_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub struct UnreachablePropagation;

impl MirPass<'_> for UnreachablePropagation {
fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
// Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt
if tcx.sess.mir_opt_level() < 4 {
// Enable only under -Zmir-opt-level=4 as in some cases (check the deeply-nested-opt
// perf benchmark) LLVM may spend quite a lot of time optimizing the generated code.
return;
}
Expand Down
30 changes: 16 additions & 14 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1938,21 +1938,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
Some(SymbolManglingVersion::V0) => {}
}

if debugging_opts.mir_opt_level > 1 {
// Functions inlined during MIR transform can, at best, make it impossible to
// effectively cover inlined functions, and, at worst, break coverage map generation
// during LLVM codegen. For example, function counter IDs are only unique within a
// function. Inlining after these counters are injected can produce duplicate counters,
// resulting in an invalid coverage map (and ICE); so this option combination is not
// allowed.
early_warn(
error_format,
&format!(
"`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \
if let Some(mir_opt_level) = debugging_opts.mir_opt_level {
if mir_opt_level > 1 {
// Functions inlined during MIR transform can, at best, make it impossible to
// effectively cover inlined functions, and, at worst, break coverage map generation
// during LLVM codegen. For example, function counter IDs are only unique within a
// function. Inlining after these counters are injected can produce duplicate counters,
// resulting in an invalid coverage map (and ICE); so this option combination is not
// allowed.
early_warn(
error_format,
&format!(
"`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \
is incompatible with `-Z instrument-coverage`. Inlining will be disabled.",
debugging_opts.mir_opt_level,
),
);
mir_opt_level,
),
);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,8 +999,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
(default: no)"),
mir_opt_level: usize = (1, parse_uint, [TRACKED],
"MIR optimization level (0-3; default: 1)"),
mir_opt_level: Option<usize> = (None, parse_opt_uint, [TRACKED],
"MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
mutable_noalias: bool = (false, parse_bool, [TRACKED],
"emit noalias metadata for mutable references (default: no)"),
new_llvm_pass_manager: bool = (false, parse_bool, [TRACKED],
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,12 @@ impl Session {
pub fn binary_dep_depinfo(&self) -> bool {
self.opts.debugging_opts.binary_dep_depinfo
}
pub fn mir_opt_level(&self) -> usize {
self.opts
.debugging_opts
.mir_opt_level
.unwrap_or_else(|| if self.opts.optimize != config::OptLevel::No { 2 } else { 1 })
}

/// Gets the features enabled for the current compilation session.
/// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents
Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen/issue-59352.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// Once the optimizer can do that, mir-opt/issues/issue-59352.rs will need to be updated and this
// test case should be removed as it will become redundant.

// mir-opt-level=2 enables inlining and enables LLVM to optimize away the unreachable panic call.
// compile-flags: -O -Z mir-opt-level=2
// mir-opt-level=3 enables inlining and enables LLVM to optimize away the unreachable panic call.
// compile-flags: -O -Z mir-opt-level=3

#![crate_type = "rlib"]

Expand Down
2 changes: 1 addition & 1 deletion src/test/codegen/naked-noinline.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Checks that naked functions are never inlined.
// compile-flags: -O -Zmir-opt-level=2
// compile-flags: -O -Zmir-opt-level=3
// ignore-wasm32
#![crate_type = "lib"]
#![feature(asm)]
Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen/sanitizer-no-sanitize-inlining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// needs-sanitizer-address
// needs-sanitizer-leak
// revisions: ASAN LSAN
//[ASAN] compile-flags: -Zsanitizer=address -C opt-level=3 -Z mir-opt-level=3
//[LSAN] compile-flags: -Zsanitizer=leak -C opt-level=3 -Z mir-opt-level=3
//[ASAN] compile-flags: -Zsanitizer=address -C opt-level=3 -Z mir-opt-level=4
//[LSAN] compile-flags: -Zsanitizer=leak -C opt-level=3 -Z mir-opt-level=4

#![crate_type="lib"]
#![feature(no_sanitize)]
Expand Down
2 changes: 1 addition & 1 deletion src/test/codegen/try_identity.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -C no-prepopulate-passes -O -Z mir-opt-level=2 -Zunsound-mir-opts
// compile-flags: -C no-prepopulate-passes -O -Z mir-opt-level=3 -Zunsound-mir-opts

// Ensure that `x?` has no overhead on `Result<T, E>` due to identity `match`es in lowering.
// This requires inlining to trigger the MIR optimizations in `SimplifyArmIdentity`.
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/const_prop/boolean_identities.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -O -Zmir-opt-level=3
// compile-flags: -O -Zmir-opt-level=4

// EMIT_MIR boolean_identities.test.ConstProp.diff
pub fn test(x: bool, y: bool) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/const_prop/issue-66971.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=2
// compile-flags: -Z mir-opt-level=3

// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
// outputs below, after ConstProp this is how _2 would look like with the bug:
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/const_prop/issue-67019.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=2
// compile-flags: -Z mir-opt-level=3

// This used to ICE in const-prop

Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/const_prop/mult_by_zero.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -O -Zmir-opt-level=3
// compile-flags: -O -Zmir-opt-level=4

// EMIT_MIR mult_by_zero.test.ConstProp.diff
fn test(x : i32) -> i32 {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/early_otherwise_branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=3
// compile-flags: -Z mir-opt-level=4
// EMIT_MIR early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
fn opt1(x: Option<u32>, y: Option<u32>) -> u32 {
match (x, y) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=3
// compile-flags: -Z mir-opt-level=4

// EMIT_MIR early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
fn opt1(x: Option<u32>, y: Option<u32>, z: Option<u32>) -> u32 {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/early_otherwise_branch_68867.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ignore-tidy-linelength
// compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts
// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts

// example from #68867
type CSSFloat = f32;
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/early_otherwise_branch_noopt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=3
// compile-flags: -Z mir-opt-level=4

// must not optimize as it does not follow the pattern of
// left and right hand side being the same variant
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/inline/inline-into-box-place.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ignore-endian-big
// ignore-wasm32-bare compiled with panic=abort by default
// compile-flags: -Z mir-opt-level=3
// compile-flags: -Z mir-opt-level=4
// EMIT_MIR_FOR_EACH_BIT_WIDTH
#![feature(box_syntax)]
// EMIT_MIR inline_into_box_place.main.Inline.diff
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/inline/inline-trait-method_2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z span_free_formats -Z mir-opt-level=3
// compile-flags: -Z span_free_formats -Z mir-opt-level=4

// EMIT_MIR inline_trait_method_2.test2.Inline.after.mir
fn test2(x: &dyn X) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/issues/issue-59352.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// removed.

// EMIT_MIR issue_59352.num_to_digit.PreCodegen.after.mir
// compile-flags: -Z mir-opt-level=2 -Z span_free_formats
// compile-flags: -Z mir-opt-level=3 -Z span_free_formats

pub fn num_to_digit(num: char) -> u32 {
// CHECK-NOT: panic
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/multiple_return_terminators.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=3
// compile-flags: -Z mir-opt-level=4
// EMIT_MIR multiple_return_terminators.test.MultipleReturnTerminators.diff

fn test(x: bool) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/simplify-arm-identity.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Checks that `SimplifyArmIdentity` is not applied if enums have incompatible layouts.
// Regression test for issue #66856.
//
// compile-flags: -Zmir-opt-level=2
// compile-flags: -Zmir-opt-level=3
// EMIT_MIR_FOR_EACH_BIT_WIDTH

enum Src {
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/simplify-arm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=2 -Zunsound-mir-opts
// compile-flags: -Z mir-opt-level=3 -Zunsound-mir-opts
// EMIT_MIR simplify_arm.id.SimplifyArmIdentity.diff
// EMIT_MIR simplify_arm.id.SimplifyBranchSame.diff
// EMIT_MIR simplify_arm.id_result.SimplifyArmIdentity.diff
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/const-generics/issues/issue-75299.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Zmir-opt-level=3
// compile-flags: -Zmir-opt-level=4
// run-pass

#![feature(const_generics)]
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/const_prop/inline_spans.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// build-fail
// compile-flags: -Zmir-opt-level=2
// compile-flags: -Zmir-opt-level=3

#![deny(warnings)]

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/const_prop/inline_spans_lint_attribute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Must be build-pass, because check-pass will not run const prop and thus not emit the lint anyway.
// build-pass
// compile-flags: -Zmir-opt-level=2
// compile-flags: -Zmir-opt-level=3

#![deny(warnings)]

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/issue-66345.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// run-pass
// compile-flags: -Z mir-opt-level=3
// compile-flags: -Z mir-opt-level=4

// Checks that the compiler does not ICE when passing references to field of by-value struct
// with -Z mir-opt-level=3
// with -Z mir-opt-level=4

fn do_nothing(_: &()) {}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/issue-67529.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=2
// compile-flags: -Z mir-opt-level=3
// run-pass

struct Baz<T: ?Sized> {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/issue-67640.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=3
// compile-flags: -Z mir-opt-level=4
// run-pass

struct X {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/issue-67641.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=2
// compile-flags: -Z mir-opt-level=3
// run-pass

use std::cell::Cell;
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/issue-67862.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=2
// compile-flags: -Z mir-opt-level=3
// run-pass

fn e220() -> (i64, i64) {
Expand Down
Loading