/** @see #resolveInlineConflicts */
  private void resolveInlineConflictsForFunction(FunctionState fs) {
    // Functions that aren't referenced don't cause conflicts.
    if (!fs.hasReferences() || !fs.canInline()) {
      return;
    }

    Node fnNode = fs.getFn().getFunctionNode();
    Set<String> names = findCalledFunctions(fnNode);
    if (!names.isEmpty()) {
      // Prevent the removal of the referenced functions.
      for (String name : names) {
        FunctionState fsCalled = fns.get(name);
        if (fsCalled != null && fsCalled.canRemove()) {
          fsCalled.setRemove(false);
          // For functions that can no longer be removed, check if they should
          // still be inlined.
          if (!mimimizeCost(fsCalled)) {
            // It can't be inlined remove it from the list.
            fsCalled.setInline(false);
          }
        }
      }

      // Make a copy of the Node, so it isn't changed by other inlines.
      fs.setSafeFnNode(fs.getFn().getFunctionNode().cloneTree());
    }
  }
 /** @return Whether inlining the function reduces code size. */
 private boolean inliningLowersCost(FunctionState fs) {
   return injector.inliningLowersCost(
       fs.getModule(),
       fs.getFn().getFunctionNode(),
       fs.getReferences(),
       fs.getNamesToAlias(),
       fs.canRemove(),
       fs.getReferencesThis());
 }
 /** Removed inlined functions that no longer have any references. */
 void removeInlinedFunctions() {
   for (FunctionState fs : fns.values()) {
     if (fs.canRemove()) {
       Function fn = fs.getFn();
       Preconditions.checkState(fs.canInline());
       Preconditions.checkState(fn != null);
       verifyAllReferencesInlined(fs);
       fn.remove();
     }
   }
 }
  /** Removed inlined functions that no longer have any references. */
  void removeInlinedFunctions() {
    for (FunctionState fs : fns.values()) {
      if (fs.canRemove()) {
        Function fn = fs.getFn();
        Preconditions.checkState(fs.canInline());
        Preconditions.checkState(fn != null);
        verifyAllReferencesInlined(fs);

        if (specializationState != null) {
          specializationState.reportRemovedFunction(fn.getFunctionNode(), fn.getDeclaringBlock());
        }

        fn.remove();
      }
    }
  }
 /** Remove entries from the list of candidates that can't be inlined. */
 private void trimCandidatesUsingOnCost() {
   Iterator<Entry<String, FunctionState>> i;
   for (i = fns.entrySet().iterator(); i.hasNext(); ) {
     FunctionState fs = i.next().getValue();
     if (fs.hasReferences()) {
       // Only inline function if it decreases the code size.
       boolean lowersCost = mimimizeCost(fs);
       if (!lowersCost) {
         // It shouldn't be inlined; remove it from the list.
         i.remove();
       }
     } else if (!fs.canRemove()) {
       // Don't bother tracking functions without references that can't be
       // removed.
       i.remove();
     }
   }
 }