src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/bu/BottomUpAllocator.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/bu/BottomUpAllocator.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/bu/BottomUpAllocator.java
Print this page
*** 40,51 ****
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig.AllocatableRegisters;
import org.graalvm.compiler.core.common.alloc.Trace;
import org.graalvm.compiler.core.common.alloc.TraceBuilderResult;
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
! import org.graalvm.compiler.debug.Debug;
! import org.graalvm.compiler.debug.Debug.Scope;
import org.graalvm.compiler.debug.Indent;
import org.graalvm.compiler.lir.InstructionValueProcedure;
import org.graalvm.compiler.lir.LIR;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
--- 40,50 ----
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig.AllocatableRegisters;
import org.graalvm.compiler.core.common.alloc.Trace;
import org.graalvm.compiler.core.common.alloc.TraceBuilderResult;
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
! import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.Indent;
import org.graalvm.compiler.lir.InstructionValueProcedure;
import org.graalvm.compiler.lir.LIR;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
*** 100,109 ****
--- 99,109 ----
private final RegisterArray callerSaveRegs;
private final RegisterAttributes[] registerAttributes;
private final BitSet allocatedBlocks;
private final TraceBuilderResult resultTraces;
private final TraceGlobalMoveResolver moveResolver;
+ private final DebugContext debug;
/**
* Maps from {@link Variable#index} to a spill stack slot. If
* {@linkplain org.graalvm.compiler.lir.alloc.trace.TraceRegisterAllocationPhase.Options#TraceRACacheStackSlots
* enabled} a {@link Variable} is always assigned to the same stack slot.
*** 117,126 ****
--- 117,127 ----
private final GlobalLivenessInfo livenessInfo;
public BottomUpAllocator(TargetDescription target, LIRGenerationResult lirGenRes, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig,
AllocatableValue[] cachedStackSlots, TraceBuilderResult resultTraces, boolean neverSpillConstant, GlobalLivenessInfo livenessInfo) {
this.target = target;
+ this.debug = lirGenRes.getLIR().getDebug();
this.lirGenRes = lirGenRes;
this.spillMoveFactory = spillMoveFactory;
this.registerAllocationConfig = registerAllocationConfig;
this.callerSaveRegs = registerAllocationConfig.getRegisterConfig().getCallerSaveRegisters();
this.registerAttributes = registerAllocationConfig.getRegisterConfig().getAttributesMap();
*** 158,174 ****
*/
private AllocatableValue allocateSpillSlot(Variable var) {
int variableIndex = var.index;
AllocatableValue cachedStackSlot = stackSlots[variableIndex];
if (cachedStackSlot != null) {
! TraceRegisterAllocationPhase.globalStackSlots.increment();
assert cachedStackSlot.getValueKind().equals(var.getValueKind()) : "CachedStackSlot: kind mismatch? " + var.getValueKind() + " vs. " + cachedStackSlot.getValueKind();
return cachedStackSlot;
}
VirtualStackSlot slot = lirGenRes.getFrameMapBuilder().allocateSpillSlot(var.getValueKind());
stackSlots[variableIndex] = slot;
! TraceRegisterAllocationPhase.allocatedStackSlots.increment();
return slot;
}
@Override
protected void run(@SuppressWarnings("hiding") TargetDescription target, @SuppressWarnings("hiding") LIRGenerationResult lirGenRes, Trace trace, TraceAllocationContext context) {
--- 159,175 ----
*/
private AllocatableValue allocateSpillSlot(Variable var) {
int variableIndex = var.index;
AllocatableValue cachedStackSlot = stackSlots[variableIndex];
if (cachedStackSlot != null) {
! TraceRegisterAllocationPhase.globalStackSlots.increment(debug);
assert cachedStackSlot.getValueKind().equals(var.getValueKind()) : "CachedStackSlot: kind mismatch? " + var.getValueKind() + " vs. " + cachedStackSlot.getValueKind();
return cachedStackSlot;
}
VirtualStackSlot slot = lirGenRes.getFrameMapBuilder().allocateSpillSlot(var.getValueKind());
stackSlots[variableIndex] = slot;
! TraceRegisterAllocationPhase.allocatedStackSlots.increment(debug);
return slot;
}
@Override
protected void run(@SuppressWarnings("hiding") TargetDescription target, @SuppressWarnings("hiding") LIRGenerationResult lirGenRes, Trace trace, TraceAllocationContext context) {
*** 203,214 ****
}
private void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock) {
LIR lir = lirGenRes.getLIR();
if (fromBlock.getSuccessorCount() <= 1) {
! if (Debug.isLogEnabled()) {
! Debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId());
}
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(fromBlock);
LIRInstruction instr = instructions.get(instructions.size() - 1);
if (instr instanceof StandardOp.JumpOp) {
--- 204,215 ----
}
private void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock) {
LIR lir = lirGenRes.getLIR();
if (fromBlock.getSuccessorCount() <= 1) {
! if (debug.isLogEnabled()) {
! debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId());
}
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(fromBlock);
LIRInstruction instr = instructions.get(instructions.size() - 1);
if (instr instanceof StandardOp.JumpOp) {
*** 217,228 ****
} else {
moveResolver.setInsertPosition(instructions, instructions.size());
}
} else {
! if (Debug.isLogEnabled()) {
! Debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId());
}
if (DetailedAsserts.getValue(getLIR().getOptions())) {
assert lir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
--- 218,229 ----
} else {
moveResolver.setInsertPosition(instructions, instructions.size());
}
} else {
! if (debug.isLogEnabled()) {
! debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId());
}
if (DetailedAsserts.getValue(getLIR().getOptions())) {
assert lir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
*** 282,301 ****
private int getLastRegisterUsage(Register reg) {
return lastRegisterUsage[reg.number];
}
private void setLastRegisterUsage(Register reg, int pos) {
! Debug.log("Register %s last used %d", reg, pos);
lastRegisterUsage[reg.number] = pos;
}
private int getLastRegisterKill(Register reg) {
return lastRegisterKill[reg.number];
}
private void setLastRegisterKill(Register reg, int pos) {
! Debug.log("Register %s killed %d", reg, pos);
lastRegisterKill[reg.number] = pos;
}
private void setCurrentLocation(Variable var, AllocatableValue location) {
locations[var.index] = location;
--- 283,302 ----
private int getLastRegisterUsage(Register reg) {
return lastRegisterUsage[reg.number];
}
private void setLastRegisterUsage(Register reg, int pos) {
! debug.log("Register %s last used %d", reg, pos);
lastRegisterUsage[reg.number] = pos;
}
private int getLastRegisterKill(Register reg) {
return lastRegisterKill[reg.number];
}
private void setLastRegisterKill(Register reg, int pos) {
! debug.log("Register %s killed %d", reg, pos);
lastRegisterKill[reg.number] = pos;
}
private void setCurrentLocation(Variable var, AllocatableValue location) {
locations[var.index] = location;
*** 307,328 ****
private void insertSpillMoveBefore(AllocatableValue dst, Value src) {
LIRInstruction move = spillMoveFactory.createMove(dst, src);
insertInstructionsBefore.add(move);
move.setComment(lirGenRes, "BottomUp: spill move before");
! Debug.log("insert before %s", move);
}
private void insertSpillMoveAfter(AllocatableValue dst, Value src) {
LIRInstruction inst = currentInstructions.get(currentInstructionIndex);
if (!(inst instanceof BlockEndOp)) {
LIRInstruction move = spillMoveFactory.createMove(dst, src);
insertInstructionsAfter.add(move);
move.setComment(lirGenRes, "BottomUp: spill move after");
! Debug.log("insert after %s", move);
} else {
! Debug.log("Block end op. No from %s to %s necessary.", src, dst);
requireResolution = true;
}
}
private void insertInstructions() {
--- 308,329 ----
private void insertSpillMoveBefore(AllocatableValue dst, Value src) {
LIRInstruction move = spillMoveFactory.createMove(dst, src);
insertInstructionsBefore.add(move);
move.setComment(lirGenRes, "BottomUp: spill move before");
! debug.log("insert before %s", move);
}
private void insertSpillMoveAfter(AllocatableValue dst, Value src) {
LIRInstruction inst = currentInstructions.get(currentInstructionIndex);
if (!(inst instanceof BlockEndOp)) {
LIRInstruction move = spillMoveFactory.createMove(dst, src);
insertInstructionsAfter.add(move);
move.setComment(lirGenRes, "BottomUp: spill move after");
! debug.log("insert after %s", move);
} else {
! debug.log("Block end op. No from %s to %s necessary.", src, dst);
requireResolution = true;
}
}
private void insertInstructions() {
*** 344,354 ****
}
}
@SuppressWarnings("try")
private void allocateTrace(Trace trace) {
! try (Scope s = Debug.scope("BottomUpAllocator", trace.getBlocks()); Indent indent = Debug.logAndIndent("%s (Trace%d)", trace, trace.getId())) {
AbstractBlockBase<?>[] blocks = trace.getBlocks();
int lastBlockIdx = blocks.length - 1;
AbstractBlockBase<?> successorBlock = blocks[lastBlockIdx];
// handle last block
allocateBlock(successorBlock);
--- 345,355 ----
}
}
@SuppressWarnings("try")
private void allocateTrace(Trace trace) {
! try (DebugContext.Scope s = debug.scope("BottomUpAllocator", trace.getBlocks()); Indent indent = debug.logAndIndent("%s (Trace%d)", trace, trace.getId())) {
AbstractBlockBase<?>[] blocks = trace.getBlocks();
int lastBlockIdx = blocks.length - 1;
AbstractBlockBase<?> successorBlock = blocks[lastBlockIdx];
// handle last block
allocateBlock(successorBlock);
*** 365,375 ****
}
successorBlock = block;
}
resolveLoopBackEdge(trace);
} catch (Throwable e) {
! throw Debug.handle(e);
}
}
private final ArrayList<LIRInstruction> phiResolutionMoves = new ArrayList<>();
--- 366,376 ----
}
successorBlock = block;
}
resolveLoopBackEdge(trace);
} catch (Throwable e) {
! throw debug.handle(e);
}
}
private final ArrayList<LIRInstruction> phiResolutionMoves = new ArrayList<>();
*** 408,418 ****
} else {
assert isVariable(phiOut) : "Not a variable or constant: " + phiOut;
// insert move from variable
move = spillMoveFactory.createMove(dest, asVariable(phiOut));
}
! Debug.log("Inserting load %s", move);
move.setComment(lirGenRes, "BottomUp: phi resolution");
phiResolutionMoves.add(move);
}
private boolean requireResolution;
--- 409,419 ----
} else {
assert isVariable(phiOut) : "Not a variable or constant: " + phiOut;
// insert move from variable
move = spillMoveFactory.createMove(dest, asVariable(phiOut));
}
! debug.log("Inserting load %s", move);
move.setComment(lirGenRes, "BottomUp: phi resolution");
phiResolutionMoves.add(move);
}
private boolean requireResolution;
*** 496,506 ****
@SuppressWarnings("try")
private boolean allocateBlock(AbstractBlockBase<?> block) {
// might be set in insertSpillMoveAfter
requireResolution = false;
! try (Indent indent = Debug.logAndIndent("handle block %s", block)) {
currentInstructions = getLIR().getLIRforBlock(block);
for (currentInstructionIndex = currentInstructions.size() - 1; currentInstructionIndex >= 0; currentInstructionIndex--) {
LIRInstruction inst = currentInstructions.get(currentInstructionIndex);
if (inst != null) {
inst.setId(currentOpId);
--- 497,507 ----
@SuppressWarnings("try")
private boolean allocateBlock(AbstractBlockBase<?> block) {
// might be set in insertSpillMoveAfter
requireResolution = false;
! try (Indent indent = debug.logAndIndent("handle block %s", block)) {
currentInstructions = getLIR().getLIRforBlock(block);
for (currentInstructionIndex = currentInstructions.size() - 1; currentInstructionIndex >= 0; currentInstructionIndex--) {
LIRInstruction inst = currentInstructions.get(currentInstructionIndex);
if (inst != null) {
inst.setId(currentOpId);
*** 513,524 ****
}
@SuppressWarnings("try")
private void allocateInstruction(LIRInstruction op, AbstractBlockBase<?> block) {
assert op != null && op.id() == currentOpId;
! try (Indent indent = Debug.logAndIndent("handle inst: %d: %s", op.id(), op)) {
! try (Indent indent1 = Debug.logAndIndent("output pos")) {
// spill caller saved registers
if (op.destroysCallerSavedRegisters()) {
spillCallerSavedRegisters();
}
--- 514,525 ----
}
@SuppressWarnings("try")
private void allocateInstruction(LIRInstruction op, AbstractBlockBase<?> block) {
assert op != null && op.id() == currentOpId;
! try (Indent indent = debug.logAndIndent("handle inst: %d: %s", op.id(), op)) {
! try (Indent indent1 = debug.logAndIndent("output pos")) {
// spill caller saved registers
if (op.destroysCallerSavedRegisters()) {
spillCallerSavedRegisters();
}
*** 538,548 ****
op.forEachOutput(allocStackOrRegisterProcedure);
if (op instanceof LabelOp) {
processIncoming(block, op);
}
}
! try (Indent indent1 = Debug.logAndIndent("input pos")) {
currentOpId++;
// fixed
op.forEachInput(allocFixedRegisterProcedure);
--- 539,549 ----
op.forEachOutput(allocStackOrRegisterProcedure);
if (op instanceof LabelOp) {
processIncoming(block, op);
}
}
! try (Indent indent1 = debug.logAndIndent("input pos")) {
currentOpId++;
// fixed
op.forEachInput(allocFixedRegisterProcedure);
*** 590,601 ****
evacuateRegisterAndSpill(reg);
assert checkRegisterUsage(reg);
setLastRegisterUsage(reg, currentOpId);
}
}
! if (Debug.isLogEnabled()) {
! Debug.log("operation destroys all caller-save registers");
}
}
private final InstructionValueProcedure allocFixedRegisterProcedure = new InstructionValueProcedure() {
@Override
--- 591,602 ----
evacuateRegisterAndSpill(reg);
assert checkRegisterUsage(reg);
setLastRegisterUsage(reg, currentOpId);
}
}
! if (debug.isLogEnabled()) {
! debug.log("operation destroys all caller-save registers");
}
}
private final InstructionValueProcedure allocFixedRegisterProcedure = new InstructionValueProcedure() {
@Override
*** 668,678 ****
}
// found a register
setRegisterUsage(freeRegister, var);
RegisterValue registerValue = freeRegister.asValue(var.getValueKind());
setCurrentLocation(var, registerValue);
! Debug.log("AllocateRegister[%5s] %s for %s", mode, freeRegister, var);
return registerValue;
}
private Value allocStackOrRegister(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
if (isRegister(value)) {
--- 669,679 ----
}
// found a register
setRegisterUsage(freeRegister, var);
RegisterValue registerValue = freeRegister.asValue(var.getValueKind());
setCurrentLocation(var, registerValue);
! debug.log("AllocateRegister[%5s] %s for %s", mode, freeRegister, var);
return registerValue;
}
private Value allocStackOrRegister(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
if (isRegister(value)) {
*** 691,707 ****
if (isRegister(currentLocation)) {
Register reg = asRegister(currentLocation);
if (mode == OperandMode.ALIVE && killedAtDef(reg)) {
AllocatableValue spillSlot = allocateSpillSlot(var);
insertSpillMoveBefore(spillSlot, currentLocation);
! Debug.log("AllocateStackOrReg[%5s] temporary use %s for %s since current location %s is destroyed at def", mode, spillSlot, var, currentLocation);
return spillSlot;
}
// update register usage
setLastRegisterUsage(reg, currentOpId);
}
! Debug.log(3, "AllocateStackOrReg[%5s] %s already in %s", mode, var, currentLocation);
return currentLocation;
}
// no location available
PlatformKind platformKind = var.getPlatformKind();
Register freeRegister = findFreeRegister(platformKind, mode);
--- 692,708 ----
if (isRegister(currentLocation)) {
Register reg = asRegister(currentLocation);
if (mode == OperandMode.ALIVE && killedAtDef(reg)) {
AllocatableValue spillSlot = allocateSpillSlot(var);
insertSpillMoveBefore(spillSlot, currentLocation);
! debug.log("AllocateStackOrReg[%5s] temporary use %s for %s since current location %s is destroyed at def", mode, spillSlot, var, currentLocation);
return spillSlot;
}
// update register usage
setLastRegisterUsage(reg, currentOpId);
}
! debug.log(3, "AllocateStackOrReg[%5s] %s already in %s", mode, var, currentLocation);
return currentLocation;
}
// no location available
PlatformKind platformKind = var.getPlatformKind();
Register freeRegister = findFreeRegister(platformKind, mode);
*** 714,724 ****
assert freeRegister != null;
// found a register
setRegisterUsage(freeRegister, var);
RegisterValue registerValue = freeRegister.asValue(var.getValueKind());
setCurrentLocation(var, registerValue);
! Debug.log("AllocateStackOrReg[%5s] %s for %s", mode, freeRegister, var);
return registerValue;
}
return value;
}
--- 715,725 ----
assert freeRegister != null;
// found a register
setRegisterUsage(freeRegister, var);
RegisterValue registerValue = freeRegister.asValue(var.getValueKind());
setCurrentLocation(var, registerValue);
! debug.log("AllocateStackOrReg[%5s] %s for %s", mode, freeRegister, var);
return registerValue;
}
return value;
}
*** 737,750 ****
AllocatableValue currentVal = getCurrentValue(reg);
if (currentVal == null && !isCurrentlyUsed(reg, mode)) {
return reg;
}
}
! if (Debug.isLogEnabled()) {
! try (Indent i = Debug.logAndIndent("All Registers occupied:")) {
for (Register reg : availableRegs) {
! Debug.log("%6s: last used %4d %s", reg, getLastRegisterUsage(reg), getCurrentValue(reg));
}
}
}
return null;
}
--- 738,751 ----
AllocatableValue currentVal = getCurrentValue(reg);
if (currentVal == null && !isCurrentlyUsed(reg, mode)) {
return reg;
}
}
! if (debug.isLogEnabled()) {
! try (Indent i = debug.logAndIndent("All Registers occupied:")) {
for (Register reg : availableRegs) {
! debug.log("%6s: last used %4d %s", reg, getLastRegisterUsage(reg), getCurrentValue(reg));
}
}
}
return null;
}
*** 790,802 ****
setCurrentValue(reg, null);
setLastRegisterKill(reg, currentOpId);
if (val != null && isVariable(val)) {
Variable var = asVariable(val);
setCurrentLocation(var, null);
! Debug.log("Free Registers %s (was %s)", reg, var);
} else {
! Debug.log("Free Registers %s", reg);
}
}
private void setRegisterUsage(Register reg, AllocatableValue currentValue) {
assert checkRegisterUsage(reg);
--- 791,803 ----
setCurrentValue(reg, null);
setLastRegisterKill(reg, currentOpId);
if (val != null && isVariable(val)) {
Variable var = asVariable(val);
setCurrentLocation(var, null);
! debug.log("Free Registers %s (was %s)", reg, var);
} else {
! debug.log("Free Registers %s", reg);
}
}
private void setRegisterUsage(Register reg, AllocatableValue currentValue) {
assert checkRegisterUsage(reg);
*** 836,846 ****
}
private void spillVariable(AllocatableValue val, Register reg) {
if (val != null && isVariable(val)) {
Variable var = asVariable(val);
! Debug.log("Spill Variable %s from %s", var, reg);
// insert reload
AllocatableValue spillSlot = allocateSpillSlot(var);
setCurrentLocation(var, spillSlot);
insertSpillMoveAfter(reg.asValue(var.getValueKind()), spillSlot);
}
--- 837,847 ----
}
private void spillVariable(AllocatableValue val, Register reg) {
if (val != null && isVariable(val)) {
Variable var = asVariable(val);
! debug.log("Spill Variable %s from %s", var, reg);
// insert reload
AllocatableValue spillSlot = allocateSpillSlot(var);
setCurrentLocation(var, spillSlot);
insertSpillMoveAfter(reg.asValue(var.getValueKind()), spillSlot);
}
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/bu/BottomUpAllocator.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File