Package dk.brics.xact.analysis.dataflow

Source Code of dk.brics.xact.analysis.dataflow.VariableAnalysis

package dk.brics.xact.analysis.dataflow;

import java.util.Set;

import dk.brics.xact.analysis.flowgraph.FlowGraph;
import dk.brics.xact.analysis.flowgraph.Statement;
import dk.brics.xact.analysis.flowgraph.VariableFilter;
import dk.brics.xact.analysis.flowgraph.Variable;
import dk.brics.xact.analysis.flowgraph.statements.AnalyzeStm;
import dk.brics.xact.analysis.flowgraph.statements.ArrayReadStm;
import dk.brics.xact.analysis.flowgraph.statements.ArrayWriteStm;
import dk.brics.xact.analysis.flowgraph.statements.ArrayWriteStringStm;
import dk.brics.xact.analysis.flowgraph.statements.Assignment;
import dk.brics.xact.analysis.flowgraph.statements.CallStm;
import dk.brics.xact.analysis.flowgraph.statements.CastStm;
import dk.brics.xact.analysis.flowgraph.statements.CheckStm;
import dk.brics.xact.analysis.flowgraph.statements.ConcatStm;
import dk.brics.xact.analysis.flowgraph.statements.ConstStm;
import dk.brics.xact.analysis.flowgraph.statements.CopyStm;
import dk.brics.xact.analysis.flowgraph.statements.EmptyStm;
import dk.brics.xact.analysis.flowgraph.statements.EscapeStm;
import dk.brics.xact.analysis.flowgraph.statements.GapifyStm;
import dk.brics.xact.analysis.flowgraph.statements.GetStm;
import dk.brics.xact.analysis.flowgraph.statements.InsertStm;
import dk.brics.xact.analysis.flowgraph.statements.NodeStm;
import dk.brics.xact.analysis.flowgraph.statements.NopStm;
import dk.brics.xact.analysis.flowgraph.statements.PlugStm;
import dk.brics.xact.analysis.flowgraph.statements.RemoveStm;
import dk.brics.xact.analysis.flowgraph.statements.SetStm;
import dk.brics.xact.analysis.flowgraph.statements.StatementVisitor;
import dk.brics.xact.analysis.flowgraph.statements.UnknownStm;
import dk.brics.xact.analysis.flowgraph.statements.ValidateStm;
import dk.brics.xact.analysis.flowgraph.statements.VarStm;

/**
* Lattice and transfer functions for a dataflow analysis that
* tracks values for program variables.
*/
public class VariableAnalysis<VariableElementType> implements AnalysisInterface<VariableAnalysisElement<VariableElementType>> {

  private VariableAnalysisInterface<VariableElementType> val;
 
  public boolean isForward() {
    return true;
  }
  public Set<Statement> getInitial(FlowGraph g) {
    return g.getEntries();
  }
 
  /**
   * Constructs a new variable analysis using the given lattice.
   */
  public VariableAnalysis(VariableAnalysisInterface<VariableElementType> val) {
    this.val = val;
  }
 
  public VariableAnalysisElement<VariableElementType> newBottomElement() {
    return new VariableAnalysisElement<VariableElementType>();
  }

  public boolean merge(VariableAnalysisElement<VariableElementType> source, VariableFilter filter, VariableAnalysisElement<VariableElementType> dest) {
    boolean changed = false;
    for (Variable v : source.getVariables()) {
      if (filter.containsVariable(v)) {
        changed |= val.merge(getVar(source, v), getVar(dest, v));
      }
    }
    return changed;
  }

  private VariableElementType getVar(VariableAnalysisElement<VariableElementType> elem, Variable var) {
    if (var == null)
      return null;
    VariableElementType t = elem.get(var);
    if (t == null) {
      t = val.newBottomElement();
      elem.put(var, t);
    }
    return t;
  }
 
