예제 #1
0
  private void insertCopy(TryCatchJoint joint) {
    Set<Variable> variableSet = new HashSet<>(joint.getSourceVariables());

    BasicBlock block = joint.getSource();
    DefinitionExtractor defExtractor = new DefinitionExtractor();
    for (int i = block.getInstructions().size() - 1; i >= 0; --i) {
      Instruction insn = block.getInstructions().get(i);
      insn.acceptVisitor(defExtractor);
      for (Variable definedVar : defExtractor.getDefinedVariables()) {
        if (variableSet.remove(definedVar)) {
          AssignInstruction copyInsn = new AssignInstruction();
          copyInsn.setReceiver(joint.getReceiver());
          copyInsn.setAssignee(definedVar);
          block.getInstructions().add(i, copyInsn);
        }
      }
    }

    for (Variable enteringVar : variableSet) {
      AssignInstruction copyInsn = new AssignInstruction();
      copyInsn.setReceiver(joint.getReceiver());
      copyInsn.setAssignee(enteringVar);
      block.getInstructions().add(0, copyInsn);
    }
  }
예제 #2
0
 private void removeRedundantCopies(
     Program program, List<MutableGraphNode> interferenceGraph, DisjointSet congruenceClasses) {
   for (int i = 0; i < program.basicBlockCount(); ++i) {
     BasicBlock block = program.basicBlockAt(i);
     for (int j = 0; j < block.getInstructions().size(); ++j) {
       Instruction insn = block.getInstructions().get(j);
       if (!(insn instanceof AssignInstruction)) {
         continue;
       }
       AssignInstruction assignment = (AssignInstruction) insn;
       boolean interfere = false;
       int copyClass = congruenceClasses.find(assignment.getReceiver().getIndex());
       int origClass = congruenceClasses.find(assignment.getAssignee().getIndex());
       for (MutableGraphEdge edge : interferenceGraph.get(origClass).getEdges()) {
         if (edge.getFirst() == edge.getSecond()) {
           continue;
         }
         int neighbour = congruenceClasses.find(edge.getSecond().getTag());
         if (neighbour == copyClass || neighbour == origClass) {
           interfere = true;
           break;
         }
       }
       if (!interfere) {
         int newClass = congruenceClasses.union(copyClass, origClass);
         block.getInstructions().set(j, new EmptyInstruction());
         if (newClass == interferenceGraph.size()) {
           MutableGraphNode newNode = new MutableGraphNode(interferenceGraph.size());
           interferenceGraph.add(newNode);
         }
         for (MutableGraphEdge edge :
             interferenceGraph.get(origClass).getEdges().toArray(new MutableGraphEdge[0])) {
           if (edge.getFirst() == interferenceGraph.get(origClass)) {
             edge.setFirst(interferenceGraph.get(newClass));
           }
           if (edge.getSecond() == interferenceGraph.get(origClass)) {
             edge.setSecond(interferenceGraph.get(newClass));
           }
         }
         for (MutableGraphEdge edge :
             interferenceGraph.get(copyClass).getEdges().toArray(new MutableGraphEdge[0])) {
           if (edge.getFirst() == interferenceGraph.get(copyClass)) {
             edge.setFirst(interferenceGraph.get(newClass));
           }
           if (edge.getSecond() == interferenceGraph.get(copyClass)) {
             edge.setSecond(interferenceGraph.get(newClass));
           }
         }
         interferenceGraph.set(copyClass, interferenceGraph.get(newClass));
         interferenceGraph.set(origClass, interferenceGraph.get(newClass));
       }
     }
   }
 }
예제 #3
0
 private DisjointSet buildPhiCongruenceClasses(Program program) {
   DisjointSet classes = new DisjointSet();
   for (int i = 0; i < program.variableCount(); ++i) {
     classes.create();
   }
   for (int i = 0; i < program.basicBlockCount(); ++i) {
     BasicBlock block = program.basicBlockAt(i);
     for (Phi phi : block.getPhis()) {
       for (Incoming incoming : phi.getIncomings()) {
         classes.union(phi.getReceiver().getIndex(), incoming.getValue().getIndex());
       }
     }
     for (TryCatchJoint joint : block.getTryCatchJoints()) {
       for (Variable sourceVar : joint.getSourceVariables()) {
         classes.union(sourceVar.getIndex(), joint.getReceiver().getIndex());
       }
     }
   }
   return classes;
 }
예제 #4
0
 Statement generateJumpStatement(BasicBlock target) {
   if (nextBlock == target && blockMap[target.getIndex()] == null) {
     return null;
   }
   Decompiler.Block block = blockMap[target.getIndex()];
   if (block == null) {
     throw new IllegalStateException("Could not find block for basic block $" + target.getIndex());
   }
   if (target.getIndex() == indexer.nodeAt(block.end)) {
     BreakStatement breakStmt = new BreakStatement();
     breakStmt.setLocation(currentLocation);
     breakStmt.setTarget(block.statement);
     return breakStmt;
   } else {
     ContinueStatement contStmt = new ContinueStatement();
     contStmt.setLocation(currentLocation);
     contStmt.setTarget(block.statement);
     return contStmt;
   }
 }
예제 #5
0
 private void insertCopy(Incoming incoming, Map<BasicBlock, BasicBlock> blockMap) {
   final Phi phi = incoming.getPhi();
   Program program = phi.getBasicBlock().getProgram();
   AssignInstruction copyInstruction = new AssignInstruction();
   Variable firstCopy = program.createVariable();
   copyInstruction.setReceiver(firstCopy);
   copyInstruction.setAssignee(incoming.getValue());
   BasicBlock source = blockMap.get(incoming.getSource());
   if (source == null) {
     source = incoming.getSource();
   } else {
     incoming.setSource(source);
   }
   if (!(incoming.getSource().getLastInstruction() instanceof JumpInstruction)) {
     final BasicBlock copyBlock = program.createBasicBlock();
     JumpInstruction jumpInstruction = new JumpInstruction();
     jumpInstruction.setTarget(phi.getBasicBlock());
     copyBlock.getInstructions().add(jumpInstruction);
     incoming
         .getSource()
         .getLastInstruction()
         .acceptVisitor(
             new BasicBlockMapper(
                 block -> block == phi.getBasicBlock().getIndex() ? copyBlock.getIndex() : block));
     blockMap.put(source, copyBlock);
     incoming.setSource(copyBlock);
     source = copyBlock;
   }
   source.getInstructions().add(source.getInstructions().size() - 1, copyInstruction);
   incoming.setValue(copyInstruction.getReceiver());
 }
예제 #6
0
 private void transformBasicBlock(BasicBlock block) {
   List<Instruction> instructions = block.getInstructions();
   for (int i = 0; i < instructions.size(); ++i) {
     Instruction insn = instructions.get(i);
     if (insn instanceof InvokeInstruction) {
       InvokeInstruction invoke = (InvokeInstruction) insn;
       List<Instruction> replacement = transformInvoke(invoke);
       if (replacement != null) {
         instructions.set(i, new EmptyInstruction());
         instructions.addAll(i, replacement);
         i += replacement.size();
       }
     }
   }
 }
예제 #7
0
 private void insertJointArgumentsCopies(Program program) {
   for (int i = 0; i < program.basicBlockCount(); ++i) {
     BasicBlock block = program.basicBlockAt(i);
     block.getTryCatchJoints().forEach(this::insertCopy);
   }
 }