Skip to content

Commit 57e5328

Browse files
committed
[GR-64008] Improve saving of the callee save registers
PullRequest: graal/20483
2 parents af5935c + 36a2b09 commit 57e5328

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/SaveCalleeSaveRegisters.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import jdk.graal.compiler.lir.LIRInsertionBuffer;
3434
import jdk.graal.compiler.lir.LIRInstruction;
3535
import jdk.graal.compiler.lir.StandardOp;
36-
import jdk.graal.compiler.lir.Variable;
3736
import jdk.graal.compiler.lir.gen.LIRGenerationResult;
3837
import jdk.graal.compiler.lir.gen.LIRGeneratorTool;
3938
import jdk.graal.compiler.lir.gen.MoveFactory;
@@ -43,6 +42,7 @@
4342
import jdk.vm.ci.code.Register;
4443
import jdk.vm.ci.code.RegisterValue;
4544
import jdk.vm.ci.code.TargetDescription;
45+
import jdk.vm.ci.meta.AllocatableValue;
4646
import jdk.vm.ci.meta.PlatformKind;
4747

4848
public class SaveCalleeSaveRegisters extends PreAllocationOptimizationPhase {
@@ -54,7 +54,7 @@ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreA
5454
return;
5555
}
5656
LIR lir = lirGenRes.getLIR();
57-
RegisterMap<Variable> savedRegisters = saveAtEntry(lir, context.lirGen, lirGenRes, calleeSaveRegisters, target.arch);
57+
RegisterMap<AllocatableValue> savedRegisters = saveAtEntry(lir, context.lirGen, lirGenRes, calleeSaveRegisters, target.arch);
5858

5959
for (int blockId : lir.getBlocks()) {
6060
if (LIR.isBlockDeleted(blockId)) {
@@ -67,7 +67,7 @@ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreA
6767
}
6868
}
6969

