1
Fork 0

Rollup merge of #78873 - tmiasko:inline-opts, r=oli-obk

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.

Having those as configurable flags makes it possible to experiment with with
different inlining thresholds and substantially increase test coverage of MIR
inlining when used with increased thresholds (for example, necessary to test
#78844).
This commit is contained in:
Jonas Schievink 2020-11-11 20:59:03 +01:00 committed by GitHub
commit 919177f7e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 86 additions and 4 deletions

View file

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

View file

@ -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) {

View file

@ -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<bool> = (None, parse_opt_bool, [TRACKED],
"control whether `#[inline]` functions are in all CGUs"),
input_stats: bool = (false, parse_bool, [UNTRACKED],

View file

@ -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::<u32>();
}
// Cost is approximately 3 * 25 + 5 = 80.
#[inline]
pub fn not_inlined() { g(); g(); g(); }
pub fn inlined<T>() { g(); g(); g(); }
#[inline(never)]
fn g() {}

View file

@ -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::<u32>) { // 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(<ZST>)) }
}
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(<ZST>)) }
}
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(<ZST>)) }
}
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(<ZST>)) }
}
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
}
}