Skip to content

Commit

Permalink
Merge changes from rust-lang/rust
Browse files Browse the repository at this point in the history
  • Loading branch information
zec committed Nov 12, 2020
2 parents 562d50e + 77180db commit e4a43fc
Show file tree
Hide file tree
Showing 69 changed files with 1,068 additions and 525 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
161 changes: 81 additions & 80 deletions compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,7 +28,8 @@ pub struct Inline;
#[derive(Copy, Clone, Debug)]
struct CallSite<'tcx> {
callee: Instance<'tcx>,
bb: BasicBlock,
block: BasicBlock,
target: Option<BasicBlock>,
source_info: SourceInfo,
}

Expand Down Expand Up @@ -175,8 +173,7 @@ impl Inliner<'tcx> {

// Only consider direct calls to functions
let terminator = bb_data.terminator();
// FIXME: Handle inlining of diverging calls
if let TerminatorKind::Call { func: ref op, destination: Some(_), .. } = terminator.kind {
if let TerminatorKind::Call { func: ref op, ref destination, .. } = terminator.kind {
if let ty::FnDef(callee_def_id, substs) = *op.ty(caller_body, self.tcx).kind() {
// To resolve an instance its substs have to be fully normalized, so
// we do this here.
Expand All @@ -190,7 +187,12 @@ impl Inliner<'tcx> {
return None;
}

return Some(CallSite { callee, bb, source_info: terminator.source_info });
return Some(CallSite {
callee,
block: bb,
target: destination.map(|(_, target)| target),
source_info: terminator.source_info,
});
}
}

Expand Down Expand Up @@ -248,7 +250,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) {
Expand Down Expand Up @@ -398,9 +404,9 @@ impl Inliner<'tcx> {
caller_body: &mut Body<'tcx>,
mut callee_body: Body<'tcx>,
) {
let terminator = caller_body[callsite.bb].terminator.take().unwrap();
let terminator = caller_body[callsite.block].terminator.take().unwrap();
match terminator.kind {
TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => {
TerminatorKind::Call { args, destination, cleanup, .. } => {
// If the call is something like `a[*i] = f(i)`, where
// `i : &mut usize`, then just duplicating the `a[*i]`
// Place could result in two different locations if `f`
Expand All @@ -417,43 +423,39 @@ impl Inliner<'tcx> {
false
}

let dest = if dest_needs_borrow(destination.0) {
trace!("creating temp for return destination");
let dest = Rvalue::Ref(
self.tcx.lifetimes.re_erased,
BorrowKind::Mut { allow_two_phase_borrow: false },
destination.0,
);

let ty = dest.ty(caller_body, self.tcx);

let temp = LocalDecl::new(ty, callsite.source_info.span);

let tmp = caller_body.local_decls.push(temp);
let tmp = Place::from(tmp);

let stmt = Statement {
source_info: callsite.source_info,
kind: StatementKind::Assign(box (tmp, dest)),
};
caller_body[callsite.bb].statements.push(stmt);
self.tcx.mk_place_deref(tmp)
let dest = if let Some((destination_place, _)) = destination {
if dest_needs_borrow(destination_place) {
trace!("creating temp for return destination");
let dest = Rvalue::Ref(
self.tcx.lifetimes.re_erased,
BorrowKind::Mut { allow_two_phase_borrow: false },
destination_place,
);
let dest_ty = dest.ty(caller_body, self.tcx);
let temp = Place::from(self.new_call_temp(caller_body, &callsite, dest_ty));
caller_body[callsite.block].statements.push(Statement {
source_info: callsite.source_info,
kind: StatementKind::Assign(box (temp, dest)),
});
self.tcx.mk_place_deref(temp)
} else {
destination_place
}
} else {
destination.0
trace!("creating temp for return place");
Place::from(self.new_call_temp(caller_body, &callsite, callee_body.return_ty()))
};

let return_block = destination.1;

// Copy the arguments if needed.
let args: Vec<_> = self.make_call_args(args, &callsite, caller_body, return_block);
let args: Vec<_> = self.make_call_args(args, &callsite, caller_body);

let mut integrator = Integrator {
args: &args,
new_locals: Local::new(caller_body.local_decls.len())..,
new_scopes: SourceScope::new(caller_body.source_scopes.len())..,
new_blocks: BasicBlock::new(caller_body.basic_blocks().len())..,
destination: dest,
return_block,
return_block: callsite.target,
cleanup_block: cleanup,
in_cleanup_block: false,
tcx: self.tcx,
Expand Down Expand Up @@ -502,7 +504,7 @@ impl Inliner<'tcx> {
caller_body.var_debug_info.extend(callee_body.var_debug_info.drain(..));
caller_body.basic_blocks_mut().extend(callee_body.basic_blocks_mut().drain(..));

caller_body[callsite.bb].terminator = Some(Terminator {
caller_body[callsite.block].terminator = Some(Terminator {
source_info: callsite.source_info,
kind: TerminatorKind::Goto { target: integrator.map_block(START_BLOCK) },
});
Expand All @@ -526,7 +528,6 @@ impl Inliner<'tcx> {
args: Vec<Operand<'tcx>>,
callsite: &CallSite<'tcx>,
caller_body: &mut Body<'tcx>,
return_block: BasicBlock,
) -> Vec<Local> {
let tcx = self.tcx;

Expand Down Expand Up @@ -557,18 +558,8 @@ impl Inliner<'tcx> {
// `callee_body.spread_arg == None`, instead of special-casing closures.
if tcx.is_closure(callsite.callee.def_id()) {
let mut args = args.into_iter();
let self_ = self.create_temp_if_necessary(
args.next().unwrap(),
callsite,
caller_body,
return_block,
);
let tuple = self.create_temp_if_necessary(
args.next().unwrap(),
callsite,
caller_body,
return_block,
);
let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
assert!(args.next().is_none());

let tuple = Place::from(tuple);
Expand All @@ -588,13 +579,13 @@ impl Inliner<'tcx> {
Operand::Move(tcx.mk_place_field(tuple, Field::new(i), ty.expect_ty()));

// Spill to a local to make e.g., `tmp0`.
self.create_temp_if_necessary(tuple_field, callsite, caller_body, return_block)
self.create_temp_if_necessary(tuple_field, callsite, caller_body)
});

closure_ref_arg.chain(tuple_tmp_args).collect()
} else {
args.into_iter()
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body, return_block))
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body))
.collect()
}
}
Expand All @@ -606,46 +597,52 @@ impl Inliner<'tcx> {
arg: Operand<'tcx>,
callsite: &CallSite<'tcx>,
caller_body: &mut Body<'tcx>,
return_block: BasicBlock,
) -> Local {
// FIXME: Analysis of the usage of the arguments to avoid
// unnecessary temporaries.

// Reuse the operand if it is a moved temporary.
if let Operand::Move(place) = &arg {
if let Some(local) = place.as_local() {
if caller_body.local_kind(local) == LocalKind::Temp {
// Reuse the operand if it's a temporary already
return local;
}
}
}

// Otherwise, create a temporary for the argument.
trace!("creating temp for argument {:?}", arg);
// Otherwise, create a temporary for the arg
let arg = Rvalue::Use(arg);

let ty = arg.ty(caller_body, self.tcx);

let arg_tmp = LocalDecl::new(ty, callsite.source_info.span);
let arg_tmp = caller_body.local_decls.push(arg_tmp);

caller_body[callsite.bb].statements.push(Statement {
let arg_ty = arg.ty(caller_body, self.tcx);
let local = self.new_call_temp(caller_body, callsite, arg_ty);
caller_body[callsite.block].statements.push(Statement {
source_info: callsite.source_info,
kind: StatementKind::StorageLive(arg_tmp),
kind: StatementKind::Assign(box (Place::from(local), Rvalue::Use(arg))),
});
caller_body[callsite.bb].statements.push(Statement {
local
}

/// Introduces a new temporary into the caller body that is live for the duration of the call.
fn new_call_temp(
&self,
caller_body: &mut Body<'tcx>,
callsite: &CallSite<'tcx>,
ty: Ty<'tcx>,
) -> Local {
let local = caller_body.local_decls.push(LocalDecl::new(ty, callsite.source_info.span));

caller_body[callsite.block].statements.push(Statement {
source_info: callsite.source_info,
kind: StatementKind::Assign(box (Place::from(arg_tmp), arg)),
kind: StatementKind::StorageLive(local),
});
caller_body[return_block].statements.insert(
0,
Statement {
source_info: callsite.source_info,
kind: StatementKind::StorageDead(arg_tmp),
},
);

arg_tmp

if let Some(block) = callsite.target {
caller_body[block].statements.insert(
0,
Statement {
source_info: callsite.source_info,
kind: StatementKind::StorageDead(local),
},
);
}

local
}
}

Expand All @@ -670,7 +667,7 @@ struct Integrator<'a, 'tcx> {
new_scopes: RangeFrom<SourceScope>,
new_blocks: RangeFrom<BasicBlock>,
destination: Place<'tcx>,
return_block: BasicBlock,
return_block: Option<BasicBlock>,
cleanup_block: Option<BasicBlock>,
in_cleanup_block: bool,
tcx: TyCtxt<'tcx>,
Expand Down Expand Up @@ -816,7 +813,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
}
}
TerminatorKind::Return => {
terminator.kind = TerminatorKind::Goto { target: self.return_block };
terminator.kind = if let Some(tgt) = self.return_block {
TerminatorKind::Goto { target: tgt }
} else {
TerminatorKind::Unreachable
}
}
TerminatorKind::Resume => {
if let Some(tgt) = self.cleanup_block {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::linux_base::opts();
let mut base = super::linux_gnu_base::opts();
base.max_atomic_width = Some(128);

Target {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_target/src/spec/android_base.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use crate::spec::{LinkerFlavor, TargetOptions};

pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
let mut base = super::linux_gnu_base::opts();
base.os = "android".to_string();
// Many of the symbols defined in compiler-rt are also defined in libgcc.
// Android's linker doesn't like that by default.
base.pre_link_args
.get_mut(&LinkerFlavor::Gcc)
.unwrap()
.push("-Wl,--allow-multiple-definition".to_string());
base.is_like_android = true;
base.dwarf_version = Some(2);
base.position_independent_executables = true;
base.has_elf_tls = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::linux_base::opts();
let mut base = super::linux_gnu_base::opts();
base.max_atomic_width = Some(64);
Target {
llvm_target: "arm-unknown-linux-gnueabi".to_string(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::linux_base::opts();
let mut base = super::linux_gnu_base::opts();
base.max_atomic_width = Some(64);
Target {
llvm_target: "arm-unknown-linux-gnueabihf".to_string(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let base = super::linux_base::opts();
let base = super::linux_gnu_base::opts();
Target {
llvm_target: "armv4t-unknown-linux-gnueabi".to_string(),
pointer_width: 32,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
let base = super::linux_base::opts();
let base = super::linux_gnu_base::opts();
Target {
llvm_target: "armv5te-unknown-linux-gnueabi".to_string(),
pointer_width: 32,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::spec::{Target, TargetOptions};
// hardfloat.

pub fn target() -> Target {
let base = super::linux_base::opts();
let base = super::linux_gnu_base::opts();
Target {
llvm_target: "armv7-unknown-linux-gnueabi".to_string(),
pointer_width: 32,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::spec::{Target, TargetOptions};
// thumb-mode. See the thumbv7neon variant for enabling both.

pub fn target() -> Target {
let base = super::linux_base::opts();
let base = super::linux_gnu_base::opts();
Target {
llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
pointer_width: 32,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::spec::{LinkerFlavor, Target};

pub fn target() -> Target {
let mut base = super::linux_base::opts();
let mut base = super::linux_gnu_base::opts();
base.cpu = "pentium4".to_string();
base.max_atomic_width = Some(64);
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
Expand Down
Loading

0 comments on commit e4a43fc

Please sign in to comment.