Package dk.brics.string.intermediate.operations

Source Code of dk.brics.string.intermediate.operations.ReachingDefinitions

package dk.brics.string.intermediate.operations;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import dk.brics.string.Debug;
import dk.brics.string.intermediate.Application;
import dk.brics.string.intermediate.Method;
import dk.brics.string.intermediate.Statement;
import dk.brics.string.intermediate.Variable;

/**
* Intra-procedural reaching definitions analysis performed on a set of methods.
* <p/>
* Reaching definitions are only made on local variables; not on fields.
*/
public class ReachingDefinitions {

    /**
     * For each statement and each used variable, which statements might have defined its value.
     */
    private Map<Statement, Map<Variable, Set<Statement>>> flow_info;
   
    /**
     * Definitely defined variables for each statement.
     */
    private DefinesVisitor dvs;
   
    /**
     * Maybe defined variables for each statement.
     */
    private DefinesVisitor dva;
   

  public ReachingDefinitions(Application app, LivenessAnalysis la, AliasAnalysis aa) {
        flow_info = new HashMap<Statement, Map<Variable, Set<Statement>>>();
        dvs = new DefinesVisitor(aa, true); // definitely defined variables for each statement
        dva = new DefinesVisitor(aa, false); // maybe defined variables for each statement
       
        for (Method m : app.getMethods()) {
            for (Statement s : m.getStatements()) {
                for (Variable v : dva.definedVars(s)) { // for each maybe defined variable v in each statement s...
                    // we don't want reaching definitions for fields
                    if (v.getField() != null)
                        continue;
                   
                    LinkedList<Statement> queue = new LinkedList<Statement>();
                    Set<Statement> seen = new HashSet<Statement>();
                    queue.addAll(s.getSuccs());
                    while (!queue.isEmpty()) { // look along successors ss...
                        Statement ss = queue.removeFirst();
                        if (!seen.contains(ss)) {
                            seen.add(ss);
                            putDef(ss, v, s); // if ss uses v then s might have defined it
                            if (!dvs.defines(ss, v) && la.getLiveAfter(ss).contains(v)) // continue along successors if v is live and not defined by ss
                            {
                                queue.addAll(ss.getSuccs());
                            }
                        }
                    }
                }
            }
        }
    }

    private void putDef(Statement s, Variable v, Statement def) {
        if (!flow_info.containsKey(s)) {
            flow_info.put(s, new HashMap<Variable, Set<Statement>>());
        }
        if (!flow_info.get(s).containsKey(v)) {
            flow_info.get(s).put(v, new HashSet<Statement>());
        }
        flow_info.get(s).get(v).add(def);
    }


    /**
     * Returns the (unmodifiable) set of definitions of the given variable reaching the given statement.
     * The result is sorted if in test mode.
     *
     * @param s the reached statement.
     * @param v the variable.
     * @return a set of {@link dk.brics.string.intermediate.Statement} objects.
     */
    public Set<Statement> getReachingDefs(Statement s, Variable v) {
        Set<Statement> t;
        if (flow_info.containsKey(s) && flow_info.get(s).containsKey(v)) {
            t = flow_info.get(s).get(v);
        } else {
            t = Collections.emptySet();
        }
        if (Debug.isTest()) {
            t = new TreeSet<Statement>(t);
        }
        return Collections.unmodifiableSet(t);
    }
   
}
TOP

Related Classes of dk.brics.string.intermediate.operations.ReachingDefinitions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.