Skip to content

[GR-64008] Improve saving of the callee save registers #10984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -25,14 +25,14 @@
package jdk.graal.compiler.lir.alloc;

import java.util.ArrayList;
import java.util.List;

import jdk.graal.compiler.core.common.LIRKind;
import jdk.graal.compiler.core.common.cfg.BasicBlock;
import jdk.graal.compiler.lir.LIR;
import jdk.graal.compiler.lir.LIRInsertionBuffer;
import jdk.graal.compiler.lir.LIRInstruction;
import jdk.graal.compiler.lir.StandardOp;
import jdk.graal.compiler.lir.Variable;
import jdk.graal.compiler.lir.gen.LIRGenerationResult;
import jdk.graal.compiler.lir.gen.LIRGeneratorTool;
import jdk.graal.compiler.lir.gen.MoveFactory;
Expand All @@ -43,6 +43,7 @@
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.PlatformKind;

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

for (int blockId : lir.getBlocks()) {
if (LIR.isBlockDeleted(blockId)) {
Expand All @@ -67,7 +68,7 @@ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreA
}
}

private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, RegisterArray calleeSaveRegisters, Architecture arch) {
private static RegisterMap<AllocatableValue> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, RegisterArray calleeSaveRegisters, Architecture arch) {
BasicBlock<?> startBlock = lir.getControlFlowGraph().getStartBlock();
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(startBlock);
int insertionIndex = lirGenRes.getFirstInsertPosition();
Expand All @@ -76,12 +77,13 @@ private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGe
StandardOp.LabelOp entry = (StandardOp.LabelOp) instructions.get(insertionIndex - 1);
RegisterValue[] savedRegisterValues = new RegisterValue[calleeSaveRegisters.size()];
int savedRegisterValueIndex = 0;
RegisterMap<Variable> saveMap = new RegisterMap<>(arch);
List<Register> allocatables = lirGenRes.getRegisterConfig().getAllocatableRegisters().asList();
RegisterMap<AllocatableValue> saveMap = new RegisterMap<>(arch);
for (Register register : calleeSaveRegisters) {
PlatformKind registerPlatformKind = arch.getLargestStorableKind(register.getRegisterCategory());
PlatformKind registerPlatformKind = lirGenRes.getRegisterConfig().getCalleeSaveRegisterStorageKind(arch, register);
LIRKind lirKind = LIRKind.value(registerPlatformKind);
RegisterValue registerValue = register.asValue(lirKind);
Variable saveVariable = lirGen.newVariable(lirKind);
AllocatableValue saveVariable = allocatables.contains(registerValue.getRegister()) ? lirGen.newVariable(lirKind) : lirGenRes.getFrameMapBuilder().allocateSpillSlot(lirKind);
LIRInstruction save = lirGen.getSpillMoveFactory().createMove(saveVariable, registerValue);
buffer.append(insertionIndex, save);
save.setComment(lirGenRes, "SaveCalleeSavedRegisters: saveAtEntry");
Expand All @@ -93,14 +95,14 @@ private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGe
return saveMap;
}

private static void restoreAtExit(LIR lir, MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap<Variable> calleeSaveRegisters, BasicBlock<?> block) {
private static void restoreAtExit(LIR lir, MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap<AllocatableValue> calleeSaveRegisters, BasicBlock<?> block) {
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
int insertionIndex = instructions.size() - 1;
LIRInsertionBuffer buffer = new LIRInsertionBuffer();
buffer.init(instructions);
LIRInstruction lirInstruction = instructions.get(insertionIndex);
assert lirInstruction instanceof StandardOp.BlockEndOp : lirInstruction;
calleeSaveRegisters.forEach((Register register, Variable saved) -> {
calleeSaveRegisters.forEach((Register register, AllocatableValue saved) -> {
LIRInstruction restore = moveFactory.createMove(register.asValue(saved.getValueKind()), saved);
buffer.append(insertionIndex, restore);
restore.setComment(lirGenRes, "SaveCalleeSavedRegisters: restoreAtExit");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -63,6 +63,7 @@
import static jdk.vm.ci.amd64.AMD64.xmm7;
import static jdk.vm.ci.amd64.AMD64.xmm8;
import static jdk.vm.ci.amd64.AMD64.xmm9;
import static jdk.vm.ci.amd64.AMD64Kind.V128_QWORD;

import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -85,6 +86,7 @@
import jdk.graal.compiler.core.common.LIRKind;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.Register;
Expand Down Expand Up @@ -234,6 +236,15 @@ public RegisterArray getCalleeSaveRegisters() {
return calleeSaveRegisters;
}

@Override
public PlatformKind getCalleeSaveRegisterStorageKind(Architecture arch, Register calleeSaveRegister) {
if (Platform.includedIn(Platform.WINDOWS.class) && AMD64.XMM.equals(calleeSaveRegister.getRegisterCategory())) {
VMError.guarantee(calleeSaveRegister.encoding() >= xmm6.encoding() && calleeSaveRegister.encoding() <= xmm15.encoding(), "unexpected callee saved register %s", calleeSaveRegister);
return V128_QWORD;
}
return SubstrateRegisterConfig.super.getCalleeSaveRegisterStorageKind(arch, calleeSaveRegister);
}

@Override
public RegisterArray getCallerSaveRegisters() {
return getAllocatableRegisters();
Expand Down Expand Up @@ -405,7 +416,7 @@ public CallingConvention getCallingConvention(Type t, JavaType returnType, JavaT
kinds = Arrays.copyOf(kinds, kinds.length + 1);
locations = Arrays.copyOf(locations, locations.length + 1);
kinds[kinds.length - 1] = JavaKind.Int;
locations[locations.length - 1] = AMD64.rax.asValue(LIRKind.value(AMD64Kind.DWORD));
locations[locations.length - 1] = rax.asValue(LIRKind.value(AMD64Kind.DWORD));
if (type.customABI()) {
var extendsParametersAssignment = Arrays.copyOf(type.fixedParameterAssignment, type.fixedParameterAssignment.length + 1);
extendsParametersAssignment[extendsParametersAssignment.length - 1] = AssignedLocation.forRegister(rax, JavaKind.Long);
Expand Down
Loading