  public boolean transfer(final VariableAnalysisElement<VariableElementType> in, Statement s, final VariableAnalysisElement<VariableElementType> out) {
    final boolean[] changed = new boolean[1];
    s.visitBy(new StatementVisitor() {

      private void handleAssign(Assignment s, VariableElementType value) {
        val.assign(value, s);
        if (s instanceof AnalyzeStm) {
          AnalyzeStm as = (AnalyzeStm) s;
          if (as.getDest().getID() == as.getBase().getID())
            return; // skip AnalyzeStm assignment if dest==base
        }
        for (Variable v : in.getVariables()) {
          if (v == s.getDest()) {
            changed[0] |= val.merge(getVar(in, v), getVar(out, v));
          }
        }
        changed[0] |= val.merge(value, getVar(out, s.getDest()));
      }
     
      public void visitAnalyzeStm(AnalyzeStm s) {
        handleAssign(s, getVar(in, s.getBase()));
      }

      public void visitCastStm(CastStm s) {
        handleAssign(s, val.transferCast(s, getVar(in, s.getBase())));
      }

      public void visitConcatStm(ConcatStm s) {
        handleAssign(s, val.transferConcat(s, getVar(in, s.getXMLSource())));
      }

      public void visitConstStm(ConstStm s) {
        handleAssign(s, val.transferConst(s));
      }

      public void visitCopyStm(CopyStm s) {
        handleAssign(s, val.transferCopy(s, getVar(in, s.getBase()), getVar(in, s.getFirstAttr()),
            getVar(in, s.getFirstChild()), getVar(in, s.getNextNode())));
      }

      public void visitEmptyStm(EmptyStm s) {
        handleAssign(s, val.transferEmpty(s));
      }

      public void visitGapifyStm(GapifyStm s) {
        handleAssign(s, val.transferGapify(s, getVar(in, s.getBase())));
      }

      public void visitGetStm(GetStm s) {
        handleAssign(s, val.transferGet(s, getVar(in, s.getBase())));
      }

      public void visitInsertStm(InsertStm s) {
        handleAssign(s, val.transferInsert(s, getVar(in, s.getBase()), getVar(in, s.getXMLSource())));
      }

      public void visitNodeStm(NodeStm s) {
        handleAssign(s, val.transferNode(s, getVar(in, s.getFirstAttr()), getVar(in, s.getFirstChild()),
            getVar(in, s.getNextNode())));
      }

      public void visitPlugStm(PlugStm s) {
        handleAssign(s, val.transferPlug(s, getVar(in, s.getBase()),
            getVar(in, s.getXMLSource())));
      }

      public void visitRemoveStm(RemoveStm s) {
        handleAssign(s, val.transferRemove(s, getVar(in, s.getBase())));
      }

      public void visitSetStm(SetStm s) {
        handleAssign(s, val.transferSet(s, getVar(in, s.getBase()), getVar(in, s.getXMLSource())));
      }

      public void visitUnknownStm(UnknownStm s) {
        handleAssign(s, val.transferUnknown(s));
      }

      public void visitValidateStm(ValidateStm s) {
        handleAssign(s, val.transferValidate(s, getVar(in, s.getBase())));
      }

      public void visitVarStm(VarStm s) {
        if (s.getDest().getID() != s.getSource().getID())
          handleAssign(s, getVar(in, s.getSource()));
        else {
          changed[0] |= out.copyFrom(in);
        }
      }
     
      public void visitNopStm(NopStm s) {
        changed[0] = merge(in, new VariableFilter(true), out);
      }
      public void visitEscapeStm(EscapeStm s) {
        changed[0] = merge(in, new VariableFilter(true), out);
      }
     
      public void visitCheckStm(CheckStm s) {
        val.transferCheck(s, getVar(in, s.getBase()));
        changed[0] = merge(in, new VariableFilter(true), out);
      }
     
      // not in this phase
      // XXX it makes sense to support these, but VariableAnalysis is never used in a phase that uses them
      public void visitArrayReadStm(ArrayReadStm s) {
      }
      public void visitArrayWriteStm(ArrayWriteStm s) {
      }
      public void visitArrayWriteStringStm(ArrayWriteStringStm s) {
      }
      public void visitCallStm(CallStm s) {
      }
    });
    return changed[0];
  }
}
TOP

Related Classes of dk.brics.xact.analysis.dataflow.VariableAnalysis

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.