From c8943c62f7a139b466648249045d557259cf22fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 10 Nov 2020 00:00:00 +0000 Subject: [PATCH] Add flags customizing behaviour of MIR inlining * `-Zinline-mir-threshold` to change the default threshold. * `-Zinline-mir-hint-threshold` to change the threshold used by functions with inline hint. --- compiler/rustc_interface/src/tests.rs | 2 + compiler/rustc_mir/src/transform/inline.rs | 9 +-- compiler/rustc_session/src/options.rs | 4 ++ src/test/mir-opt/inline/inline-options.rs | 19 +++++++ .../inline_options.main.Inline.after.mir | 56 +++++++++++++++++++ 5 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 src/test/mir-opt/inline/inline-options.rs create mode 100644 src/test/mir-opt/inline/inline_options.main.Inline.after.mir diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index dfc6f69145753..1fc2d281e7935 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -554,6 +554,8 @@ fn test_debugging_options_tracking_hash() { tracked!(function_sections, Some(false)); tracked!(human_readable_cgu_names, true); tracked!(inline_in_all_cgus, Some(true)); + tracked!(inline_mir_threshold, 123); + tracked!(inline_mir_hint_threshold, 123); tracked!(insert_sideeffect, true); tracked!(instrument_coverage, true); tracked!(instrument_mcount, true); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 97b513445264a..c742821e9bf0a 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -16,9 +16,6 @@ use crate::transform::MirPass; use std::iter; use std::ops::{Range, RangeFrom}; -const DEFAULT_THRESHOLD: usize = 50; -const HINT_THRESHOLD: usize = 100; - const INSTR_COST: usize = 5; const CALL_PENALTY: usize = 25; const LANDINGPAD_PENALTY: usize = 50; @@ -248,7 +245,11 @@ impl Inliner<'tcx> { } } - let mut threshold = if hinted { HINT_THRESHOLD } else { DEFAULT_THRESHOLD }; + let mut threshold = if hinted { + self.tcx.sess.opts.debugging_opts.inline_mir_hint_threshold + } else { + self.tcx.sess.opts.debugging_opts.inline_mir_threshold + }; // Significantly lower the threshold for inlining cold functions if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index ceed730e25b08..1cd3d11e32153 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -929,6 +929,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, (default: no)"), incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED], "verify incr. comp. hashes of green query instances (default: no)"), + inline_mir_threshold: usize = (50, parse_uint, [TRACKED], + "a default MIR inlining threshold (default: 50)"), + inline_mir_hint_threshold: usize = (100, parse_uint, [TRACKED], + "inlining threshold for functions with inline hint (default: 100)"), inline_in_all_cgus: Option = (None, parse_opt_bool, [TRACKED], "control whether `#[inline]` functions are in all CGUs"), input_stats: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/test/mir-opt/inline/inline-options.rs b/src/test/mir-opt/inline/inline-options.rs new file mode 100644 index 0000000000000..477f050b69e42 --- /dev/null +++ b/src/test/mir-opt/inline/inline-options.rs @@ -0,0 +1,19 @@ +// Checks that inlining threshold can be controlled with +// inline-mir-threshold and inline-hint-threshold options. +// +// compile-flags: -Zinline-mir-threshold=90 +// compile-flags: -Zinline-mir-hint-threshold=50 + +// EMIT_MIR inline_options.main.Inline.after.mir +fn main() { + not_inlined(); + inlined::(); +} + +// Cost is approximately 3 * 25 + 5 = 80. +#[inline] +pub fn not_inlined() { g(); g(); g(); } +pub fn inlined() { g(); g(); g(); } + +#[inline(never)] +fn g() {} diff --git a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir new file mode 100644 index 0000000000000..4cbdde2ba07d7 --- /dev/null +++ b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir @@ -0,0 +1,56 @@ +// MIR for `main` after Inline + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-options.rs:8:11: 8:11 + let _1: (); // in scope 0 at $DIR/inline-options.rs:9:5: 9:18 + let _2: (); // in scope 0 at $DIR/inline-options.rs:10:5: 10:21 + scope 1 (inlined inlined::) { // at $DIR/inline-options.rs:10:5: 10:21 + let _3: (); // in scope 1 at $DIR/inline-options.rs:10:5: 10:21 + let _4: (); // in scope 1 at $DIR/inline-options.rs:10:5: 10:21 + let _5: (); // in scope 1 at $DIR/inline-options.rs:10:5: 10:21 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-options.rs:9:5: 9:18 + _1 = not_inlined() -> bb1; // scope 0 at $DIR/inline-options.rs:9:5: 9:18 + // mir::Constant + // + span: $DIR/inline-options.rs:9:5: 9:16 + // + literal: Const { ty: fn() {not_inlined}, val: Value(Scalar()) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/inline-options.rs:9:18: 9:19 + StorageLive(_2); // scope 0 at $DIR/inline-options.rs:10:5: 10:21 + StorageLive(_3); // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + _3 = g() -> bb2; // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + // mir::Constant + // + span: $DIR/inline-options.rs:10:5: 10:21 + // + literal: Const { ty: fn() {g}, val: Value(Scalar()) } + } + + bb2: { + StorageDead(_3); // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + StorageLive(_4); // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + _4 = g() -> bb3; // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + // mir::Constant + // + span: $DIR/inline-options.rs:10:5: 10:21 + // + literal: Const { ty: fn() {g}, val: Value(Scalar()) } + } + + bb3: { + StorageDead(_4); // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + StorageLive(_5); // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + _5 = g() -> bb4; // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + // mir::Constant + // + span: $DIR/inline-options.rs:10:5: 10:21 + // + literal: Const { ty: fn() {g}, val: Value(Scalar()) } + } + + bb4: { + StorageDead(_5); // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + _2 = const (); // scope 1 at $DIR/inline-options.rs:10:5: 10:21 + StorageDead(_2); // scope 0 at $DIR/inline-options.rs:10:21: 10:22 + _0 = const (); // scope 0 at $DIR/inline-options.rs:8:11: 11:2 + return; // scope 0 at $DIR/inline-options.rs:11:2: 11:2 + } +}