예제 #1
0
  private int repeatInternal(
      @NotNull PseudocodeImpl originalPseudocode,
      @Nullable Label startLabel,
      @Nullable Label finishLabel,
      int labelCount) {
    Integer startIndex =
        startLabel != null
            ? ((PseudocodeLabel) startLabel).getTargetInstructionIndex()
            : Integer.valueOf(0);
    assert startIndex != null;
    Integer finishIndex =
        finishLabel != null
            ? ((PseudocodeLabel) finishLabel).getTargetInstructionIndex()
            : Integer.valueOf(originalPseudocode.mutableInstructionList.size());
    assert finishIndex != null;

    Map<Label, Label> originalToCopy = Maps.newLinkedHashMap();
    Multimap<Instruction, Label> originalLabelsForInstruction = HashMultimap.create();
    for (PseudocodeLabel label : originalPseudocode.labels) {
      Integer index = label.getTargetInstructionIndex();
      if (index == null) continue; // label is not bounded yet
      if (label == startLabel || label == finishLabel) continue;

      if (startIndex <= index && index <= finishIndex) {
        originalToCopy.put(label, label.copy(labelCount++));
        originalLabelsForInstruction.put(getJumpTarget(label), label);
      }
    }
    for (Label label : originalToCopy.values()) {
      labels.add((PseudocodeLabel) label);
    }
    for (int index = startIndex; index < finishIndex; index++) {
      Instruction originalInstruction = originalPseudocode.mutableInstructionList.get(index);
      repeatLabelsBindingForInstruction(
          originalInstruction, originalToCopy, originalLabelsForInstruction);
      Instruction copy = copyInstruction(originalInstruction, originalToCopy);
      addInstruction(copy);
      if (originalInstruction == originalPseudocode.errorInstruction
          && copy instanceof SubroutineExitInstruction) {
        errorInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.exitInstruction
          && copy instanceof SubroutineExitInstruction) {
        exitInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.sinkInstruction
          && copy instanceof SubroutineSinkInstruction) {
        sinkInstruction = (SubroutineSinkInstruction) copy;
      }
    }
    if (finishIndex < mutableInstructionList.size()) {
      repeatLabelsBindingForInstruction(
          originalPseudocode.mutableInstructionList.get(finishIndex),
          originalToCopy,
          originalLabelsForInstruction);
    }
    return labelCount;
  }
예제 #2
0
 @NotNull
 private static List<Label> copyLabels(
     Collection<Label> labels, Map<Label, Label> originalToCopy) {
   List<Label> newLabels = Lists.newArrayList();
   for (Label label : labels) {
     Label newLabel = originalToCopy.get(label);
     newLabels.add(newLabel != null ? newLabel : label);
   }
   return newLabels;
 }
예제 #3
0
 private void collectAndCacheReachableInstructions() {
   Set<Instruction> reachableInstructions = collectReachableInstructions();
   for (Instruction instruction : mutableInstructionList) {
     if (reachableInstructions.contains(instruction)) {
       instructions.add(instruction);
     }
   }
   markDeadInstructions();
 }
예제 #4
0
 @NotNull
 @Override
 public List<Instruction> getReversedInstructions() {
   LinkedHashSet<Instruction> traversedInstructions = Sets.newLinkedHashSet();
   PseudocodeTraverserKt.traverseFollowingInstructions(
       sinkInstruction, traversedInstructions, BACKWARD, null);
   if (traversedInstructions.size() < instructions.size()) {
     List<Instruction> simplyReversedInstructions = Lists.newArrayList(instructions);
     Collections.reverse(simplyReversedInstructions);
     for (Instruction instruction : simplyReversedInstructions) {
       if (!traversedInstructions.contains(instruction)) {
         PseudocodeTraverserKt.traverseFollowingInstructions(
             instruction, traversedInstructions, BACKWARD, null);
       }
     }
   }
   return Lists.newArrayList(traversedInstructions);
 }
예제 #5
0
  /*package*/ void addInstruction(Instruction instruction) {
    mutableInstructionList.add(instruction);
    instruction.setOwner(this);

    if (instruction instanceof KtElementInstruction) {
      KtElementInstruction elementInstruction = (KtElementInstruction) instruction;
      representativeInstructions.put(elementInstruction.getElement(), instruction);
    }

    if (instruction instanceof MergeInstruction) {
      addMergedValues((MergeInstruction) instruction);
    }

    for (PseudoValue inputValue : instruction.getInputValues()) {
      addValueUsage(inputValue, instruction);
      for (PseudoValue mergedValue : getMergedValues(inputValue)) {
        addValueUsage(mergedValue, instruction);
      }
    }
    if (PseudocodeUtilsKt.calcSideEffectFree(instruction)) {
      sideEffectFree.add(instruction);
    }
  }
예제 #6
0
 @NotNull
 private Instruction getNextPosition(int currentPosition) {
   int targetPosition = currentPosition + 1;
   assert targetPosition < mutableInstructionList.size() : currentPosition;
   return mutableInstructionList.get(targetPosition);
 }
예제 #7
0
 /*package*/ void bindLabel(Label label) {
   ((PseudocodeLabel) label).setTargetInstructionIndex(mutableInstructionList.size());
 }
예제 #8
0
 @Override
 @NotNull
 public SubroutineEnterInstruction getEnterInstruction() {
   return (SubroutineEnterInstruction) mutableInstructionList.get(0);
 }
예제 #9
0
 /*package*/ PseudocodeLabel createLabel(@NotNull String name, @Nullable String comment) {
   PseudocodeLabel label = new PseudocodeLabel(name, comment);
   labels.add(label);
   return label;
 }