70-
private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, List<Register> calleeSaveRegisters, Architecture arch) {
70+
private static RegisterMap<AllocatableValue> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, List<Register> calleeSaveRegisters, Architecture arch) {
7171
BasicBlock<?> startBlock = lir.getControlFlowGraph().getStartBlock();
7272
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(startBlock);
7373
int insertionIndex = lirGenRes.getFirstInsertPosition();
@@ -76,12 +76,15 @@ private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGe
7676
StandardOp.LabelOp entry = (StandardOp.LabelOp) instructions.get(insertionIndex - 1);
7777
RegisterValue[] savedRegisterValues = new RegisterValue[calleeSaveRegisters.size()];
7878
int savedRegisterValueIndex = 0;
79-
RegisterMap<Variable> saveMap = new RegisterMap<>(arch);
79+
List<Register> allocatables = lirGenRes.getRegisterConfig().getAllocatableRegisters();
80+
RegisterMap<AllocatableValue> saveMap = new RegisterMap<>(arch);
8081
for (Register register : calleeSaveRegisters) {
81-
PlatformKind registerPlatformKind = arch.getLargestStorableKind(register.getRegisterCategory());
82+
PlatformKind registerPlatformKind = lirGenRes.getRegisterConfig().getCalleeSaveRegisterStorageKind(arch, register);
8283
LIRKind lirKind = LIRKind.value(registerPlatformKind);
8384
RegisterValue registerValue = register.asValue(lirKind);
84-
Variable saveVariable = lirGen.newVariable(lirKind);
85+
// Force a non-allocatable register to be saved to a stack slot
86+
// so as to avoid unnecessary register pressure.
87+
AllocatableValue saveVariable = allocatables.contains(registerValue.getRegister()) ? lirGen.newVariable(lirKind) : lirGenRes.getFrameMapBuilder().allocateSpillSlot(lirKind);
8588
LIRInstruction save = lirGen.getSpillMoveFactory().createMove(saveVariable, registerValue);
8689
buffer.append(insertionIndex, save);
8790
save.setComment(lirGenRes, "SaveCalleeSavedRegisters: saveAtEntry");
@@ -93,14 +96,14 @@ private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGe
9396
return saveMap;
9497
}
9598

96-
private static void restoreAtExit(LIR lir, MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap<Variable> calleeSaveRegisters, BasicBlock<?> block) {
99+
private static void restoreAtExit(LIR lir, MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap<AllocatableValue> calleeSaveRegisters, BasicBlock<?> block) {
97100
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
98101
int insertionIndex = instructions.size() - 1;
99102
LIRInsertionBuffer buffer = new LIRInsertionBuffer();
100103
buffer.init(instructions);
101104
LIRInstruction lirInstruction = instructions.get(insertionIndex);
102105
assert lirInstruction instanceof StandardOp.BlockEndOp : lirInstruction;
103-
calleeSaveRegisters.forEach((Register register, Variable saved) -> {
106+
calleeSaveRegisters.forEach((Register register, AllocatableValue saved) -> {
104107
LIRInstruction restore = moveFactory.createMove(register.asValue(saved.getValueKind()), saved);
105108
buffer.append(insertionIndex, restore);
106109
restore.setComment(lirGenRes, "SaveCalleeSavedRegisters: restoreAtExit");

substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64RegisterConfig.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import static jdk.vm.ci.amd64.AMD64.xmm7;
6565
import static jdk.vm.ci.amd64.AMD64.xmm8;
6666
import static jdk.vm.ci.amd64.AMD64.xmm9;
67+
import static jdk.vm.ci.amd64.AMD64Kind.V128_QWORD;
6768

6869
import java.util.ArrayList;
6970
import java.util.Arrays;
@@ -87,6 +88,7 @@
8788
import jdk.graal.compiler.core.common.LIRKind;
8889
import jdk.vm.ci.amd64.AMD64;
8990
import jdk.vm.ci.amd64.AMD64Kind;
91+
import jdk.vm.ci.code.Architecture;
9092
import jdk.vm.ci.code.CallingConvention;
9193
import jdk.vm.ci.code.CallingConvention.Type;
9294
import jdk.vm.ci.code.Register;
@@ -239,6 +241,15 @@ public List<Register> getCalleeSaveRegisters() {
239241
return calleeSaveRegisters;
240242
}
241243

244+
@Override
245+
public PlatformKind getCalleeSaveRegisterStorageKind(Architecture arch, Register calleeSaveRegister) {
246+
if (Platform.includedIn(Platform.WINDOWS.class) && AMD64.XMM.equals(calleeSaveRegister.getRegisterCategory())) {
247+
VMError.guarantee(calleeSaveRegister.encoding() >= xmm6.encoding() && calleeSaveRegister.encoding() <= xmm15.encoding(), "unexpected callee saved register");
248+
return V128_QWORD;
249+
}
250+
return SubstrateRegisterConfig.super.getCalleeSaveRegisterStorageKind(arch, calleeSaveRegister);
251+
}
252+
242253
@Override
243254
public List<Register> getCallerSaveRegisters() {
244255
return getAllocatableRegisters();
@@ -410,7 +421,7 @@ public CallingConvention getCallingConvention(Type t, JavaType returnType, JavaT
410421
kinds = Arrays.copyOf(kinds, kinds.length + 1);
411422
locations = Arrays.copyOf(locations, locations.length + 1);
412423
kinds[kinds.length - 1] = JavaKind.Int;
413-
locations[locations.length - 1] = AMD64.rax.asValue(LIRKind.value(AMD64Kind.DWORD));
424+
locations[locations.length - 1] = rax.asValue(LIRKind.value(AMD64Kind.DWORD));
414425
if (type.customABI()) {
415426
var extendsParametersAssignment = Arrays.copyOf(type.fixedParameterAssignment, type.fixedParameterAssignment.length + 1);
416427
extendsParametersAssignment[extendsParametersAssignment.length - 1] = AssignedLocation.forRegister(rax, JavaKind.Long);

0 commit comments

Comments
 (0)