src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/lir/HotSpotZapRegistersPhase.java
changeset 58299 6df94ce3ab2f
parent 52910 583fd71c47d6
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/lir/HotSpotZapRegistersPhase.java	Tue Sep 24 08:54:08 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/lir/HotSpotZapRegistersPhase.java	Tue Sep 24 12:47:15 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -28,23 +28,28 @@
 
 import java.util.ArrayList;
 
+import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.Indent;
 import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
 import org.graalvm.compiler.hotspot.stubs.Stub;
 import org.graalvm.compiler.lir.LIR;
-import org.graalvm.compiler.lir.LIRFrameState;
 import org.graalvm.compiler.lir.LIRInsertionBuffer;
 import org.graalvm.compiler.lir.LIRInstruction;
-import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
+import org.graalvm.compiler.lir.StandardOp.ZapRegistersOp;
+import org.graalvm.compiler.lir.ValueConsumer;
 import org.graalvm.compiler.lir.gen.DiagnosticLIRGeneratorTool;
 import org.graalvm.compiler.lir.gen.DiagnosticLIRGeneratorTool.ZapRegistersAfterInstruction;
 import org.graalvm.compiler.lir.gen.DiagnosticLIRGeneratorTool.ZapStackArgumentSpaceBeforeInstruction;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.phases.PostAllocationOptimizationPhase;
 
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.ValueUtil;
 import jdk.vm.ci.meta.AllocatableValue;
 
 /**
@@ -58,9 +63,10 @@
     @Override
     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PostAllocationOptimizationContext context) {
         Stub stub = ((HotSpotLIRGenerationResult) lirGenRes).getStub();
-        boolean zapRegisters = stub != null && !stub.preservesRegisters();
+        boolean zapRegisters = stub == null;
         boolean zapStack = false;
-        for (AllocatableValue arg : lirGenRes.getCallingConvention().getArguments()) {
+        CallingConvention callingConvention = lirGenRes.getCallingConvention();
+        for (AllocatableValue arg : callingConvention.getArguments()) {
             if (isStackSlot(arg)) {
                 zapStack = true;
                 break;
@@ -68,21 +74,25 @@
         }
         if (zapRegisters || zapStack) {
             LIR lir = lirGenRes.getLIR();
-            processLIR(context.diagnosticLirGenTool, (HotSpotLIRGenerationResult) lirGenRes, lir, zapRegisters, zapStack);
+            EconomicSet<Register> allocatableRegisters = EconomicSet.create(Equivalence.IDENTITY);
+            for (Register r : lirGenRes.getFrameMap().getRegisterConfig().getAllocatableRegisters()) {
+                allocatableRegisters.add(r);
+            }
+            processLIR(context.diagnosticLirGenTool, lir, allocatableRegisters, zapRegisters, zapStack);
         }
     }
 
-    private static void processLIR(DiagnosticLIRGeneratorTool diagnosticLirGenTool, HotSpotLIRGenerationResult res, LIR lir, boolean zapRegisters, boolean zapStack) {
+    private static void processLIR(DiagnosticLIRGeneratorTool diagnosticLirGenTool, LIR lir, EconomicSet<Register> allocatableRegisters, boolean zapRegisters, boolean zapStack) {
         LIRInsertionBuffer buffer = new LIRInsertionBuffer();
         for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
             if (block != null) {
-                processBlock(diagnosticLirGenTool, res, lir, buffer, block, zapRegisters, zapStack);
+                processBlock(diagnosticLirGenTool, lir, allocatableRegisters, buffer, block, zapRegisters, zapStack);
             }
         }
     }
 
     @SuppressWarnings("try")
-    private static void processBlock(DiagnosticLIRGeneratorTool diagnosticLirGenTool, HotSpotLIRGenerationResult res, LIR lir, LIRInsertionBuffer buffer, AbstractBlockBase<?> block,
+    private static void processBlock(DiagnosticLIRGeneratorTool diagnosticLirGenTool, LIR lir, EconomicSet<Register> allocatableRegisters, LIRInsertionBuffer buffer, AbstractBlockBase<?> block,
                     boolean zapRegisters, boolean zapStack) {
         DebugContext debug = lir.getDebug();
         try (Indent indent = debug.logAndIndent("Process block %s", block)) {
@@ -97,31 +107,30 @@
                     }
                 }
                 if (zapRegisters && inst instanceof ZapRegistersAfterInstruction) {
-                    LIRFrameState state = getLIRState(inst);
-                    if (state != null) {
-                        SaveRegistersOp zap = diagnosticLirGenTool.createZapRegisters();
-                        SaveRegistersOp old = res.getCalleeSaveInfo().put(state, zap);
-                        assert old == null : "Already another SaveRegisterOp registered! " + old;
-                        buffer.append(index + 1, (LIRInstruction) zap);
-                        debug.log("Insert ZapRegister after %s", inst);
-                    }
+                    final EconomicSet<Register> destroyedRegisters = EconomicSet.create(Equivalence.IDENTITY);
+                    ValueConsumer tempConsumer = (value, mode, flags) -> {
+                        if (ValueUtil.isRegister(value)) {
+                            final Register reg = ValueUtil.asRegister(value);
+                            if (allocatableRegisters.contains(reg)) {
+                                destroyedRegisters.add(reg);
+                            }
+                        }
+                    };
+                    ValueConsumer defConsumer = (value, mode, flags) -> {
+                        if (ValueUtil.isRegister(value)) {
+                            final Register reg = ValueUtil.asRegister(value);
+                            destroyedRegisters.remove(reg);
+                        }
+                    };
+                    inst.visitEachTemp(tempConsumer);
+                    inst.visitEachOutput(defConsumer);
+
+                    ZapRegistersOp zap = diagnosticLirGenTool.createZapRegisters(destroyedRegisters.toArray(new Register[destroyedRegisters.size()]));
+                    buffer.append(index + 1, (LIRInstruction) zap);
+                    debug.log("Insert ZapRegister after %s", inst);
                 }
             }
             buffer.finish();
         }
     }
-
-    /**
-     * Returns the {@link LIRFrameState} of an instruction.
-     */
-    private static LIRFrameState getLIRState(LIRInstruction inst) {
-        final LIRFrameState[] lirState = {null};
-        inst.forEachState(state -> {
-            assert lirState[0] == null : "Multiple states: " + inst;
-            lirState[0] = state;
-        });
-        assert lirState[0] != null : "No state: " + inst;
-        return lirState[0];
-    }
-
 }