Пример #1
0
 @Override
 protected void handleSpillSlot(Interval interval) {
   assert interval.location() != null : "interval  not assigned " + interval;
   if (interval.canMaterialize()) {
     assert !isStackSlot(interval.location())
         : "interval can materialize but assigned to a stack slot " + interval;
     return;
   }
   assert isStackSlot(interval.location()) : "interval not assigned to a stack slot " + interval;
   try (Scope s1 = Debug.scope("LSRAOptimization")) {
     Debug.log("adding stack to unhandled list %s", interval);
     unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Stack, interval);
   }
 }
Пример #2
0
  private boolean optimize(
      int currentPos,
      AbstractBlock<?> currentBlock,
      Interval currentInterval,
      RegisterBinding binding) {
    // BEGIN initialize and sanity checks
    assert currentBlock != null : "block must not be null";
    assert currentInterval != null : "interval must not be null";

    assert currentBlock.getPredecessorCount() == 1
        : "more than one predecessors -> optimization not possible";

    if (!currentInterval.isSplitChild()) {
      // interval is not a split child -> no need for optimization
      return false;
    }

    if (currentInterval.from() == currentPos) {
      // the interval starts at the current position so no need for splitting
      return false;
    }

    // get current location
    AllocatableValue currentLocation = currentInterval.location();
    assert currentLocation != null : "active intervals must have a location assigned!";

    // get predecessor stuff
    AbstractBlock<?> predecessorBlock = currentBlock.getPredecessors().get(0);
    int predEndId = allocator.getLastLirInstructionId(predecessorBlock);
    Interval predecessorInterval = currentInterval.getIntervalCoveringOpId(predEndId);
    assert predecessorInterval != null
        : "variable not live at the end of the only predecessor! "
            + predecessorBlock
            + " -> "
            + currentBlock
            + " interval: "
            + currentInterval;
    AllocatableValue predecessorLocation = predecessorInterval.location();
    assert predecessorLocation != null : "handled intervals must have a location assigned!";

    // END initialize and sanity checks

    if (currentLocation.equals(predecessorLocation)) {
      // locations are already equal -> nothing to optimize
      return false;
    }

    if (!isStackSlot(predecessorLocation) && !isRegister(predecessorLocation)) {
      assert predecessorInterval.canMaterialize();
      // value is materialized -> no need for optimization
      return false;
    }

    assert isStackSlot(currentLocation) || isRegister(currentLocation)
        : "current location not a register or stack slot " + currentLocation;

    try (Indent indent =
        Debug.logAndIndent("location differs: %s vs. %s", predecessorLocation, currentLocation)) {
      // split current interval at current position
      Debug.log("splitting at position %d", currentPos);

      assert allocator.isBlockBegin(currentPos) && ((currentPos & 1) == 0)
          : "split pos must be even when on block boundary";

      Interval splitPart = currentInterval.split(currentPos, allocator);
      activeLists.remove(binding, currentInterval);

      assert splitPart.from() >= currentPosition
          : "cannot append new interval before current walk position";

      // the currentSplitChild is needed later when moves are inserted for reloading
      assert splitPart.currentSplitChild() == currentInterval
          : "overwriting wrong currentSplitChild";
      splitPart.makeCurrentSplitChild();

      if (Debug.isLogEnabled()) {
        Debug.log("left interval  : %s", currentInterval.logString(allocator));
        Debug.log("right interval : %s", splitPart.logString(allocator));
      }

      if (Options.LSRAOptSplitOnly.getValue()) {
        // just add the split interval to the unhandled list
        unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart);
      } else {
        if (isRegister(predecessorLocation)) {
          splitRegisterInterval(splitPart, asRegister(predecessorLocation));
        } else {
          assert isStackSlot(predecessorLocation);
          Debug.log("assigning interval %s to %s", splitPart, predecessorLocation);
          splitPart.assignLocation(predecessorLocation);
          // activate interval
          activeLists.addToListSortedByCurrentFromPositions(RegisterBinding.Stack, splitPart);
          splitPart.state = State.Active;

          splitStackInterval(splitPart);
        }
      }
    }
    return true;
  }