Package dk.brics.xact.analysis.transformations

Source Code of dk.brics.xact.analysis.transformations.FieldTransformer

package dk.brics.xact.analysis.transformations;

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

import dk.brics.xact.analysis.Debug;
import dk.brics.xact.analysis.flowgraph.Edge;
import dk.brics.xact.analysis.flowgraph.FlowGraph;
import dk.brics.xact.analysis.flowgraph.Statement;
import dk.brics.xact.analysis.flowgraph.Variable;
import dk.brics.xact.analysis.flowgraph.VariableFilter;
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;

/**
* Flow graph transformation for globally linking field variables.
* For each field variable, a nop node is created.
* Edges labeled with the variable are inserted from all definitions to the join node,
* and from the join node to all uses.
* The variable is removed from the labels of all edges out of use and def sites
* to restrict its flow to the new edges.
*/
public class FieldTransformer {

  /**
   * Constructs a new <code>FieldTransformer</code>.
   */
  public FieldTransformer() {}

  /**
   * Transforms the given flow graph.
   */
  public void run(final FlowGraph graph) {
    final Map<Variable,Statement> global_use = new HashMap<Variable,Statement>();
   
    // find all uses of field variables
    for (Statement s : new LinkedHashSet<Statement>(graph.getNodes()))
      s.visitBy(new StatementVisitor() {
       
        private void use(Variable v, Statement s) {
          if (v.isGlobal()) {
            Statement join = global_use.get(v);
            if (join == null) {
              // make new join node
              Debug.println(6, true, "Making join node for " + v + " (used in " + s + ")");
              join = new NopStm(s.getOrigin());
              graph.addNode(join);
              global_use.put(v, join);
//              Statement ea = new EmptyStm(v, s.getOrigin()); // initialisation value for the global var
//              graph.addNode(ea);
//              graph.addEntry(ea);
            }
            // add use edge
            graph.addEdge(join, s, new VariableFilter(v));
            // remove the variable from the outflow of the statement
            for (Edge<Statement,VariableFilter> edge : graph.getOutEdges(s))
              edge.getData().removeVariable(v);
          }
        }

        public void visitAnalyzeStm(AnalyzeStm s) {
          use(s.getBase(), s);
        }

        public void visitConcatStm(ConcatStm s) {
          use(s.getXMLSource(), s);
        }

        public void visitConstStm(ConstStm s) {
          // do nothing
        }

        public void visitCopyStm(CopyStm s) {
          use(s.getBase(), s);
          if (s.getFirstChild() != null)
            use(s.getFirstChild(), s);
          if (s.getFirstAttr() != null)
            use(s.getFirstAttr(), s);
          if (s.getNextNode() != null)
            use(s.getNextNode(), s);
        }

        public void visitCastStm(CastStm s) {
          use(s.getBase(), s);
        }

        public void visitCheckStm(CheckStm s) {
          if (s.getBase() != null)
            use(s.getBase(), s);
        }

        public void visitEmptyStm(EmptyStm s) {
          // do nothing
        }

        public void visitGapifyStm(GapifyStm s) {
          use(s.getBase(), s);
        }

        public void visitGetStm(GetStm s) {
          use(s.getBase(), s);
        }

        public void visitInsertStm(InsertStm s) {
          use(s.getBase(), s);
          if (s.getXMLSource() != null)
            use(s.getXMLSource(), s);
        }

        public void visitNodeStm(NodeStm s) {
          if (s.getFirstChild() != null)
            use(s.getFirstChild(), s);
          if (s.getFirstAttr() != null)
            use(s.getFirstAttr(), s);
          if (s.getNextNode() != null)
            use(s.getNextNode(), s);
        }

        public void visitNopStm(NopStm s) {
          // do nothing
        }

        public void visitPlugStm(PlugStm s) {
          use(s.getBase(), s);
          if (s.getXMLSource() != null)
            use(s.getXMLSource(), s);
        }

        public void visitRemoveStm(RemoveStm s) {
          use(s.getBase(), s);
        }

        public void visitSetStm(SetStm s) {
          use(s.getBase(), s);
          if (s.getXMLSource() != null)
            use(s.getXMLSource(), s);
        }

        public void visitUnknownStm(UnknownStm s) {
          // do nothing
        }

        public void visitValidateStm(ValidateStm s) {
          if (s.getBase() != null)
            use(s.getBase(), s);
        }

        public void visitVarStm(VarStm s) {
          use(s.getSource(), s);
        }
       
        // not in this phase
        public void visitArrayReadStm(ArrayReadStm s) {
        }
        public void visitArrayWriteStm(ArrayWriteStm s) {
        }
        public void visitArrayWriteStringStm(ArrayWriteStringStm s) {
        }
        public void visitCallStm(CallStm s) {
        }
        public void visitEscapeStm(EscapeStm s) {
        }
      });
   
    // insert edges from definitions to single global use
    for (Statement s : new LinkedHashSet<Statement>(graph.getNodes()))
      if (s instanceof Assignment) {
        Variable v = ((Assignment)s).getDest();
        if (v.isGlobal()) {
          Debug.println(6, true, "Redirecting join flow edge for " + v + " (assigned in " + s + ")");
          // remove the variable from the outflow of the statement
          for (Edge<Statement,VariableFilter> edge : graph.getOutEdges(s))
            edge.getData().removeVariable(v);
          // insert new edge to the single global use (which only exists if it is used somewhere)
          if (global_use.containsKey(v)) {
            graph.addEdge(s, global_use.get(v), new VariableFilter(v));
          }
        }
      }
  }
}
TOP

Related Classes of dk.brics.xact.analysis.transformations.FieldTransformer

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.