This is an archive of the discontinued LLVM Phabricator instance.

[ASTMatchers] Avoid recursion in ancestor matching to save stack space.
ClosedPublic

Authored by sammccall on Sep 1 2020, 11:24 AM.

Details

Summary

A recent change increased the stack size of memoizedMatchesAncestorOfRecursively
leading to stack overflows on real code involving large fold expressions.
It's not totally unreasonable to choke on very deep ASTs, but as common
infrastructure it's be nice if ASTMatchFinder is more robust.
(It already uses data recursion for the regular "downward" traversal.)

Diff Detail

Event Timeline

sammccall created this revision.Sep 1 2020, 11:24 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 1 2020, 11:24 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
sammccall requested review of this revision.Sep 1 2020, 11:24 AM
hokein accepted this revision.Sep 3 2020, 12:01 AM
hokein added inline comments.
clang/lib/ASTMatchers/ASTMatchFinder.cpp
705

this API makes sense, I'm wondering whether we should do it further (more aligned with matchesChildOf pattern):

  • make matchesParentOf public;
  • introduce a new matchesParentOf interface in ASTMatcherFinder, which calls this function here;
  • then we can remove the special parent case in MatchASTVisitor::matchesAncestorOf, and the AncestorMatchMode enum is also not needed anymore;

I'm also ok with the current way.

738

nit: I think we should explicitly describe (either in the comment or name) these keys are for the single-parent *chain*. It took me a while to understand what are these keys for?

740

maybe

Finish => Memorize
Result => IsMatched

809

nit: assert(Parents.size() > 1).

This revision is now accepted and ready to land.Sep 3 2020, 12:01 AM

bump this in case you have missed this patch :) our another internal pipeline seems to need this fix.

sammccall marked 3 inline comments as done.Sep 22 2020, 10:28 AM
sammccall added inline comments.
clang/lib/ASTMatchers/ASTMatchFinder.cpp
705

I'm happy with that change, but I'd rather not bundle it into this one.
The goal here is to fix weird production characteristics (rather than APIs or algorithm output) and those are slippery, so let's change one thing at a time.

740

Finish => Memorize

Memoize and Memorize are different words, and memoize doesn't act on results but rather on functions. So I think this rename is confusing.

Result => IsMatched

Done

This revision was automatically updated to reflect the committed changes.
sammccall marked an inline comment as done.