Mercurial > hg > truffle
comparison graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java @ 20994:68ff637e95b1
Merge
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Thu, 16 Apr 2015 17:09:06 +0200 |
parents | abc059cb0acf |
children | d15ee06d36d0 |
comparison
equal
deleted
inserted
replaced
20993:ec36daea3cf0 | 20994:68ff637e95b1 |
---|---|
552 | 552 |
553 if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) { | 553 if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) { |
554 // move target is a stack slot that is always correct, so eliminate | 554 // move target is a stack slot that is always correct, so eliminate |
555 // instruction | 555 // instruction |
556 if (Debug.isLogEnabled()) { | 556 if (Debug.isLogEnabled()) { |
557 Debug.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult())); | 557 if (Debug.isLogEnabled()) { |
558 Debug.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult())); | |
559 } | |
558 } | 560 } |
559 // null-instructions are deleted by assignRegNum | 561 // null-instructions are deleted by assignRegNum |
560 instructions.set(j, null); | 562 instructions.set(j, null); |
561 } | 563 } |
562 | 564 |
580 assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState(); | 582 assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState(); |
581 assert isStackSlotValue(toLocation) : "to operand must be a stack slot"; | 583 assert isStackSlotValue(toLocation) : "to operand must be a stack slot"; |
582 | 584 |
583 insertionBuffer.append(j + 1, getSpillMoveFactory().createMove(toLocation, fromLocation)); | 585 insertionBuffer.append(j + 1, getSpillMoveFactory().createMove(toLocation, fromLocation)); |
584 | 586 |
585 Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId); | 587 if (Debug.isLogEnabled()) { |
588 Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId); | |
589 } | |
586 } | 590 } |
587 interval = interval.next; | 591 interval = interval.next; |
588 } | 592 } |
589 } | 593 } |
590 } // end of instruction iteration | 594 } // end of instruction iteration |
610 | 614 |
611 assert temp.spillSlot() != null || temp.canMaterialize() : "interval has no spill slot assigned"; | 615 assert temp.spillSlot() != null || temp.canMaterialize() : "interval has no spill slot assigned"; |
612 assert temp.spillDefinitionPos() >= temp.from() : "invalid order"; | 616 assert temp.spillDefinitionPos() >= temp.from() : "invalid order"; |
613 assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized"; | 617 assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized"; |
614 | 618 |
615 Debug.log("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos()); | 619 if (Debug.isLogEnabled()) { |
620 Debug.log("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos()); | |
621 } | |
616 | 622 |
617 prev = temp; | 623 prev = temp; |
618 temp = temp.next; | 624 temp = temp.next; |
619 } | 625 } |
620 } | 626 } |
693 ValueConsumer useConsumer = (operand, mode, flags) -> { | 699 ValueConsumer useConsumer = (operand, mode, flags) -> { |
694 if (isVariable(operand)) { | 700 if (isVariable(operand)) { |
695 int operandNum = operandNumber(operand); | 701 int operandNum = operandNumber(operand); |
696 if (!liveKill.get(operandNum)) { | 702 if (!liveKill.get(operandNum)) { |
697 liveGen.set(operandNum); | 703 liveGen.set(operandNum); |
698 Debug.log("liveGen for operand %d", operandNum); | 704 if (Debug.isLogEnabled()) { |
705 Debug.log("liveGen for operand %d", operandNum); | |
706 } | |
699 } | 707 } |
700 if (block.getLoop() != null) { | 708 if (block.getLoop() != null) { |
701 intervalInLoop.setBit(operandNum, block.getLoop().getIndex()); | 709 intervalInLoop.setBit(operandNum, block.getLoop().getIndex()); |
702 } | 710 } |
703 } | 711 } |
709 ValueConsumer stateConsumer = (operand, mode, flags) -> { | 717 ValueConsumer stateConsumer = (operand, mode, flags) -> { |
710 if (isVariableOrRegister(operand)) { | 718 if (isVariableOrRegister(operand)) { |
711 int operandNum = operandNumber(operand); | 719 int operandNum = operandNumber(operand); |
712 if (!liveKill.get(operandNum)) { | 720 if (!liveKill.get(operandNum)) { |
713 liveGen.set(operandNum); | 721 liveGen.set(operandNum); |
714 Debug.log("liveGen in state for operand %d", operandNum); | 722 if (Debug.isLogEnabled()) { |
723 Debug.log("liveGen in state for operand %d", operandNum); | |
724 } | |
715 } | 725 } |
716 } | 726 } |
717 }; | 727 }; |
718 ValueConsumer defConsumer = (operand, mode, flags) -> { | 728 ValueConsumer defConsumer = (operand, mode, flags) -> { |
719 if (isVariable(operand)) { | 729 if (isVariable(operand)) { |
720 int varNum = operandNumber(operand); | 730 int varNum = operandNumber(operand); |
721 liveKill.set(varNum); | 731 liveKill.set(varNum); |
722 Debug.log("liveKill for operand %d", varNum); | 732 if (Debug.isLogEnabled()) { |
733 Debug.log("liveKill for operand %d", varNum); | |
734 } | |
723 if (block.getLoop() != null) { | 735 if (block.getLoop() != null) { |
724 intervalInLoop.setBit(varNum, block.getLoop().getIndex()); | 736 intervalInLoop.setBit(varNum, block.getLoop().getIndex()); |
725 } | 737 } |
726 } | 738 } |
727 | 739 |
752 blockSets.liveGen = liveGen; | 764 blockSets.liveGen = liveGen; |
753 blockSets.liveKill = liveKill; | 765 blockSets.liveKill = liveKill; |
754 blockSets.liveIn = new BitSet(liveSize); | 766 blockSets.liveIn = new BitSet(liveSize); |
755 blockSets.liveOut = new BitSet(liveSize); | 767 blockSets.liveOut = new BitSet(liveSize); |
756 | 768 |
757 Debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen); | 769 if (Debug.isLogEnabled()) { |
758 Debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill); | 770 Debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen); |
771 Debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill); | |
772 } | |
759 | 773 |
760 } | 774 } |
761 } // end of block iteration | 775 } // end of block iteration |
762 } | 776 } |
763 | 777 |
843 liveIn.clear(); | 857 liveIn.clear(); |
844 liveIn.or(blockSets.liveOut); | 858 liveIn.or(blockSets.liveOut); |
845 liveIn.andNot(blockSets.liveKill); | 859 liveIn.andNot(blockSets.liveKill); |
846 liveIn.or(blockSets.liveGen); | 860 liveIn.or(blockSets.liveGen); |
847 | 861 |
848 Debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); | 862 if (Debug.isLogEnabled()) { |
863 Debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); | |
864 } | |
849 } | 865 } |
850 } | 866 } |
851 iterationCount++; | 867 iterationCount++; |
852 | 868 |
853 if (changeOccurred && iterationCount > 50) { | 869 if (changeOccurred && iterationCount > 50) { |
981 interval.addRange(from, to); | 997 interval.addRange(from, to); |
982 | 998 |
983 // Register use position at even instruction id. | 999 // Register use position at even instruction id. |
984 interval.addUsePos(to & ~1, registerPriority); | 1000 interval.addUsePos(to & ~1, registerPriority); |
985 | 1001 |
986 Debug.log("add use: %s, from %d to %d (%s)", interval, from, to, registerPriority.name()); | 1002 if (Debug.isLogEnabled()) { |
1003 Debug.log("add use: %s, from %d to %d (%s)", interval, from, to, registerPriority.name()); | |
1004 } | |
987 } | 1005 } |
988 | 1006 |
989 void addTemp(AllocatableValue operand, int tempPos, RegisterPriority registerPriority, LIRKind kind) { | 1007 void addTemp(AllocatableValue operand, int tempPos, RegisterPriority registerPriority, LIRKind kind) { |
990 if (!isProcessed(operand)) { | 1008 if (!isProcessed(operand)) { |
991 return; | 1009 return; |
998 | 1016 |
999 interval.addRange(tempPos, tempPos + 1); | 1017 interval.addRange(tempPos, tempPos + 1); |
1000 interval.addUsePos(tempPos, registerPriority); | 1018 interval.addUsePos(tempPos, registerPriority); |
1001 interval.addMaterializationValue(null); | 1019 interval.addMaterializationValue(null); |
1002 | 1020 |
1003 Debug.log("add temp: %s tempPos %d (%s)", interval, tempPos, RegisterPriority.MustHaveRegister.name()); | 1021 if (Debug.isLogEnabled()) { |
1022 Debug.log("add temp: %s tempPos %d (%s)", interval, tempPos, RegisterPriority.MustHaveRegister.name()); | |
1023 } | |
1004 } | 1024 } |
1005 | 1025 |
1006 boolean isProcessed(Value operand) { | 1026 boolean isProcessed(Value operand) { |
1007 return !isRegister(operand) || attributes(asRegister(operand)).isAllocatable(); | 1027 return !isRegister(operand) || attributes(asRegister(operand)).isAllocatable(); |
1008 } | 1028 } |
1028 } else { | 1048 } else { |
1029 // Dead value - make vacuous interval | 1049 // Dead value - make vacuous interval |
1030 // also add register priority for dead intervals | 1050 // also add register priority for dead intervals |
1031 interval.addRange(defPos, defPos + 1); | 1051 interval.addRange(defPos, defPos + 1); |
1032 interval.addUsePos(defPos, registerPriority); | 1052 interval.addUsePos(defPos, registerPriority); |
1033 Debug.log("Warning: def of operand %s at %d occurs without use", operand, defPos); | 1053 if (Debug.isLogEnabled()) { |
1054 Debug.log("Warning: def of operand %s at %d occurs without use", operand, defPos); | |
1055 } | |
1034 } | 1056 } |
1035 | 1057 |
1036 changeSpillDefinitionPos(interval, defPos); | 1058 changeSpillDefinitionPos(interval, defPos); |
1037 if (registerPriority == RegisterPriority.None && interval.spillState().ordinal() <= SpillState.StartInMemory.ordinal()) { | 1059 if (registerPriority == RegisterPriority.None && interval.spillState().ordinal() <= SpillState.StartInMemory.ordinal()) { |
1038 // detection of method-parameters and roundfp-results | 1060 // detection of method-parameters and roundfp-results |
1039 interval.setSpillState(SpillState.StartInMemory); | 1061 interval.setSpillState(SpillState.StartInMemory); |
1040 } | 1062 } |
1041 interval.addMaterializationValue(LinearScan.getMaterializedValue(op, operand, interval)); | 1063 interval.addMaterializationValue(LinearScan.getMaterializedValue(op, operand, interval)); |
1042 | 1064 |
1043 Debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name()); | 1065 if (Debug.isLogEnabled()) { |
1066 Debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name()); | |
1067 } | |
1044 } | 1068 } |
1045 | 1069 |
1046 /** | 1070 /** |
1047 * Determines the register priority for an instruction's output/result operand. | 1071 * Determines the register priority for an instruction's output/result operand. |
1048 */ | 1072 */ |
1090 if (DetailedAsserts.getValue()) { | 1114 if (DetailedAsserts.getValue()) { |
1091 assert op.id() > 0 : "invalid id"; | 1115 assert op.id() > 0 : "invalid id"; |
1092 assert blockForId(op.id()).getPredecessorCount() == 0 : "move from stack must be in first block"; | 1116 assert blockForId(op.id()).getPredecessorCount() == 0 : "move from stack must be in first block"; |
1093 assert isVariable(move.getResult()) : "result of move must be a variable"; | 1117 assert isVariable(move.getResult()) : "result of move must be a variable"; |
1094 | 1118 |
1095 Debug.log("found move from stack slot %s to %s", slot, move.getResult()); | 1119 if (Debug.isLogEnabled()) { |
1120 Debug.log("found move from stack slot %s to %s", slot, move.getResult()); | |
1121 } | |
1096 } | 1122 } |
1097 | 1123 |
1098 Interval interval = intervalFor(move.getResult()); | 1124 Interval interval = intervalFor(move.getResult()); |
1099 interval.setSpillSlot(slot); | 1125 interval.setSpillSlot(slot); |
1100 interval.assignLocation(slot); | 1126 interval.assignLocation(slot); |
1114 if (hintAtDef) { | 1140 if (hintAtDef) { |
1115 to.setLocationHint(from); | 1141 to.setLocationHint(from); |
1116 } else { | 1142 } else { |
1117 from.setLocationHint(to); | 1143 from.setLocationHint(to); |
1118 } | 1144 } |
1119 Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); | 1145 if (Debug.isLogEnabled()) { |
1146 Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); | |
1147 } | |
1120 | 1148 |
1121 return registerHint; | 1149 return registerHint; |
1122 } | 1150 } |
1123 return null; | 1151 return null; |
1124 }); | 1152 }); |
1189 // Update intervals for operands live at the end of this block; | 1217 // Update intervals for operands live at the end of this block; |
1190 BitSet live = blockData.get(block).liveOut; | 1218 BitSet live = blockData.get(block).liveOut; |
1191 for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { | 1219 for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { |
1192 assert live.get(operandNum) : "should not stop here otherwise"; | 1220 assert live.get(operandNum) : "should not stop here otherwise"; |
1193 AllocatableValue operand = intervalFor(operandNum).operand; | 1221 AllocatableValue operand = intervalFor(operandNum).operand; |
1194 Debug.log("live in %d: %s", operandNum, operand); | 1222 if (Debug.isLogEnabled()) { |
1223 Debug.log("live in %d: %s", operandNum, operand); | |
1224 } | |
1195 | 1225 |
1196 addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, LIRKind.Illegal); | 1226 addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, LIRKind.Illegal); |
1197 | 1227 |
1198 // add special use positions for loop-end blocks when the | 1228 // add special use positions for loop-end blocks when the |
1199 // interval is used anywhere inside this loop. It's possible | 1229 // interval is used anywhere inside this loop. It's possible |
1218 for (Register r : callerSaveRegs) { | 1248 for (Register r : callerSaveRegs) { |
1219 if (attributes(r).isAllocatable()) { | 1249 if (attributes(r).isAllocatable()) { |
1220 addTemp(r.asValue(), opId, RegisterPriority.None, LIRKind.Illegal); | 1250 addTemp(r.asValue(), opId, RegisterPriority.None, LIRKind.Illegal); |
1221 } | 1251 } |
1222 } | 1252 } |
1223 Debug.log("operation destroys all caller-save registers"); | 1253 if (Debug.isLogEnabled()) { |
1254 Debug.log("operation destroys all caller-save registers"); | |
1255 } | |
1224 } | 1256 } |
1225 | 1257 |
1226 op.visitEachOutput(outputConsumer); | 1258 op.visitEachOutput(outputConsumer); |
1227 op.visitEachTemp(tempConsumer); | 1259 op.visitEachTemp(tempConsumer); |
1228 op.visitEachAlive(aliveConsumer); | 1260 op.visitEachAlive(aliveConsumer); |
1411 // instead of returning null | 1443 // instead of returning null |
1412 Interval splitChildAtOpId(Interval interval, int opId, LIRInstruction.OperandMode mode) { | 1444 Interval splitChildAtOpId(Interval interval, int opId, LIRInstruction.OperandMode mode) { |
1413 Interval result = interval.getSplitChildAtOpId(opId, mode, this); | 1445 Interval result = interval.getSplitChildAtOpId(opId, mode, this); |
1414 | 1446 |
1415 if (result != null) { | 1447 if (result != null) { |
1416 Debug.log("Split child at pos %d of interval %s is %s", opId, interval, result); | 1448 if (Debug.isLogEnabled()) { |
1449 Debug.log("Split child at pos %d of interval %s is %s", opId, interval, result); | |
1450 } | |
1417 return result; | 1451 return result; |
1418 } | 1452 } |
1419 | 1453 |
1420 throw new BailoutException("LinearScan: interval is null"); | 1454 throw new BailoutException("LinearScan: interval is null"); |
1421 } | |
1422 | |
1423 Interval intervalAtBlockBegin(AbstractBlockBase<?> block, int operandNumber) { | |
1424 return splitChildAtOpId(intervalFor(operandNumber), getFirstLirInstructionId(block), LIRInstruction.OperandMode.DEF); | |
1425 } | |
1426 | |
1427 Interval intervalAtBlockEnd(AbstractBlockBase<?> block, int operandNumber) { | |
1428 return splitChildAtOpId(intervalFor(operandNumber), getLastLirInstructionId(block) + 1, LIRInstruction.OperandMode.DEF); | |
1429 } | 1455 } |
1430 | 1456 |
1431 void resolveCollectMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { | 1457 void resolveCollectMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { |
1432 assert moveResolver.checkEmpty(); | 1458 assert moveResolver.checkEmpty(); |
1433 | 1459 |
1460 int toBlockFirstInstructionId = getFirstLirInstructionId(toBlock); | |
1461 int fromBlockLastInstructionId = getLastLirInstructionId(fromBlock) + 1; | |
1434 int numOperands = operandSize(); | 1462 int numOperands = operandSize(); |
1435 BitSet liveAtEdge = blockData.get(toBlock).liveIn; | 1463 BitSet liveAtEdge = blockData.get(toBlock).liveIn; |
1436 | 1464 |
1437 // visit all variables for which the liveAtEdge bit is set | 1465 // visit all variables for which the liveAtEdge bit is set |
1438 for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { | 1466 for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { |
1439 assert operandNum < numOperands : "live information set for not exisiting interval"; | 1467 assert operandNum < numOperands : "live information set for not exisiting interval"; |
1440 assert blockData.get(fromBlock).liveOut.get(operandNum) && blockData.get(toBlock).liveIn.get(operandNum) : "interval not live at this edge"; | 1468 assert blockData.get(fromBlock).liveOut.get(operandNum) && blockData.get(toBlock).liveIn.get(operandNum) : "interval not live at this edge"; |
1441 | 1469 |
1442 Interval fromInterval = intervalAtBlockEnd(fromBlock, operandNum); | 1470 Interval fromInterval = splitChildAtOpId(intervalFor(operandNum), fromBlockLastInstructionId, LIRInstruction.OperandMode.DEF); |
1443 Interval toInterval = intervalAtBlockBegin(toBlock, operandNum); | 1471 Interval toInterval = splitChildAtOpId(intervalFor(operandNum), toBlockFirstInstructionId, LIRInstruction.OperandMode.DEF); |
1444 | 1472 |
1445 if (fromInterval != toInterval && !fromInterval.location().equals(toInterval.location())) { | 1473 if (fromInterval != toInterval && !fromInterval.location().equals(toInterval.location())) { |
1446 // need to insert move instruction | 1474 // need to insert move instruction |
1447 moveResolver.addMapping(fromInterval, toInterval); | 1475 moveResolver.addMapping(fromInterval, toInterval); |
1448 } | 1476 } |
1449 } | 1477 } |
1450 } | 1478 } |
1451 | 1479 |
1452 void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { | 1480 void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { |
1453 if (fromBlock.getSuccessorCount() <= 1) { | 1481 if (fromBlock.getSuccessorCount() <= 1) { |
1454 Debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId()); | 1482 if (Debug.isLogEnabled()) { |
1483 Debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId()); | |
1484 } | |
1455 | 1485 |
1456 List<LIRInstruction> instructions = ir.getLIRforBlock(fromBlock); | 1486 List<LIRInstruction> instructions = ir.getLIRforBlock(fromBlock); |
1457 LIRInstruction instr = instructions.get(instructions.size() - 1); | 1487 LIRInstruction instr = instructions.get(instructions.size() - 1); |
1458 if (instr instanceof StandardOp.JumpOp) { | 1488 if (instr instanceof StandardOp.JumpOp) { |
1459 // insert moves before branch | 1489 // insert moves before branch |
1461 } else { | 1491 } else { |
1462 moveResolver.setInsertPosition(instructions, instructions.size()); | 1492 moveResolver.setInsertPosition(instructions, instructions.size()); |
1463 } | 1493 } |
1464 | 1494 |
1465 } else { | 1495 } else { |
1466 Debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId()); | 1496 if (Debug.isLogEnabled()) { |
1497 Debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId()); | |
1498 } | |
1467 | 1499 |
1468 if (DetailedAsserts.getValue()) { | 1500 if (DetailedAsserts.getValue()) { |
1469 assert ir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label"; | 1501 assert ir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label"; |
1470 | 1502 |
1471 // because the number of predecessor edges matches the number of | 1503 // because the number of predecessor edges matches the number of |
1506 AbstractBlockBase<?> pred = block.getPredecessors().iterator().next(); | 1538 AbstractBlockBase<?> pred = block.getPredecessors().iterator().next(); |
1507 AbstractBlockBase<?> sux = block.getSuccessors().iterator().next(); | 1539 AbstractBlockBase<?> sux = block.getSuccessors().iterator().next(); |
1508 | 1540 |
1509 // prevent optimization of two consecutive blocks | 1541 // prevent optimization of two consecutive blocks |
1510 if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) { | 1542 if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) { |
1511 Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId()); | 1543 if (Debug.isLogEnabled()) { |
1544 Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId()); | |
1545 } | |
1512 | 1546 |
1513 blockCompleted.set(block.getLinearScanNumber()); | 1547 blockCompleted.set(block.getLinearScanNumber()); |
1514 | 1548 |
1515 // directly resolve between pred and sux (without looking | 1549 // directly resolve between pred and sux (without looking |
1516 // at the empty block | 1550 // at the empty block |
1533 for (AbstractBlockBase<?> toBlock : fromBlock.getSuccessors()) { | 1567 for (AbstractBlockBase<?> toBlock : fromBlock.getSuccessors()) { |
1534 | 1568 |
1535 // check for duplicate edges between the same blocks (can happen with switch | 1569 // check for duplicate edges between the same blocks (can happen with switch |
1536 // blocks) | 1570 // blocks) |
1537 if (!alreadyResolved.get(toBlock.getLinearScanNumber())) { | 1571 if (!alreadyResolved.get(toBlock.getLinearScanNumber())) { |
1538 Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId()); | 1572 if (Debug.isLogEnabled()) { |
1573 Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId()); | |
1574 } | |
1539 | 1575 |
1540 alreadyResolved.set(toBlock.getLinearScanNumber()); | 1576 alreadyResolved.set(toBlock.getLinearScanNumber()); |
1541 | 1577 |
1542 // collect all intervals that have been split between | 1578 // collect all intervals that have been split between |
1543 // fromBlock and toBlock | 1579 // fromBlock and toBlock |
1839 assert firstSpillChild.from() < splitChild.from(); | 1875 assert firstSpillChild.from() < splitChild.from(); |
1840 } | 1876 } |
1841 // iterate all blocks where the interval has use positions | 1877 // iterate all blocks where the interval has use positions |
1842 for (AbstractBlockBase<?> splitBlock : blocksForInterval(splitChild)) { | 1878 for (AbstractBlockBase<?> splitBlock : blocksForInterval(splitChild)) { |
1843 if (dominates(defBlock, splitBlock)) { | 1879 if (dominates(defBlock, splitBlock)) { |
1844 Debug.log("Split interval %s, block %s", splitChild, splitBlock); | 1880 if (Debug.isLogEnabled()) { |
1881 Debug.log("Split interval %s, block %s", splitChild, splitBlock); | |
1882 } | |
1845 if (spillBlock == null) { | 1883 if (spillBlock == null) { |
1846 spillBlock = splitBlock; | 1884 spillBlock = splitBlock; |
1847 } else { | 1885 } else { |
1848 spillBlock = commonDominator(spillBlock, splitBlock); | 1886 spillBlock = commonDominator(spillBlock, splitBlock); |
1849 assert spillBlock != null; | 1887 assert spillBlock != null; |
1866 * is on the stack) spill in the dominator. | 1904 * is on the stack) spill in the dominator. |
1867 */ | 1905 */ |
1868 assert firstSpillChild != null; | 1906 assert firstSpillChild != null; |
1869 if (!defBlock.equals(spillBlock) && spillBlock.equals(blockForId(firstSpillChild.from()))) { | 1907 if (!defBlock.equals(spillBlock) && spillBlock.equals(blockForId(firstSpillChild.from()))) { |
1870 AbstractBlockBase<?> dom = spillBlock.getDominator(); | 1908 AbstractBlockBase<?> dom = spillBlock.getDominator(); |
1871 Debug.log("Spill block (%s) is the beginning of a spill child -> use dominator (%s)", spillBlock, dom); | 1909 if (Debug.isLogEnabled()) { |
1910 Debug.log("Spill block (%s) is the beginning of a spill child -> use dominator (%s)", spillBlock, dom); | |
1911 } | |
1872 spillBlock = dom; | 1912 spillBlock = dom; |
1873 } | 1913 } |
1874 | 1914 |
1875 if (!defBlock.equals(spillBlock)) { | 1915 if (!defBlock.equals(spillBlock)) { |
1876 assert dominates(defBlock, spillBlock); | 1916 assert dominates(defBlock, spillBlock); |
1877 betterSpillPos.increment(); | 1917 betterSpillPos.increment(); |
1878 Debug.log("Better spill position found (Block %s)", spillBlock); | 1918 if (Debug.isLogEnabled()) { |
1919 Debug.log("Better spill position found (Block %s)", spillBlock); | |
1920 } | |
1879 | 1921 |
1880 if (defBlock.probability() <= spillBlock.probability()) { | 1922 if (defBlock.probability() <= spillBlock.probability()) { |
1881 // better spill block has the same probability -> do nothing | 1923 // better spill block has the same probability -> do nothing |
1882 interval.setSpillState(SpillState.StoreAtDefinition); | 1924 interval.setSpillState(SpillState.StoreAtDefinition); |
1883 } else { | 1925 } else { |