Ruby: Reduce non-linear recursion in CFG completion library

Before

```
noinline
incremental
Completion::nestedEnsureCompletion#ff(/* Completion::Completion */ Completion::TCompletion outer,
                                      int nestLevel)
:-
  (
    (
      Completion::TReturnCompletion#f(outer),
      rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TBreakCompletion#f(outer),
      rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TNextCompletion#f(outer),
      rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TRedoCompletion#f(outer),
      rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TRetryCompletion#f(outer),
      rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TRaiseCompletion#f(outer),
      rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TExitCompletion#f(outer),
      rec Completion::Completion#class#f(outer)
    )
  ),
  exists(/* ControlFlowGraphImpl::Trees::BodyStmtTree */ cached dontcare AST::Cached::TAstNode _ |
    ControlFlowGraphImpl::Trees::BodyStmtTree::getNestLevel_dispred#ff(_,
                                                                       nestLevel)
  )
| [base_case] false()
| [delta_order]
  (
    (
      Completion::TReturnCompletion#f(outer),
      delta previous rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TBreakCompletion#f(outer),
      delta previous rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TNextCompletion#f(outer),
      delta previous rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TRedoCompletion#f(outer),
      delta previous rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TRetryCompletion#f(outer),
      delta previous rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TRaiseCompletion#f(outer),
      delta previous rec Completion::Completion#class#f(outer)
    );
    (
      Completion::TExitCompletion#f(outer),
      delta previous rec Completion::Completion#class#f(outer)
    )
  ),
  project#ControlFlowGraphImpl::Trees::BodyStmtTree::getNestLevel_dispred#ff(nestLevel),
  not(previous rec Completion::nestedEnsureCompletion#ff(outer, nestLevel))
.
```

After

```
noinline
Completion::nestedEnsureCompletion#ff(Completion::TCompletion outer,
                                      int nestLevel)
:-
  (
    Completion::TReturnCompletion#f(outer);
    Completion::TBreakCompletion#f(outer);
    Completion::TNextCompletion#f(outer);
    Completion::TRedoCompletion#f(outer);
    Completion::TRetryCompletion#f(outer);
    Completion::TRaiseCompletion#f(outer);
    Completion::TExitCompletion#f(outer)
  ),
  project#ControlFlowGraphImpl::Trees::BodyStmtTree::getNestLevel_dispred#ff(nestLevel)
.
```
This commit is contained in:
Tom Hvitved
2021-12-20 19:22:47 +01:00
parent aa92fe8c90
commit 29cd346702

View File

@@ -23,7 +23,7 @@ private newtype TCompletion =
TRetryCompletion() or
TRaiseCompletion() or // TODO: Add exception type?
TExitCompletion() or
TNestedCompletion(Completion inner, Completion outer, int nestLevel) {
TNestedCompletion(TCompletion inner, TCompletion outer, int nestLevel) {
inner = TBreakCompletion() and
outer instanceof NonNestedNormalCompletion and
nestLevel = 0
@@ -37,7 +37,7 @@ private newtype TCompletion =
}
pragma[noinline]
private predicate nestedEnsureCompletion(Completion outer, int nestLevel) {
private predicate nestedEnsureCompletion(TCompletion outer, int nestLevel) {
(
outer = TReturnCompletion()
or