code: @Nullable
    private Node trySimplifyUnusedResult(Node expression) {
      ArrayDeque<Node> sideEffectRoots = new ArrayDeque<>();
      boolean atFixedPoint = trySimplifyUnusedResultInternal(expression, sideEffectRoots);
  
      if (atFixedPoint) {
        // `expression` is in a form that cannot be further optimized.
        return expression;
      } else if (sideEffectRoots.isEmpty()) {
        deleteNode(expression);
        return null;
      } else if (sideEffectRoots.peekFirst() == expression) {
        // Expression was a conditional that was transformed. There can't be any other side-effects,
        // but we also can't detach the transformed root.
        checkState(sideEffectRoots.size() == 1, sideEffectRoots);
        reportChangeToEnclosingScope(expression);
        return expression;
      } else {
        Node sideEffects = asDetachedExpression(sideEffectRoots.pollFirst());
  
        // Assemble a tree of comma expressions for all the side-effects. The tree must execute the
        // side-effects in FIFO order with respect to the queue. It must also be left leaning to match
        // the parser's preferred strucutre.
        while (!sideEffectRoots.isEmpty()) {
          Node next = asDetachedExpression(sideEffectRoots.pollFirst());
          sideEffects = IR.comma(sideEffects, next).srcref(next);
        }
  
        expression.getParent().addChildBefore(sideEffects, expression);
        deleteNode(expression);
        return sideEffects;
      }
    }
docs: Replaces {@code expression} with an expression that contains only side-effects of the original.
  
  <p>This replacement is made under the assumption that the result of {@code expression} is
  unused and therefore it is correct to eliminate non-side-effectful nodes.
  
  @return The replacement expression, or {@code null} if there were no side-effects to preserve.