UnboxableOpsAnalysisProblem.java

package org.jruby.ir.dataflow.analyses;

import org.jruby.ir.dataflow.DataFlowConstants;
import org.jruby.ir.dataflow.DataFlowProblem;
import org.jruby.ir.operands.TemporaryLocalVariable;
import org.jruby.ir.operands.Variable;
import org.jruby.ir.representations.BasicBlock;

import java.util.HashMap;
import java.util.Map;

// This problem tries to find unboxable (currently, Float and Fixnum) operands
// by inferring types and optimistically assuming that Float and Fixnum numeric
// operations have not been / will not be modified in those classes.
//
// This is a very simplistic type analysis. Doesn't analyze Array/Splat/Range
// operands and array/splat dereference/iteration since that requires assumptions
// to be made about those classes.
//
// In this analysis, we will treat:
// * 'null' as Dataflow.TOP
// * a concrete class as known type
// * 'Object.class' as Dataflow.BOTTOM
//
// Type of a variable will change at most twice: TOP --> class --> BOTTOM

public class UnboxableOpsAnalysisProblem extends DataFlowProblem<UnboxableOpsAnalysisProblem, UnboxableOpsAnalysisNode> {
    public final static String NAME = "UnboxableOpsAnalysis";

    public UnboxableOpsAnalysisProblem() {
        super(DataFlowProblem.DF_Direction.FORWARD);
    }

    @Override
    public String getName() {
        return "Unboxable Operands Analysis";
    }

    @Override
    public UnboxableOpsAnalysisNode buildFlowGraphNode(BasicBlock bb) {
        return new UnboxableOpsAnalysisNode(this, bb);
    }

    @Override
    public String getDataFlowVarsForOutput() {
        return "";
    }

    public void unbox() {
        // System.out.println("---------------- SCOPE BEFORE unboxing ----------------");
        // System.out.println("\nInstrs:\n" + getScope().cfg().toStringInstrs());
        Map<Variable, TemporaryLocalVariable> unboxMap = new HashMap<Variable, TemporaryLocalVariable>();
        for (UnboxableOpsAnalysisNode n : generateWorkList()) {
            n.unbox(unboxMap);
        }

        // SSS FIXME: This should be done differently
        getScope().setDataFlowSolution(DataFlowConstants.LVP_NAME, null);
    }
}