1 /*
2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
29 import java.util.EnumSet;
30
31 import jdk.internal.vm.compiler.collections.EconomicMap;
32 import jdk.internal.vm.compiler.collections.EconomicSet;
33 import jdk.internal.vm.compiler.collections.Equivalence;
34 import jdk.internal.vm.compiler.collections.MapCursor;
35 import org.graalvm.compiler.code.CompilationResult;
36 import org.graalvm.compiler.core.common.CompilationIdentifier;
37 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
38 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
39 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
40 import org.graalvm.compiler.core.target.Backend;
41 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
42 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
43 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
44 import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
45 import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantStubCall;
46 import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions;
47 import org.graalvm.compiler.hotspot.replacements.BigIntegerSubstitutions;
48 import org.graalvm.compiler.hotspot.replacements.CipherBlockChainingSubstitutions;
49 import org.graalvm.compiler.hotspot.replacements.SHA2Substitutions;
50 import org.graalvm.compiler.hotspot.replacements.SHA5Substitutions;
51 import org.graalvm.compiler.hotspot.replacements.SHASubstitutions;
52 import org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub;
53 import org.graalvm.compiler.hotspot.stubs.Stub;
54 import org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub;
55 import org.graalvm.compiler.hotspot.word.KlassPointer;
56 import org.graalvm.compiler.hotspot.word.MethodCountersPointer;
57 import org.graalvm.compiler.lir.LIR;
58 import org.graalvm.compiler.lir.LIRFrameState;
59 import org.graalvm.compiler.lir.LIRInstruction;
60 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
61 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
62 import org.graalvm.compiler.lir.StandardOp.LabelOp;
63 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
64 import org.graalvm.compiler.lir.ValueConsumer;
65 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
66 import org.graalvm.compiler.lir.framemap.FrameMap;
67 import org.graalvm.compiler.nodes.UnwindNode;
68 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
69 import org.graalvm.compiler.options.Option;
70 import org.graalvm.compiler.options.OptionKey;
71 import org.graalvm.compiler.options.OptionType;
72 import org.graalvm.compiler.options.OptionValues;
73 import org.graalvm.compiler.phases.tiers.SuitesProvider;
74 import org.graalvm.compiler.word.Word;
75 import jdk.internal.vm.compiler.word.Pointer;
76
77 import jdk.vm.ci.code.CompilationRequest;
78 import jdk.vm.ci.code.CompiledCode;
79 import jdk.vm.ci.code.Register;
80 import jdk.vm.ci.code.RegisterSaveLayout;
81 import jdk.vm.ci.code.StackSlot;
82 import jdk.vm.ci.code.ValueUtil;
83 import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
84 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
85 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
86 import jdk.vm.ci.meta.ResolvedJavaMethod;
87 import jdk.vm.ci.meta.Value;
88 import jdk.vm.ci.runtime.JVMCICompiler;
89
90 /**
91 * HotSpot specific backend.
92 */
93 public abstract class HotSpotBackend extends Backend implements FrameMap.ReferenceMapBuilderFactory {
94
95 public static class Options {
96 // @formatter:off
97 @Option(help = "Use Graal arithmetic stubs instead of HotSpot stubs where possible")
98 public static final OptionKey<Boolean> GraalArithmeticStubs = new OptionKey<>(false); // GR-8276
99 @Option(help = "Enables instruction profiling on assembler level. Valid values are a comma separated list of supported instructions." +
100 " Compare with subclasses of Assembler.InstructionCounter.", type = OptionType.Debug)
101 public static final OptionKey<String> ASMInstructionProfiling = new OptionKey<>(null);
102 // @formatter:on
103 }
104
105 /**
106 * Descriptor for {@link ExceptionHandlerStub}. This stub is called by the
107 * {@linkplain GraalHotSpotVMConfig#MARKID_EXCEPTION_HANDLER_ENTRY exception handler} in a
108 * compiled method.
109 */
110 public static final ForeignCallDescriptor EXCEPTION_HANDLER = new ForeignCallDescriptor("exceptionHandler", void.class, Object.class, Word.class);
111
112 /**
113 * Descriptor for SharedRuntime::get_ic_miss_stub().
114 */
115 public static final ForeignCallDescriptor IC_MISS_HANDLER = new ForeignCallDescriptor("icMissHandler", void.class);
116
117 /**
118 * Descriptor for SharedRuntime::get_handle_wrong_method_stub().
244
245 public static void sha2ImplCompressStub(Word bufAddr, Object state) {
246 sha2ImplCompressStub(HotSpotBackend.SHA2_IMPL_COMPRESS, bufAddr, state);
247 }
248
249 @NodeIntrinsic(ForeignCallNode.class)
250 private static native void sha2ImplCompressStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state);
251
252 /**
253 * @see SHA5Substitutions#implCompress0
254 */
255 public static final ForeignCallDescriptor SHA5_IMPL_COMPRESS = new ForeignCallDescriptor("sha5ImplCompress", void.class, Word.class, Object.class);
256
257 public static void sha5ImplCompressStub(Word bufAddr, Object state) {
258 sha5ImplCompressStub(HotSpotBackend.SHA5_IMPL_COMPRESS, bufAddr, state);
259 }
260
261 @NodeIntrinsic(ForeignCallNode.class)
262 private static native void sha5ImplCompressStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state);
263
264 public static void unsafeArraycopy(Word srcAddr, Word dstAddr, Word size) {
265 unsafeArraycopyStub(UNSAFE_ARRAYCOPY, srcAddr, dstAddr, size);
266 }
267
268 @NodeIntrinsic(ForeignCallNode.class)
269 private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word size);
270
271 /**
272 * @see VMErrorNode
273 */
274 public static final ForeignCallDescriptor VM_ERROR = new ForeignCallDescriptor("vm_error", void.class, Object.class, Object.class, long.class);
275
276 /**
277 * New multi array stub that throws an {@link OutOfMemoryError} on allocation failure.
278 */
279 public static final ForeignCallDescriptor NEW_MULTI_ARRAY = new ForeignCallDescriptor("new_multi_array", Object.class, KlassPointer.class, int.class, Word.class);
280
281 /**
282 * New multi array stub that will return null on allocation failure.
283 */
284 public static final ForeignCallDescriptor NEW_MULTI_ARRAY_OR_NULL = new ForeignCallDescriptor("new_multi_array_or_null", Object.class, KlassPointer.class, int.class, Word.class);
285
286 /**
287 * New array stub that throws an {@link OutOfMemoryError} on allocation failure.
288 */
289 public static final ForeignCallDescriptor NEW_ARRAY = new ForeignCallDescriptor("new_array", Object.class, KlassPointer.class, int.class);
290
291 /**
370 final Register reg = ValueUtil.asRegister(value);
371 destroyedRegisters.add(reg);
372 }
373 }
374 };
375 for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
376 if (block == null) {
377 continue;
378 }
379 for (LIRInstruction op : lir.getLIRforBlock(block)) {
380 if (op instanceof LabelOp) {
381 // Don't consider this as a definition
382 } else {
383 op.visitEachTemp(defConsumer);
384 op.visitEachOutput(defConsumer);
385 }
386 }
387 }
388 return translateToCallerRegisters(destroyedRegisters);
389 }
390
391 /**
392 * Updates a given stub with respect to the registers it destroys.
393 * <p>
394 * Any entry in {@code calleeSaveInfo} that {@linkplain SaveRegistersOp#supportsRemove()
395 * supports} pruning will have {@code destroyedRegisters}
396 * {@linkplain SaveRegistersOp#remove(EconomicSet) removed} as these registers are declared as
397 * temporaries in the stub's {@linkplain ForeignCallLinkage linkage} (and thus will be saved by
398 * the stub's caller).
399 *
400 * @param stub the stub to update
401 * @param destroyedRegisters the registers destroyed by the stub
402 * @param calleeSaveInfo a map from debug infos to the operations that provide their
403 * {@linkplain RegisterSaveLayout callee-save information}
404 * @param frameMap used to {@linkplain FrameMap#offsetForStackSlot(StackSlot) convert} a virtual
405 * slot to a frame slot index
406 */
407 protected void updateStub(Stub stub, EconomicSet<Register> destroyedRegisters, EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo, FrameMap frameMap) {
408 stub.initDestroyedCallerRegisters(destroyedRegisters);
409
|
1 /*
2 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
29 import java.util.EnumSet;
30
31 import jdk.internal.vm.compiler.collections.EconomicMap;
32 import jdk.internal.vm.compiler.collections.EconomicSet;
33 import jdk.internal.vm.compiler.collections.Equivalence;
34 import jdk.internal.vm.compiler.collections.MapCursor;
35 import org.graalvm.compiler.code.CompilationResult;
36 import org.graalvm.compiler.core.common.CompilationIdentifier;
37 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
38 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
39 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
40 import org.graalvm.compiler.core.target.Backend;
41 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
42 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
43 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
44 import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
45 import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantStubCall;
46 import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions;
47 import org.graalvm.compiler.hotspot.replacements.BigIntegerSubstitutions;
48 import org.graalvm.compiler.hotspot.replacements.CipherBlockChainingSubstitutions;
49 import org.graalvm.compiler.hotspot.replacements.DigestBaseSubstitutions;
50 import org.graalvm.compiler.hotspot.replacements.SHA2Substitutions;
51 import org.graalvm.compiler.hotspot.replacements.SHA5Substitutions;
52 import org.graalvm.compiler.hotspot.replacements.SHASubstitutions;
53 import org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub;
54 import org.graalvm.compiler.hotspot.stubs.Stub;
55 import org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub;
56 import org.graalvm.compiler.hotspot.word.KlassPointer;
57 import org.graalvm.compiler.hotspot.word.MethodCountersPointer;
58 import org.graalvm.compiler.lir.LIR;
59 import org.graalvm.compiler.lir.LIRFrameState;
60 import org.graalvm.compiler.lir.LIRInstruction;
61 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
62 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
63 import org.graalvm.compiler.lir.StandardOp.LabelOp;
64 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
65 import org.graalvm.compiler.lir.ValueConsumer;
66 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
67 import org.graalvm.compiler.lir.framemap.FrameMap;
68 import org.graalvm.compiler.nodes.UnwindNode;
69 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
70 import org.graalvm.compiler.options.Option;
71 import org.graalvm.compiler.options.OptionKey;
72 import org.graalvm.compiler.options.OptionType;
73 import org.graalvm.compiler.options.OptionValues;
74 import org.graalvm.compiler.phases.tiers.SuitesProvider;
75 import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
76 import org.graalvm.compiler.word.Word;
77 import jdk.internal.vm.compiler.word.Pointer;
78
79 import jdk.vm.ci.code.CompilationRequest;
80 import jdk.vm.ci.code.CompiledCode;
81 import jdk.vm.ci.code.Register;
82 import jdk.vm.ci.code.RegisterSaveLayout;
83 import jdk.vm.ci.code.StackSlot;
84 import jdk.vm.ci.code.ValueUtil;
85 import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
86 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
87 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
88 import jdk.vm.ci.meta.ResolvedJavaMethod;
89 import jdk.vm.ci.meta.Value;
90 import jdk.vm.ci.runtime.JVMCICompiler;
91
92 /**
93 * HotSpot specific backend.
94 */
95 public abstract class HotSpotBackend extends Backend implements FrameMap.ReferenceMapBuilderFactory {
96
97 public static class Options {
98 // @formatter:off
99 @Option(help = "Use Graal arithmetic stubs instead of HotSpot stubs where possible")
100 public static final OptionKey<Boolean> GraalArithmeticStubs = new OptionKey<>(JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 9);
101 @Option(help = "Enables instruction profiling on assembler level. Valid values are a comma separated list of supported instructions." +
102 " Compare with subclasses of Assembler.InstructionCounter.", type = OptionType.Debug)
103 public static final OptionKey<String> ASMInstructionProfiling = new OptionKey<>(null);
104 // @formatter:on
105 }
106
107 /**
108 * Descriptor for {@link ExceptionHandlerStub}. This stub is called by the
109 * {@linkplain GraalHotSpotVMConfig#MARKID_EXCEPTION_HANDLER_ENTRY exception handler} in a
110 * compiled method.
111 */
112 public static final ForeignCallDescriptor EXCEPTION_HANDLER = new ForeignCallDescriptor("exceptionHandler", void.class, Object.class, Word.class);
113
114 /**
115 * Descriptor for SharedRuntime::get_ic_miss_stub().
116 */
117 public static final ForeignCallDescriptor IC_MISS_HANDLER = new ForeignCallDescriptor("icMissHandler", void.class);
118
119 /**
120 * Descriptor for SharedRuntime::get_handle_wrong_method_stub().
246
247 public static void sha2ImplCompressStub(Word bufAddr, Object state) {
248 sha2ImplCompressStub(HotSpotBackend.SHA2_IMPL_COMPRESS, bufAddr, state);
249 }
250
251 @NodeIntrinsic(ForeignCallNode.class)
252 private static native void sha2ImplCompressStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state);
253
254 /**
255 * @see SHA5Substitutions#implCompress0
256 */
257 public static final ForeignCallDescriptor SHA5_IMPL_COMPRESS = new ForeignCallDescriptor("sha5ImplCompress", void.class, Word.class, Object.class);
258
259 public static void sha5ImplCompressStub(Word bufAddr, Object state) {
260 sha5ImplCompressStub(HotSpotBackend.SHA5_IMPL_COMPRESS, bufAddr, state);
261 }
262
263 @NodeIntrinsic(ForeignCallNode.class)
264 private static native void sha5ImplCompressStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state);
265
266 /**
267 * @see DigestBaseSubstitutions#implCompressMultiBlock0
268 */
269 public static final ForeignCallDescriptor SHA_IMPL_COMPRESS_MB = new ForeignCallDescriptor("shaImplCompressMB", int.class, Word.class, Object.class, int.class, int.class);
270
271 public static int shaImplCompressMBStub(Word bufAddr, Object stateAddr, int ofs, int limit) {
272 return shaImplCompressMBStub(HotSpotBackend.SHA_IMPL_COMPRESS_MB, bufAddr, stateAddr, ofs, limit);
273 }
274
275 @NodeIntrinsic(ForeignCallNode.class)
276 private static native int shaImplCompressMBStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state, int ofs, int limit);
277
278 public static final ForeignCallDescriptor SHA2_IMPL_COMPRESS_MB = new ForeignCallDescriptor("sha2ImplCompressMB", int.class, Word.class, Object.class, int.class, int.class);
279
280 public static int sha2ImplCompressMBStub(Word bufAddr, Object stateAddr, int ofs, int limit) {
281 return sha2ImplCompressMBStub(HotSpotBackend.SHA2_IMPL_COMPRESS_MB, bufAddr, stateAddr, ofs, limit);
282 }
283
284 @NodeIntrinsic(ForeignCallNode.class)
285 private static native int sha2ImplCompressMBStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state, int ofs, int limit);
286
287 public static final ForeignCallDescriptor SHA5_IMPL_COMPRESS_MB = new ForeignCallDescriptor("sha5ImplCompressMB", int.class, Word.class, Object.class, int.class, int.class);
288
289 public static int sha5ImplCompressMBStub(Word bufAddr, Object stateAddr, int ofs, int limit) {
290 return sha5ImplCompressMBStub(HotSpotBackend.SHA5_IMPL_COMPRESS_MB, bufAddr, stateAddr, ofs, limit);
291 }
292
293 @NodeIntrinsic(ForeignCallNode.class)
294 private static native int sha5ImplCompressMBStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state, int ofs, int limit);
295
296 public static void unsafeArraycopy(Word srcAddr, Word dstAddr, Word size) {
297 unsafeArraycopyStub(UNSAFE_ARRAYCOPY, srcAddr, dstAddr, size);
298 }
299
300 @NodeIntrinsic(ForeignCallNode.class)
301 private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word size);
302
303 /**
304 * Descriptor for {@code StubRoutines::_ghash_processBlocks}.
305 */
306 public static final ForeignCallDescriptor GHASH_PROCESS_BLOCKS = new ForeignCallDescriptor("ghashProcessBlocks", void.class, Word.class, Word.class, Word.class, int.class);
307
308 /**
309 * Descriptor for {@code StubRoutines::_counterMode_AESCrypt}.
310 */
311 public static final ForeignCallDescriptor COUNTERMODE_IMPL_CRYPT = new ForeignCallDescriptor("counterModeAESCrypt", int.class, Word.class, Word.class, Word.class, Word.class, int.class,
312 Word.class, Word.class);
313
314 public static int counterModeAESCrypt(Word srcAddr, Word dstAddr, Word kPtr, Word cntPtr, int len, Word encCntPtr, Word used) {
315 return counterModeAESCrypt(COUNTERMODE_IMPL_CRYPT, srcAddr, dstAddr, kPtr, cntPtr, len, encCntPtr, used);
316 }
317
318 @NodeIntrinsic(ForeignCallNode.class)
319 private static native int counterModeAESCrypt(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word kPtr, Word cntPtr, int len, Word encCntPtr,
320 Word used);
321
322 /**
323 * Descriptor for {@code StubRoutines::_vectorizedMismatch}.
324 */
325 public static final ForeignCallDescriptor VECTORIZED_MISMATCHED = new ForeignCallDescriptor("vectorizedMismatch", int.class, Word.class, Word.class, int.class, int.class);
326
327 public static int vectorizedMismatch(Word aAddr, Word bAddr, int length, int log2ArrayIndexScale) {
328 return vectorizedMismatchStub(VECTORIZED_MISMATCHED, aAddr, bAddr, length, log2ArrayIndexScale);
329 }
330
331 @NodeIntrinsic(ForeignCallNode.class)
332 private static native int vectorizedMismatchStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word aAddr, Word bAddr, int length, int log2ArrayIndexScale);
333
334 /**
335 * @see VMErrorNode
336 */
337 public static final ForeignCallDescriptor VM_ERROR = new ForeignCallDescriptor("vm_error", void.class, Object.class, Object.class, long.class);
338
339 /**
340 * New multi array stub that throws an {@link OutOfMemoryError} on allocation failure.
341 */
342 public static final ForeignCallDescriptor NEW_MULTI_ARRAY = new ForeignCallDescriptor("new_multi_array", Object.class, KlassPointer.class, int.class, Word.class);
343
344 /**
345 * New multi array stub that will return null on allocation failure.
346 */
347 public static final ForeignCallDescriptor NEW_MULTI_ARRAY_OR_NULL = new ForeignCallDescriptor("new_multi_array_or_null", Object.class, KlassPointer.class, int.class, Word.class);
348
349 /**
350 * New array stub that throws an {@link OutOfMemoryError} on allocation failure.
351 */
352 public static final ForeignCallDescriptor NEW_ARRAY = new ForeignCallDescriptor("new_array", Object.class, KlassPointer.class, int.class);
353
354 /**
433 final Register reg = ValueUtil.asRegister(value);
434 destroyedRegisters.add(reg);
435 }
436 }
437 };
438 for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
439 if (block == null) {
440 continue;
441 }
442 for (LIRInstruction op : lir.getLIRforBlock(block)) {
443 if (op instanceof LabelOp) {
444 // Don't consider this as a definition
445 } else {
446 op.visitEachTemp(defConsumer);
447 op.visitEachOutput(defConsumer);
448 }
449 }
450 }
451 return translateToCallerRegisters(destroyedRegisters);
452 }
453
454 /**
455 * Translates a set of registers from the callee's perspective to the caller's perspective. This
456 * is needed for architectures where input/output registers are renamed during a call (e.g.
457 * register windows on SPARC). Registers which are not visible by the caller are removed.
458 */
459 protected abstract EconomicSet<Register> translateToCallerRegisters(EconomicSet<Register> calleeRegisters);
460
461 /**
462 * Updates a given stub with respect to the registers it destroys.
463 * <p>
464 * Any entry in {@code calleeSaveInfo} that {@linkplain SaveRegistersOp#supportsRemove()
465 * supports} pruning will have {@code destroyedRegisters}
466 * {@linkplain SaveRegistersOp#remove(EconomicSet) removed} as these registers are declared as
467 * temporaries in the stub's {@linkplain ForeignCallLinkage linkage} (and thus will be saved by
468 * the stub's caller).
469 *
470 * @param stub the stub to update
471 * @param destroyedRegisters the registers destroyed by the stub
472 * @param calleeSaveInfo a map from debug infos to the operations that provide their
473 * {@linkplain RegisterSaveLayout callee-save information}
474 * @param frameMap used to {@linkplain FrameMap#offsetForStackSlot(StackSlot) convert} a virtual
475 * slot to a frame slot index
476 */
477 protected void updateStub(Stub stub, EconomicSet<Register> destroyedRegisters, EconomicMap<LIRFrameState, SaveRegistersOp> calleeSaveInfo, FrameMap frameMap) {
478 stub.initDestroyedCallerRegisters(destroyedRegisters);
479
|