Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /* Soot - a J*va Optimization Framework
    * Copyright (C) 2000 Feng Qian
    *
    * This library is free software; you can redistribute it and/or
    * modify it under the terms of the GNU Lesser General Public
    * License as published by the Free Software Foundation; either
    * version 2.1 of the License, or (at your option) any later version.
    *
    * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 02111-1307, USA.
   */
  
  /*
   * Modified by the Sable Research Group and others 1997-1999.  
   * See the 'credits' file distributed with Soot for the complete list of
   * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
   */
  
  package soot.jimple.toolkits.annotation.arraycheck;
  import soot.options.*;
  
  import soot.*;
  import soot.jimple.*;
  
  import java.util.*;
  
  {
  
      private final Map<FlowGraphEdgeWeightedDirectedSparseGraphedgeMap;
      private final Set<FlowGraphEdgeedgeSet;
  
      private HashMap<BlockIntegerstableRoundOfUnits;
  
      private ArrayRefBlockGraph graph;
  
      private final IntContainer zero = new IntContainer(0);
  
      private boolean fieldin = false;
      private HashMap<ObjectHashSet<Value>> localToFieldRef;
      private HashMap<ObjectHashSet<Value>> fieldToFieldRef;
      private final int strictness = 2;
  
      private boolean arrayin = false;
  
      private boolean csin = false;
      private HashMap<ValueHashSet<Value>> localToExpr;
  
      private boolean classfieldin = false;
      private ClassFieldAnalysis cfield;
  
      private boolean rectarray = false;
      private HashSet<Localrectarrayset;
      private HashSet<Localmultiarraylocals;
  
      private final ArrayIndexLivenessAnalysis ailanalysis;
  
      /* A little bit different from ForwardFlowAnalysis */
      public ArrayBoundsCheckerAnalysis(Body body
                                        boolean takeClassField,
                                        boolean takeFieldRef,
                                        boolean takeArrayRef,
                                        boolean takeCSE,
                                        boolean takeRectArray)
      {
           = takeClassField;
           = takeFieldRef;
           = takeArrayRef;
           = takeCSE;
           = takeRectArray;
          
          SootMethod thismethod = body.getMethod();
  
          if (Options.v().debug()) 
              G.v()..println("ArrayBoundsCheckerAnalysis started on  "+thismethod.getName());
  
          
          if ()
          {
              this. = .getLocalToFieldRef();
              this. = .getFieldToFieldRef();
          }
          
          if ()
          {
              if ()
              {
                  this. = .getMultiArrayLocals();
                 this. = new HashSet<Local>();
 
                 RectangularArrayFinder pgbuilder = RectangularArrayFinder.v();
 
                 Iterator<LocallocalIt = .iterator();
                 while (localIt.hasNext())
                 {
                     Local local = localIt.next();
                     
                     MethodLocal mlocal = new MethodLocal(thismethodlocal);
                     
                     if (pgbuilder.isRectangular(mlocal))
                         this..add(local);
                 }
             }
         }
         
         if ()
         {
             this. = .getLocalToExpr();
         }
 
         if ()
         {
             this. = ClassFieldAnalysis.v();    
         }
 
         this. = new ArrayRefBlockGraph(body);
 
          = new HashMap<BlockWeightedDirectedSparseGraph>(.size()*2+1, 0.7f);
         
          = new HashMap<FlowGraphEdgeWeightedDirectedSparseGraph>(.size()*2+1, 0.7f);
         
          = buildEdgeSet();
         
         doAnalysis();
         
         convertToUnitEntry();
         
         if (Options.v().debug()) 
             G.v()..println("ArrayBoundsCheckerAnalysis finished.");
     }
 
     private void convertToUnitEntry()
     {
         Iterator<BlockblockIt = .keySet().iterator();
         while (blockIt.hasNext())
         {
             Block block = blockIt.next();
             Unit first = block.getHead();
             .put(first.get(block));
         }
     }

    
buildEdgeSet creates a set of edges from directed graph.
 
     {
         HashSet<FlowGraphEdgeedges = new HashSet<FlowGraphEdge>();
 
         Iterator<BlockblockIt = dg.iterator();
         while (blockIt.hasNext())
         {
             Block s = blockIt.next();
 
             List<Blockpreds = .getPredsOf(s);
             List<Blocksuccs = .getSuccsOf(s);
 
             /* Head units has in edge from itself to itself.*/
             if (preds.size() == 0)
             {
                 edges.add(new FlowGraphEdge(s,s));
             }
             
             /* End units has out edge from itself to itself.*/
             if (succs.size() == 0)
             {
                 edges.add(new FlowGraphEdge(s,s));
             }
             else
             {
                 Iterator succIt = succs.iterator();
                 while (succIt.hasNext())
                 {
                     edges.add(new FlowGraphEdge(ssuccIt.next()));
                 }
             }
         }
         
         return edges;
     }
     
     public Object getFlowBefore(Object s)
     {
         return .get(s);
     }
 
     /* merge all preds' out set */
     private void mergebunch(Object ins[], Object sObject prevOutObject out)
     {
         WeightedDirectedSparseGraph prevgraph = (WeightedDirectedSparseGraph)prevOut,
             outgraph = (WeightedDirectedSparseGraph)out;
 
         WeightedDirectedSparseGraph[] ingraphs
             = new WeightedDirectedSparseGraph[ins.length];
 
         for (int i=0; i<ins.lengthi++)
             ingraphs[i] = (WeightedDirectedSparseGraph)ins[i];
 
         {
             outgraph.addBoundedAll(ingraphs[0]);
         
             for (int i=1; i<ingraphs.lengthi++)
             {
                 outgraph.unionSelf(ingraphs[i]);
                 outgraph.makeShortestPathGraph();
             }
                 
             //       if (flowStable)
             /*
             Integer round = (Integer)stableRoundOfUnits.get(s);
 
             if (round.intValue() < 2)
             {
                 stableRoundOfUnits.put(s, new Integer(round.intValue()+1));
             }
             else
             {
                 // To make output stable. compare with previous output value.
                 outgraph.wideEdges((WeightedDirectedSparseGraph)prevOut);
                 outgraph.makeShortestPathGraph();
             }
             */
 
             outgraph.widenEdges(prevgraph);
 
             //            outgraph.makeShortestPathGraph();        
             /*        
             for (int i=0; i<ins.length; i++)
             {
                 G.v().out.println("in " + i);
                 G.v().out.println(ins[i]);
             }
 
             G.v().out.println("out ");
             G.v().out.println(out);        
             */
         }
     }
 
     /* override ForwardFlowAnalysis
      */
     private void doAnalysis()
     {
         Date start = new Date();
         if (Options.v().debug())
             G.v()..println("Building PseudoTopological order list on "+start);
 
         LinkedList allUnits = (LinkedList)SlowPseudoTopologicalOrderer.v().newList(this.,false);
                         
         BoundedPriorityList changedUnits = 
             new BoundedPriorityList(allUnits);            
 
         //               LinkedList changedUnits = new LinkedList(allUnits);        
 
         Date finish = new Date();
         if (Options.v().debug())
         {
             long runtime = finish.getTime()-start.getTime();
             long mins = runtime/60000;
             long secs = (runtime%60000)/1000;
             G.v()..println("Building PseudoTopological order finished. "
                                +"It took "+mins+" mins and "+secs+" secs.");
         }
 
         start = new Date();
 
         HashSet changedUnitsSet = new HashSet(allUnits);
 
         List<ObjectchangedSuccs;
 
         /* An temporary object. */
         FlowGraphEdge tmpEdge = new FlowGraphEdge();
 
         /* If any output flow set has unknow value, it will be put in this set
          */
         HashSet<BlockunvisitedNodes = new HashSet<Block>(.size()*2+1, 0.7f);
 
         /* adjust livelocals set */
         {
             Iterator blockIt = .iterator();
             while (blockIt.hasNext())
             {
                 Block block = (Block)blockIt.next();
                 HashSet<IntContainerlivelocals = (HashSet<IntContainer>).getFlowBefore(block.getHead());
                 livelocals.add();
             }
         }
 
         /* Set initial values and nodes to visit. */
         {
              = new HashMap<BlockInteger>();
             
             Iterator it = .iterator();
 
             while(it.hasNext())
             {
                 Block block = (Block)it.next();
 
                 unvisitedNodes.add(block);
                 .put(blocknew Integer(0));
 
                 /* only take out the necessary node set. */
                 HashSet livelocals = (HashSet).getFlowBefore(block.getHead());
                 
                 .put(blocknew WeightedDirectedSparseGraph(livelocalsfalse));                
             }
 
             Iterator<FlowGraphEdgeedgeIt = .iterator();
             while (edgeIt.hasNext())
             {
                 FlowGraphEdge edge = edgeIt.next();
                 
                 Block target = (Block)edge.to;
                 HashSet livelocals = (HashSet).getFlowBefore(target.getHead());
                 
                 .put(edgenew WeightedDirectedSparseGraph(livelocalsfalse));
             }
         }
 
         /* perform customized initialization. */
         {
             List headlist = .getHeads();
             Iterator headIt = headlist.iterator();
 
             while (headIt.hasNext())
             {
                 Object head = headIt.next() ;
                 FlowGraphEdge edge = new FlowGraphEdge(headhead);
 
                 WeightedDirectedSparseGraph initgraph = 
                     .get(edge) ;
 
                 initgraph.setTop();
             }        
         }
 
         /* Perform fixed point flow analysis.
          */
         {
             WeightedDirectedSparseGraph beforeFlow = 
                 new WeightedDirectedSparseGraph(nullfalse);
 
             //            DebugMsg.counter1 += allUnits.size();
 
             while(!changedUnits.isEmpty())
             {
                 Block s = (BlockchangedUnits.removeFirst();
                 changedUnitsSet.remove(s);
 
                 // DebugMsg.counter2++;
 
                 /* previousAfterFlow, old-out, it is null initially */
                 WeightedDirectedSparseGraph previousBeforeFlow = 
                     .get(s);
                 
                 beforeFlow.setVertexes(previousBeforeFlow.getVertexes());
 
                 // Compute and store beforeFlow
                 {
                     List preds = .getPredsOf(s);
 
                     /* the init node */
                     if (preds.size() == 0)
                     {
                         tmpEdge.changeEndUnits(s,s);
                         copy(.get(tmpEdge), beforeFlow);
                     }
                     else if (preds.size() == 1)
                     {
                         tmpEdge.changeEndUnits(preds.get(0),s);
                         copy(.get(tmpEdge), beforeFlow);
                         
                         //                             widenGraphs(beforeFlow, previousBeforeFlow);
                     }
                     else 
                     {                    
                     /* has 2 or more preds, Updated by Feng. */
                         Object predFlows[] = new Object[preds.size()] ;
  
                         boolean allUnvisited = true;
                         Iterator predIt = preds.iterator();
                         
                         int index = 0 ;
 
                         int lastVisited = 0;
 
                         while(predIt.hasNext())
                         {
                             Object pred = predIt.next();
 
                                   tmpEdge.changeEndUnits(pred,s);
             
                             if (!unvisitedNodes.contains(pred))
                             {
                                 allUnvisited = false;
                                 lastVisited = index;
                             }
 
                             predFlows[index++] = .get(tmpEdge);
                               }
                         // put the visited node as the first one
 
                         if (allUnvisited)
                         {
                             G.v()..println("Warning : see all unvisited node");
                         }
                         else
                         {
                             Object tmp = predFlows[0];
                             predFlows[0] = predFlows[lastVisited];
                             predFlows[lastVisited] = tmp;
                         }
 
                         mergebunch(predFlowsspreviousBeforeFlowbeforeFlow); 
                     }
                     
                     copy(beforeFlowpreviousBeforeFlow);
                 }
 
                 /* Compute afterFlow and store it.
                  * Now we do not have afterFlow, we only have the out edges.
                  * Different out edges may have different flow set.
                  * It returns back a list of succ units that edge has been
                  * changed.
                  */
                 {
                     changedSuccs = flowThrough(beforeFlows);
                 }
 
                 {
                     for (int i = 0; i < changedSuccs.size(); i++)
                     {
                         Object succ = changedSuccs.get(i);
                         if (!changedUnitsSet.contains(succ))
                         {
                             changedUnits.add(succ);
                             changedUnitsSet.add(succ);
                         }
                     }
                 }
                 
                 /* Decide to remove or add unit from/to unvisitedNodes set */
                 {
                     unvisitedNodes.remove(s);
                 }
             }
         }
 
         finish = new Date();
         if (Options.v().debug())
         {
             long runtime = finish.getTime()-start.getTime();
             long mins = runtime/60000;
             long secs = (runtime/60000)/1000;
             G.v()..println("Doing analysis finished."
                                + " It took "+mins+" mins and "+secs"secs.");
         }
     }
 
     /* Flow go through a node, the output will be put into edgeMap, and also
      * the changed succ will be in a list to return back.
      */
     private List<ObjectflowThrough(Object inValueObject unit)
     {        
         ArrayList<ObjectchangedSuccs = new ArrayList<Object>();
       
         WeightedDirectedSparseGraph ingraph = 
             (WeightedDirectedSparseGraph)inValue;
 
         Block block = (Block)unit ;
 
         List succs = block.getSuccs();
 
         // leave out the last element.
         Unit s = block.getHead();
         Unit nexts = block.getSuccOf(s);
         while (nexts != null)
         {
             /* deal with array references */
             assertArrayRef(ingraphs);
 
             /* deal with normal expressions. */
             assertNormalExpr(ingraphs);
 
             s = nexts
             nexts = block.getSuccOf(nexts);
         }
 
         // at the end of block, it should update the out edges.
         if (s instanceof IfStmt)
         {
           if (!assertBranchStmt(ingraphsblocksuccschangedSuccs))
             updateOutEdges(ingraphblocksuccschangedSuccs);
         }
         else
         {
             assertArrayRef(ingraphs);
             assertNormalExpr(ingraphs);
             updateOutEdges(ingraphblocksuccschangedSuccs);
         }
 
         return changedSuccs;
     }
 
     private void assertArrayRef(Object inUnit unit)
     {
         if (!(unit instanceof AssignStmt))
             return;
 
         Stmt s = (Stmt)unit;
 
 
         /*
         ArrayRef op = null;
        
         Value leftOp = ((AssignStmt)s).getLeftOp();
         Value rightOp = ((AssignStmt)s).getRightOp();
 
         if (leftOp instanceof ArrayRef)
             op = (ArrayRef)leftOp;
 
         if (rightOp instanceof ArrayRef)
             op = (ArrayRef)rightOp;
 
         if (op == null)
             return;
         */
         
         if (!s.containsArrayRef())
             return;
 
         ArrayRef op = s.getArrayRef();
         
 
         Value base = (op).getBase();
         Value index = (op).getIndex();
 
         HashSet livelocals = (HashSet).getFlowAfter(s);
         if (!livelocals.contains(base) && !livelocals.contains(index))
             return;
         
         if (index instanceof IntConstant)
         {
             int weight = ((IntConstant)index).;
             weight = -1-weight;
 
             ingraph.addEdge(baseweight);
         }
         else
         {
             // add two edges.
             // index <= a.length -1;
             ingraph.addEdge(baseindex, -1);
 
             // index >= 0
             ingraph.addEdge(index, 0);
         }
     }
 
     private void assertNormalExpr(Object inUnit s)
     {
 
 
         /* If it is a contains invoke expr, the parameter should be analyzed. */
         if ()
         {
             Stmt stmt = (Stmt)s;
             if (stmt.containsInvokeExpr())
             {
                 HashSet tokills = new HashSet();
                 Value expr = stmt.getInvokeExpr();
                 List parameters = ((InvokeExpr)expr).getArgs();
                 
                 /* kill only the locals in hierarchy. */
                 if ( == 0)
                 {
                     Hierarchy hierarchy = Scene.v().getActiveHierarchy();
 
                     for (int i=0; i<parameters.size(); i++)
                     {
                         Value para = (Value)parameters.get(i);
                         Type type = para.getType();
                         if (type instanceof RefType)
                         {
                             SootClass pclass = ((RefType)type).getSootClass();
 
                             /* then we are looking for the possible types. */
                             Iterator<ObjectkeyIt = .keySet().iterator();
                             while (keyIt.hasNext())
                             {
                                 Value local = (Value)keyIt.next();
 
                                 Type ltype = local.getType();
                                 
                                 SootClass lclass = ((RefType)ltype).getSootClass();
 
                                 if (hierarchy.isClassSuperclassOfIncluding(pclasslclass) ||
                                     hierarchy.isClassSuperclassOfIncluding(lclasspclass))
                                 {
                                     HashSet toadd = .get(local);
                                     tokills.addAll(toadd);
                                 }                                    
                             }
                         }
                     }
                     
                     if (expr instanceof InstanceInvokeExpr)
                     {
                         Value base = ((InstanceInvokeExpr)expr).getBase();
                         Type type = base.getType();
                         if (type instanceof RefType)
                         {
                             SootClass pclass = ((RefType)type).getSootClass();
 
                             /* then we are looking for the possible types. */
                             Iterator<ObjectkeyIt = .keySet().iterator();
                             while (keyIt.hasNext())
                             {
                                 Value local = (Value)keyIt.next();
 
                                 Type ltype = local.getType();
                                 
                                 SootClass lclass = ((RefType)ltype).getSootClass();
 
                                 if (hierarchy.isClassSuperclassOfIncluding(pclasslclass) ||
                                     hierarchy.isClassSuperclassOfIncluding(lclasspclass))
                                 {
                                     HashSet toadd = .get(local);
                                     tokills.addAll(toadd);
                                 }                                    
                             }
                         }
                     }
                 }
                 else
                     /* kill all instance field reference. */ 
                 if ( == 1)
                 {
                     boolean killall = false;
                     if (expr instanceof InstanceInvokeExpr)
                         killall = true;
                     else
                     {
                         for (int i=0; i<parameters.size(); i++)
                         {
                             Value para = (Value)parameters.get(i);
                             if (para.getType() instanceof RefType)
                             {
                                 killall = true;
                                 break;
                             }
                         }
                     }
 
                     if (killall)
                     {
                         Iterator<ObjectkeyIt = .keySet().iterator();
                         while (keyIt.hasNext())
                         {
                             HashSet toadd = .get(keyIt.next());
                             tokills.addAll(toadd);
                         }                            
                     }
                 }
                 else
                 if ( == 2)
                 {
                     //                    tokills.addAll(allFieldRefs);
                     HashSet vertexes = ingraph.getVertexes();
                     Iterator nodeIt = vertexes.iterator();
                     while (nodeIt.hasNext())
                     {
                         Object node = nodeIt.next();
                         if (node instanceof FieldRef)
                             ingraph.killNode(node);
                     }
                 }
 
                 /*
                 Iterator killIt = tokills.iterator();
                 while (killIt.hasNext())
                     ingraph.killNode(killIt.next());
                 */
             }
         }
 
         if ()
         {
             Stmt stmt = (Stmt)s;
 
             if (stmt.containsInvokeExpr())
             {
                 if ( == 2)
                 {
                     /*
                     Iterator killIt = allArrayRefs.iterator();
                     while (killIt.hasNext())
                     {
                         ingraph.killNode(killIt.next());
                     }
                     */
                     HashSet vertexes = ingraph.getVertexes();
                     Iterator nodeIt = vertexes.iterator();
                     while (nodeIt.hasNext())
                     {
                         Object node = nodeIt.next();
                         if (node instanceof ArrayRef)
                             ingraph.killNode(node);
 
                         /*
                         if (rectarray)
                             if (node instanceof Array2ndDimensionSymbol)
                                 ingraph.killNode(node);
                         */
                     }
                 }
             }
         }
 
         if (!(s instanceof AssignStmt))
             return;
 
         Value leftOp = ((AssignStmt)s).getLeftOp();
         Value rightOp = ((AssignStmt)s).getRightOp();
 
 
         HashSet livelocals = (HashSet).getFlowAfter(s);
 
         if ()
         {
             if (leftOp instanceof Local)
             {
                 HashSet fieldrefs = .get(leftOp);
                 
                 if (fieldrefs != null)
                 {
                     Iterator refsIt = fieldrefs.iterator();
                     while (refsIt.hasNext())
                     {
                         Object ref = refsIt.next();
                         if (livelocals.contains(ref))
                             ingraph.killNode(ref);
                     }
                 }
             }
             else
             if (leftOp instanceof InstanceFieldRef)
             {
                 SootField field = ((InstanceFieldRef)leftOp).getField();
                 
                 HashSet fieldrefs = .get(field);
                 
                 if (fieldrefs != null)
                 {
                     Iterator refsIt = fieldrefs.iterator();
                     while (refsIt.hasNext())
                     {
                         Object ref = refsIt.next();
                         if (livelocals.contains(ref))
                             ingraph.killNode(ref);
                     }
                 }                
             }
         }
 
         if ()
         {
             /* a = ..;  kill all references of a;
                i = ..;  kill all references with index i;
             */
             if (leftOp instanceof Local)
             {
                 /*
                 HashSet arrayrefs = (HashSet)localToArrayRef.get(leftOp);
                 
                 if (arrayrefs != null)
                 {
                     Iterator refsIt = arrayrefs.iterator();
                     while (refsIt.hasNext())
                     {
                         Object ref = refsIt.next();
                         ingraph.killNode(ref);
                     }
                 }
                 */
                 HashSet vertexes = ingraph.getVertexes();
                 Iterator nodeIt = vertexes.iterator();
                 while (nodeIt.hasNext())
                 {
                     Object node = nodeIt.next();
                     if (node instanceof ArrayRef)
                     {
                         Value base = ((ArrayRef)node).getBase();
                         Value index = ((ArrayRef)node).getIndex();
                         
                         if (base.equals(leftOp) || index.equals(leftOp))
                             ingraph.killNode(node);                        
                     }
 
                     if ()
                     {
                         if (node instanceof Array2ndDimensionSymbol)
                         {
                             Object base = ((Array2ndDimensionSymbol)node).getVar();
                             if (base.equals(leftOp))
                                 ingraph.killNode(node);
                         }
                     }
                 }
             }
             else
                 /* kill all array references */
             if (leftOp instanceof ArrayRef)
             {
                 /*
                 Iterator allrefsIt = allArrayRefs.iterator();
                 while (allrefsIt.hasNext())
                 {
                     Object ref = allrefsIt.next();
                     ingraph.killNode(ref);
                 }
                 */
                 HashSet vertexes = ingraph.getVertexes();
                 {
                     Iterator nodeIt = vertexes.iterator();
                     while (nodeIt.hasNext())
                     {
                         Object node = nodeIt.next();
                         if (node instanceof ArrayRef)
                             ingraph.killNode(node);
                     }
                 }
 
                 /* only when multiarray was given a new value to its sub dimension, we kill all second dimensions of arrays */
                 /*
                 if (rectarray)
                 {
                     Value base = ((ArrayRef)leftOp).getBase();
 
                     if (multiarraylocals.contains(base))
                     {
                         Iterator nodeIt = vertexes.iterator();
                         while (nodeIt.hasNext())
                         {
                             Object node = nodeIt.next();
                             if (node instanceof Array2ndDimensionSymbol)
                                 ingraph.killNode(node);
                         }
                     }
                 }
                 */
             }
         }
 
         if ( !livelocals.contains(leftOp) && !livelocals.contains(rightOp))
             return;
 
         // i = i;
         if (rightOp.equals(leftOp))
             return;
 
         if ()
         {
             HashSet exprs = .get(leftOp);
             if (exprs != null)
             {
                 Iterator exprIt = exprs.iterator();
                 while (exprIt.hasNext())
                 {
                     ingraph.killNode(exprIt.next());
                 }
             }
         }
 
 
         // i = i + c; is special
         if (rightOp instanceof AddExpr)
         {
             Value op1 = ((AddExpr)rightOp).getOp1();
             Value op2 = ((AddExpr)rightOp).getOp2();
 
             if (op1 == leftOp && op2 instanceof IntConstant)
             {
                 int inc_w = ((IntConstant)op2).;
                 ingraph.updateWeight(leftOpinc_w);
                 return;
             }
             else
             if (op2 == leftOp && op1 instanceof IntConstant)
             {
                 int inc_w = ((IntConstant)op1).;
                 ingraph.updateWeight(leftOpinc_w);
                 return;
             }
         }
         
         // i = i - c; is also special
         if (rightOp instanceof SubExpr)
         {
             Value op1 = ((SubExpr)rightOp).getOp1();
             Value op2 = ((SubExpr)rightOp).getOp2();
 
             if ((op1 == leftOp) && (op2 instanceof IntConstant))
             {
                 int inc_w = - ((IntConstant)op2).;
                 ingraph.updateWeight(leftOpinc_w);
                 return;
             }
         }
 
         // i = j; i = j + c; i = c + j; need two operations, kill node and add new relationship.
         // kill left hand side,
 
         ingraph.killNode(leftOp);
 
         // add new relationship.
 
         // i = c;
         if (rightOp instanceof IntConstant)
         {
             int inc_w = ((IntConstant)rightOp).;
             ingraph.addMutualEdges(leftOpinc_w);
             return;
         }
 
         // i = j;
         if (rightOp instanceof Local)
         {
             ingraph.addMutualEdges(rightOpleftOp, 0);
             return;
         }
 
         if (rightOp instanceof FieldRef)
         {
             if ()
             {
                 ingraph.addMutualEdges(rightOpleftOp, 0);
             }
 
             if ()
             {            
                 SootField field = ((FieldRef)rightOp).getField();
                 IntValueContainer flength = (IntValueContainer).getFieldInfo(field);
 
                 if (flength != null)
                 {
                     if (flength.isInteger())
                     {
                         ingraph.addMutualEdges(leftOpflength.getValue());
                     }
                 }        
             }
 
             return;
         }
 
         /*
         if (rectarray)
         {
             Type leftType = leftOp.getType();
 
             if ((leftType instanceof ArrayType) && (rightOp instanceof ArrayRef))
             {
                 Local base = (Local)((ArrayRef)rightOp).getBase();
                 
                 SymbolArrayLength sv = (SymbolArrayLength)lra_analysis.getSymbolLengthAt(base, s);
                 if (sv != null)
                 {
                     ingraph.addMutualEdges(leftOp, sv.next(), 0);
                 }
             }
         }
         */
 
         if ()
         {
             if (rightOp instanceof ArrayRef)
             {
                 ingraph.addMutualEdges(rightOpleftOp, 0);
 
                 if ()
                 {
                     Value base = ((ArrayRef)rightOp).getBase();
 
                     if (.contains(base))
                     {
                        ingraph.addMutualEdges(leftOp, Array2ndDimensionSymbol.v(base), 0);
                    }
                }
                return;
            }
        }
        if ()
        {
            Value rhs = rightOp;
            if (rhs instanceof BinopExpr)
            {
                Value op1 = ((BinopExpr)rhs).getOp1();
                Value op2 = ((BinopExpr)rhs).getOp2();
                if (rhs instanceof AddExpr)
                {
                    if ((op1 instanceof Local) &&
                        (op2 instanceof Local))
                    {
                        ingraph.addMutualEdges(rhsleftOp, 0);
                        return;
                    }
                }
                else
                if (rhs instanceof MulExpr)
                {
                    if ((op1 instanceof Local) ||
                        (op2 instanceof Local))
                    {
                        ingraph.addMutualEdges(rhsleftOp, 0);
                        return;
                    }                    
                }
                else
                if (rhs instanceof SubExpr)
                {
                    if (op2 instanceof Local)
                    {
                        ingraph.addMutualEdges(rhsleftOp, 0);
                        return;
                    }
                }
            }
        }
        // i = j + c; or i = c + j;
        if (rightOp instanceof AddExpr)
        {
            Value op1 = ((AddExpr)rightOp).getOp1();
            Value op2 = ((AddExpr)rightOp).getOp2();
            if ( (op1 instanceof Local) && (op2 instanceof IntConstant) )
            {
                int inc_w = ((IntConstant)op2).;
                ingraph.addMutualEdges(op1leftOpinc_w);
                return;
            }
            if ( (op2 instanceof Local) && (op1 instanceof IntConstant) )
            {
                int inc_w = ((IntConstant)op1).;
                ingraph.addMutualEdges(op2leftOpinc_w);
                return;
            }
        }
        // only i = j - c was considered. 
        if (rightOp instanceof SubExpr)
        {
            Value op1 = ((SubExpr)rightOp).getOp1();
            Value op2 = ((SubExpr)rightOp).getOp2();
            if ((op1 instanceof Local) && (op2 instanceof IntConstant))
            {
                int inc_w = - ((IntConstant)op2).;
                ingraph.addMutualEdges(op1leftOpinc_w);
                return;
            }
        }
        
        // new experessions can also generate relationship
        // a = new A[i]; a = new A[c];
        if (rightOp instanceof NewArrayExpr)
        {
            Value size = ((NewArrayExpr)rightOp).getSize();
            if (size instanceof Local)
            {
                ingraph.addMutualEdges(sizeleftOp, 0);
                return;
            }
            if (size instanceof IntConstant)
            {
                int inc_w = ((IntConstant)size).;
                ingraph.addMutualEdges(leftOpinc_w);