@@ -5605,29 +5605,33 @@ bool Compiler::fgHeadMerge(BasicBlock* block, bool early)
56055605}
56065606
56075607// ------------------------------------------------------------------------
5608- //  gtTreeContainsTailCall: Check if a tree contains any tail call or tail call 
5609- //  candidate .
5608+ //  gtTreeContainsCall: 
5609+ //    Check if a tree contains a call node matching the given predicate .
56105610// 
56115611//  Parameters:
56125612//    tree - The tree
5613+ //    pred - Predicate that the call must match
56135614// 
5614- //  Remarks:
5615- //    While tail calls are generally expected to be top level nodes we do allow
5616- //    some other shapes of calls to be tail calls, including some cascading
5617- //    trivial assignments and casts. This function does a tree walk to check if
5618- //    any sub tree is a tail call.
5615+ //  Returns:
5616+ //    True if a call node matching the predicate was found, false otherwise.
56195617// 
5620- bool  Compiler::gtTreeContainsTailCall (GenTree* tree)
5618+ template  <typename  Predicate>
5619+ bool  Compiler::gtTreeContainsCall (GenTree* tree, Predicate pred)
56215620{
5622-     struct  HasTailCallCandidateVisitor  : GenTreeVisitor<HasTailCallCandidateVisitor >
5621+     struct  HasCallVisitor  : GenTreeVisitor<HasCallVisitor >
56235622    {
5623+     private: 
5624+         Predicate& m_pred;
5625+ 
5626+     public: 
56245627        enum 
56255628        {
56265629            DoPreOrder = true 
56275630        };
56285631
5629-         HasTailCallCandidateVisitor (Compiler* comp)
5630-             : GenTreeVisitor(comp)
5632+         HasCallVisitor (Compiler* comp, Predicate& pred)
5633+             : GenTreeVisitor<HasCallVisitor>(comp)
5634+             , m_pred(pred)
56315635        {
56325636        }
56335637
@@ -5639,7 +5643,7 @@ bool Compiler::gtTreeContainsTailCall(GenTree* tree)
56395643                return  WALK_SKIP_SUBTREES;
56405644            }
56415645
5642-             if  (node->IsCall () && (node->AsCall ()-> CanTailCall () || node-> AsCall ()-> IsTailCall ()))
5646+             if  (node->IsCall () && m_pred (node->AsCall ()))
56435647            {
56445648                return  WALK_ABORT;
56455649            }
@@ -5648,8 +5652,54 @@ bool Compiler::gtTreeContainsTailCall(GenTree* tree)
56485652        }
56495653    };
56505654
5651-     HasTailCallCandidateVisitor visitor (this );
5652-     return  visitor.WalkTree (&tree, nullptr ) == WALK_ABORT;
5655+     if  ((tree->gtFlags  & GTF_CALL) == 0 )
5656+     {
5657+         return  false ;
5658+     }
5659+ 
5660+     HasCallVisitor hasCall (this , pred);
5661+     return  hasCall.WalkTree (&tree, nullptr ) == WALK_ABORT;
5662+ }
5663+ 
5664+ // ------------------------------------------------------------------------
5665+ //  gtTreeContainsTailCall: Check if a tree contains any tail call or tail call
5666+ //  candidate.
5667+ // 
5668+ //  Parameters:
5669+ //    tree - The tree
5670+ // 
5671+ //  Remarks:
5672+ //    While tail calls are generally expected to be top level nodes we do allow
5673+ //    some other shapes of calls to be tail calls, including some cascading
5674+ //    trivial assignments and casts. This function does a tree walk to check if
5675+ //    any sub tree is a tail call.
5676+ // 
5677+ bool  Compiler::gtTreeContainsTailCall (GenTree* tree)
5678+ {
5679+     return  gtTreeContainsCall (tree, [](GenTreeCall* call) {
5680+         return  call->CanTailCall () || call->IsTailCall ();
5681+     });
5682+ }
5683+ 
5684+ // ------------------------------------------------------------------------
5685+ //  gtTreeContainsAsyncCall: Check if a tree contains any async call.
5686+ // 
5687+ //  Parameters:
5688+ //    tree - The tree to check
5689+ // 
5690+ //  Returns:
5691+ //    True if any node in the tree is an async call, false otherwise.
5692+ // 
5693+ bool  Compiler::gtTreeContainsAsyncCall (GenTree* tree)
5694+ {
5695+     if  (!compIsAsync ())
5696+     {
5697+         return  false ;
5698+     }
5699+ 
5700+     return  gtTreeContainsCall (tree, [](GenTreeCall* call) {
5701+         return  call->IsAsync ();
5702+     });
56535703}
56545704
56555705// ------------------------------------------------------------------------
0 commit comments