-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Micro-optimize InstSimplify
's simplify_primitive_clone
#139644
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,6 @@ use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, layout}; | |
use rustc_span::{DUMMY_SP, Symbol, sym}; | ||
|
||
use crate::simplify::simplify_duplicate_switch_targets; | ||
use crate::take_array; | ||
|
||
pub(super) enum InstSimplify { | ||
BeforeInline, | ||
|
@@ -229,39 +228,31 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { | |
terminator: &mut Terminator<'tcx>, | ||
statements: &mut Vec<Statement<'tcx>>, | ||
) { | ||
let TerminatorKind::Call { func, args, destination, target, .. } = &mut terminator.kind | ||
let TerminatorKind::Call { | ||
func, args, destination, target: Some(destination_block), .. | ||
} = &terminator.kind | ||
else { | ||
return; | ||
}; | ||
|
||
// It's definitely not a clone if there are multiple arguments | ||
let [arg] = &args[..] else { return }; | ||
|
||
let Some(destination_block) = *target else { return }; | ||
|
||
// Only bother looking more if it's easy to know what we're calling | ||
let Some((fn_def_id, fn_args)) = func.const_fn_def() else { return }; | ||
|
||
// Clone needs one arg, so we can cheaply rule out other stuff | ||
if fn_args.len() != 1 { | ||
return; | ||
} | ||
let Some((fn_def_id, ..)) = func.const_fn_def() else { return }; | ||
|
||
// These types are easily available from locals, so check that before | ||
// doing DefId lookups to figure out what we're actually calling. | ||
let arg_ty = arg.node.ty(self.local_decls, self.tcx); | ||
|
||
let ty::Ref(_region, inner_ty, Mutability::Not) = *arg_ty.kind() else { return }; | ||
|
||
if !inner_ty.is_trivially_pure_clone_copy() { | ||
return; | ||
} | ||
|
||
if !self.tcx.is_lang_item(fn_def_id, LangItem::CloneFn) { | ||
if !self.tcx.is_lang_item(fn_def_id, LangItem::CloneFn) | ||
|| !inner_ty.is_trivially_pure_clone_copy() | ||
compiler-errors marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
return; | ||
} | ||
|
||
let Ok([arg]) = take_array(args) else { return }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, this can never return |
||
let Some(arg_place) = arg.node.place() else { return }; | ||
|
||
statements.push(Statement { | ||
|
@@ -273,7 +264,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { | |
)), | ||
))), | ||
}); | ||
terminator.kind = TerminatorKind::Goto { target: destination_block }; | ||
terminator.kind = TerminatorKind::Goto { target: *destination_block }; | ||
} | ||
|
||
fn simplify_nounwind_call(&self, terminator: &mut Terminator<'tcx>) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for second check that the fn being called has only 1 arg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can maybe leave a
debug_assert
here as a sanity check?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine, we'll ICE otherwise or at least fail MIR validation.