Auto merge of #93381 - tmiasko:is-self-recursive, r=ecstatic-morse
Check the number of arguments first in `is_recursive_call`
This commit is contained in:
commit
745e926487
1 changed files with 10 additions and 4 deletions
|
@ -66,8 +66,14 @@ struct Search<'mir, 'tcx> {
|
|||
|
||||
impl<'mir, 'tcx> Search<'mir, 'tcx> {
|
||||
/// Returns `true` if `func` refers to the function we are searching in.
|
||||
fn is_recursive_call(&self, func: &Operand<'tcx>) -> bool {
|
||||
fn is_recursive_call(&self, func: &Operand<'tcx>, args: &[Operand<'tcx>]) -> bool {
|
||||
let Search { tcx, body, trait_substs, .. } = *self;
|
||||
// Resolving function type to a specific instance that is being called is expensive. To
|
||||
// avoid the cost we check the number of arguments first, which is sufficient to reject
|
||||
// most of calls as non-recursive.
|
||||
if args.len() != body.arg_count {
|
||||
return false;
|
||||
}
|
||||
let caller = body.source.def_id();
|
||||
let param_env = tcx.param_env(caller);
|
||||
|
||||
|
@ -141,8 +147,8 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> {
|
|||
fn node_settled(&mut self, bb: BasicBlock) -> ControlFlow<Self::BreakVal> {
|
||||
// When we examine a node for the last time, remember it if it is a recursive call.
|
||||
let terminator = self.body[bb].terminator();
|
||||
if let TerminatorKind::Call { func, .. } = &terminator.kind {
|
||||
if self.is_recursive_call(func) {
|
||||
if let TerminatorKind::Call { func, args, .. } = &terminator.kind {
|
||||
if self.is_recursive_call(func, args) {
|
||||
self.reachable_recursive_calls.push(terminator.source_info.span);
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +163,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> {
|
|||
}
|
||||
// Don't traverse successors of recursive calls or false CFG edges.
|
||||
match self.body[bb].terminator().kind {
|
||||
TerminatorKind::Call { ref func, .. } => self.is_recursive_call(func),
|
||||
TerminatorKind::Call { ref func, ref args, .. } => self.is_recursive_call(func, args),
|
||||
TerminatorKind::FalseEdge { imaginary_target, .. } => imaginary_target == target,
|
||||
_ => false,
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue