This change avoids inlining a function involved in a mutual-recursive cycle. Due to the lack of a global inline history, such inlining may cause an exponential size growth as the inlining extends up along the call graph.
Consider the following example,
void A() { B(); B();}
void B() { A(); }
void C() { B(); }
void D() { C(); }
When processing C, inlining B will result in
void C() { B(); B(); }
When processing D, inlining C and futher the two B callsites will result in
void D() { B(); B(); B(); B(); }
We've also seen that one of our internal services suffered from the inliner hanging for 6 hours.