< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
Print this page
rev 56282 : [mq]: graal
*** 59,68 ****
--- 59,69 ----
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
import org.graalvm.compiler.lir.StandardOp.LabelOp;
+ import org.graalvm.compiler.lir.StandardOp.RestoreRegistersOp;
import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
import org.graalvm.compiler.lir.ValueConsumer;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.framemap.FrameMap;
import org.graalvm.compiler.nodes.UnwindNode;
*** 74,92 ****
import org.graalvm.compiler.phases.tiers.SuitesProvider;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.Word;
import jdk.internal.vm.compiler.word.Pointer;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.Register;
- import jdk.vm.ci.code.RegisterSaveLayout;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.ValueUtil;
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.runtime.JVMCICompiler;
/**
--- 75,94 ----
import org.graalvm.compiler.phases.tiers.SuitesProvider;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.Word;
import jdk.internal.vm.compiler.word.Pointer;
+ import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.ValueUtil;
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+ import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.runtime.JVMCICompiler;
/**
*** 423,459 ****
}
/**
* Finds all the registers that are defined by some given LIR.
*
! * @param lir the LIR to examine
* @return the registers that are defined by or used as temps for any instruction in {@code lir}
*/
! protected final EconomicSet<Register> gatherDestroyedCallerRegisters(LIR lir) {
final EconomicSet<Register> destroyedRegisters = EconomicSet.create(Equivalence.IDENTITY);
ValueConsumer defConsumer = new ValueConsumer() {
@Override
public void visitValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
if (ValueUtil.isRegister(value)) {
final Register reg = ValueUtil.asRegister(value);
destroyedRegisters.add(reg);
}
}
};
for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
if (block == null) {
continue;
}
for (LIRInstruction op : lir.getLIRforBlock(block)) {
if (op instanceof LabelOp) {
// Don't consider this as a definition
} else {
op.visitEachTemp(defConsumer);
op.visitEachOutput(defConsumer);
}
}
}
return translateToCallerRegisters(destroyedRegisters);
}
/**
--- 425,487 ----
}
/**
* Finds all the registers that are defined by some given LIR.
*
! * @param gen the result to examine
* @return the registers that are defined by or used as temps for any instruction in {@code lir}
*/
! private EconomicSet<Register> gatherDestroyedCallerRegisters(HotSpotLIRGenerationResult gen) {
! LIR lir = gen.getLIR();
! final EconomicSet<Register> preservedRegisters = EconomicSet.create(Equivalence.IDENTITY);
final EconomicSet<Register> destroyedRegisters = EconomicSet.create(Equivalence.IDENTITY);
ValueConsumer defConsumer = new ValueConsumer() {
@Override
public void visitValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
if (ValueUtil.isRegister(value)) {
final Register reg = ValueUtil.asRegister(value);
+ if (!preservedRegisters.contains(reg)) {
destroyedRegisters.add(reg);
}
}
+ }
};
+ boolean sawSaveRegisters = false;
for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
if (block == null) {
continue;
}
+ // Ignore the effects of instructions bracketed by save/restore
+ SaveRegistersOp save = null;
for (LIRInstruction op : lir.getLIRforBlock(block)) {
if (op instanceof LabelOp) {
// Don't consider this as a definition
+ } else if (op instanceof SaveRegistersOp) {
+ save = (SaveRegistersOp) op;
+ sawSaveRegisters = true;
+ preservedRegisters.addAll(save.getSaveableRegisters());
+ } else if (op instanceof RestoreRegistersOp) {
+ save = null;
+ preservedRegisters.clear();
} else {
op.visitEachTemp(defConsumer);
op.visitEachOutput(defConsumer);
}
}
+ assert save == null : "missing RestoreRegistersOp";
+ }
+
+ if (sawSaveRegisters) {
+ // The return value must be killed so it can be propagated out
+ CallingConvention cc = gen.getCallingConvention();
+ AllocatableValue returnValue = cc.getReturn();
+ if (returnValue != null) {
+ if (ValueUtil.isRegister(returnValue)) {
+ destroyedRegisters.add(ValueUtil.asRegister(returnValue));
+ }
+ }
}
return translateToCallerRegisters(destroyedRegisters);
}
/**
*** 462,495 ****
* register windows on SPARC). Registers which are not visible by the caller are removed.
*/
protected abstract EconomicSet<Register> translateToCallerRegisters(EconomicSet<Register> calleeRegisters);
/**
! * Updates a given stub with respect to the registers it destroys.
! * <p>
! * Any entry in {@code calleeSaveInfo} that {@linkplain SaveRegistersOp#supportsRemove()
! * supports} pruning will have {@code destroyedRegisters}
! * {@linkplain SaveRegistersOp#remove(EconomicSet) removed} as these registers are declared as
! * temporaries in the stub's {@linkplain ForeignCallLinkage linkage} (and thus will be saved by
! * the stub's caller).
*
* @param stub the stub to update
! * @param destroyedRegisters the registers destroyed by the stub
! * @param calleeSaveInfo a map from debug infos to the operations that provide their
! * {@linkplain RegisterSaveLayout callee-save information}
* @param frameMap used to {@linkplain FrameMap#offsetForStackSlot(StackSlot) convert} a virtual
- * slot to a frame slot index
*/
! protected void updateStub(Stub stub, EconomicSet<Register> destroyedRegisters, EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo, FrameMap frameMap) {
stub.initDestroyedCallerRegisters(destroyedRegisters);
MapCursor<LIRFrameState, SaveRegistersOp> cursor = calleeSaveInfo.getEntries();
while (cursor.advance()) {
SaveRegistersOp save = cursor.getValue();
- if (save.supportsRemove()) {
save.remove(destroyedRegisters);
- }
if (cursor.getKey() != LIRFrameState.NO_STATE) {
cursor.getKey().debugInfo().setCalleeSaveInfo(save.getMap(frameMap));
}
}
}
--- 490,528 ----
* register windows on SPARC). Registers which are not visible by the caller are removed.
*/
protected abstract EconomicSet<Register> translateToCallerRegisters(EconomicSet<Register> calleeRegisters);
/**
! * Updates a given stub with respect to the registers it destroys by
! * {@link #gatherDestroyedCallerRegisters(HotSpotLIRGenerationResult) computing the destroyed
! * registers} and removing those registers from the {@linkplain SaveRegistersOp SaveRegistersOp}
! * as these registers are declared as temporaries in the stub's {@linkplain ForeignCallLinkage
! * linkage} (and thus will be saved by the stub's caller).
*
* @param stub the stub to update
! * @param gen the HotSpotLIRGenerationResult being emitted
* @param frameMap used to {@linkplain FrameMap#offsetForStackSlot(StackSlot) convert} a virtual
*/
! protected void updateStub(Stub stub, HotSpotLIRGenerationResult gen, FrameMap frameMap) {
! EconomicSet<Register> destroyedRegisters = gatherDestroyedCallerRegisters(gen);
! EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo = gen.getCalleeSaveInfo();
!
! if (stub.getLinkage().needsDebugInfo() && calleeSaveInfo.isEmpty()) {
! // This call is a safepoint but no register saving was done so we must ensure that all
! // registers appear to be killed. The Native ABI may allow caller save registers but
! // for HotSpot they must be described in a RegisterMap so they are accessible.
! for (Register r : frameMap.getRegisterConfig().getCallerSaveRegisters()) {
! destroyedRegisters.add(r);
! }
! }
!
stub.initDestroyedCallerRegisters(destroyedRegisters);
MapCursor<LIRFrameState, SaveRegistersOp> cursor = calleeSaveInfo.getEntries();
while (cursor.advance()) {
SaveRegistersOp save = cursor.getValue();
save.remove(destroyedRegisters);
if (cursor.getKey() != LIRFrameState.NO_STATE) {
cursor.getKey().debugInfo().setCalleeSaveInfo(save.getMap(frameMap));
}
}
}
< prev index next >