private boolean optimize()

in linq4j/src/main/java/org/apache/calcite/linq4j/tree/BlockBuilder.java [355:465]


  private boolean optimize(Shuttle optimizer, boolean performInline) {
    int optimizeCount = 0;
    final UseCounter useCounter = new UseCounter();
    for (Statement statement : statements) {
      if (statement instanceof DeclarationStatement && performInline) {
        DeclarationStatement decl = (DeclarationStatement) statement;
        useCounter.map.put(decl.parameter, new Slot());
      }
      // We are added only counters up to current statement.
      // It is fine to count usages as the latter declarations cannot be used
      // in more recent statements.
      if (!useCounter.map.isEmpty()) {
        statement.accept(useCounter);
      }
    }
    final IdentityHashMap<ParameterExpression, Expression> subMap =
        new IdentityHashMap<>(useCounter.map.size());
    final Shuttle visitor = new InlineVariableVisitor(subMap);
    final ArrayList<Statement> oldStatements = new ArrayList<>(statements);
    statements.clear();

    for (Statement oldStatement : oldStatements) {
      if (oldStatement instanceof DeclarationStatement) {
        DeclarationStatement statement = (DeclarationStatement) oldStatement;
        final Slot slot = useCounter.map.get(statement.parameter);
        int count = slot == null ? Integer.MAX_VALUE - 10 : slot.count;
        if (count > 1 && isSimpleExpression(statement.initializer)) {
          // Inline simple final constants
          count = 1;
        }
        if (!isSafeForReuse(statement)) {
          // Don't inline variables that are not final. They might be assigned
          // more than once.
          count = 100;
        }
        if (isCostly(statement)) {
          // Don't inline variables that are costly, such as "new MyFunction()".
          // Later we will make their declarations static.
          count = 100;
        }
        if (statement.parameter.name.startsWith("_")) {
          // Don't inline variables whose name begins with "_". This
          // is a hacky way to prevent inlining. E.g.
          //   final int _count = collection.size();
          //   foo(collection);
          //   return collection.size() - _count;
          count = Integer.MAX_VALUE;
        }
        if (statement.initializer instanceof NewExpression
            && ((NewExpression) statement.initializer).memberDeclarations
                != null) {
          // Don't inline anonymous inner classes. Janino gets
          // confused referencing variables from deeply nested
          // anonymous classes.
          count = Integer.MAX_VALUE;
        }
        Expression normalized = normalizeDeclaration(statement);
        expressionForReuse.remove(normalized);
        switch (count) {
        case 0:
          // Only declared, never used. Throw away declaration.
          break;
        case 1:
          // declared, used once. inline it.
          subMap.put(statement.parameter, normalized);
          break;
        default:
          Statement beforeOptimize = oldStatement;
          if (!subMap.isEmpty()) {
            oldStatement = oldStatement.accept(visitor); // remap
          }
          oldStatement = oldStatement.accept(optimizer);
          if (beforeOptimize != oldStatement) {
            ++optimizeCount;
            if (count != Integer.MAX_VALUE
                && oldStatement instanceof DeclarationStatement
                && isSafeForReuse((DeclarationStatement) oldStatement)
                && isSimpleExpression(
                  ((DeclarationStatement) oldStatement).initializer)) {
              // Allow to inline the expression that became simple after
              // optimizations.
              DeclarationStatement newDecl =
                  (DeclarationStatement) oldStatement;
              subMap.put(newDecl.parameter, normalizeDeclaration(newDecl));
              oldStatement = OptimizeShuttle.EMPTY_STATEMENT;
            }
          }
          if (oldStatement != OptimizeShuttle.EMPTY_STATEMENT) {
            if (oldStatement instanceof DeclarationStatement) {
              addExpressionForReuse((DeclarationStatement) oldStatement);
            }
            statements.add(oldStatement);
          }
          break;
        }
      } else {
        Statement beforeOptimize = oldStatement;
        if (!subMap.isEmpty()) {
          oldStatement = oldStatement.accept(visitor); // remap
        }
        oldStatement = oldStatement.accept(optimizer);
        if (beforeOptimize != oldStatement) {
          ++optimizeCount;
        }
        if (oldStatement != OptimizeShuttle.EMPTY_STATEMENT) {
          statements.add(oldStatement);
        }
      }
    }
    return optimizeCount > 0;
  }