static void runFlowAnalyzes(OptFunctionNode fn, Node[] statementNodes)
    {
        int paramCount = fn.fnode.getParamCount();
        int varCount = fn.fnode.getParamAndVarCount();
        int[] varTypes = new int[varCount];
        // If the variable is a parameter, it could have any type.
        for (int i = 0; i != paramCount; ++i) {
            varTypes[i] = Optimizer.AnyType;
        }
        // If the variable is from a "var" statement, its typeEvent will be set
        // when we see the setVar node.
        for (int i = paramCount; i != varCount; ++i) {
            varTypes[i] = Optimizer.NoType;
        }

        Block[] theBlocks = buildBlocks(statementNodes);

        if (DEBUG) {
            ++debug_blockCount;
            System.out.println("-------------------"+fn.fnode.getFunctionName()+"  "+debug_blockCount+"--------");
            System.out.println(toString(theBlocks, statementNodes));
        }

        reachingDefDataFlow(fn, statementNodes, theBlocks, varTypes);
        typeFlow(fn, statementNodes, theBlocks, varTypes);

        if (DEBUG) {
            for (int i = 0; i < theBlocks.length; i++) {
                System.out.println("For block " + theBlocks[i].itsBlockID);
                theBlocks[i].printLiveOnEntrySet(fn);
            }
            System.out.println("Variable Table, size = " + varCount);
            for (int i = 0; i != varCount; i++) {
                System.out.println("["+i+"] type: "+varTypes[i]);
            }
        }

        for (int i = paramCount; i != varCount; i++) {
            if (varTypes[i] == Optimizer.NumberType) {
                fn.setIsNumberVar(i);
            }
        }

    }