< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/ssa/SSALinearScanLifetimeAnalysisPhase.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -22,18 +22,21 @@
  */
 
 
 package org.graalvm.compiler.lir.alloc.lsra.ssa;
 
+import java.util.BitSet;
 import java.util.EnumSet;
 
+import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.lir.LIR;
 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;
 import org.graalvm.compiler.lir.StandardOp.LabelOp;
-import org.graalvm.compiler.lir.ValueConsumer;
 import org.graalvm.compiler.lir.alloc.lsra.Interval;
 import org.graalvm.compiler.lir.alloc.lsra.Interval.RegisterPriority;
 import org.graalvm.compiler.lir.alloc.lsra.LinearScan;
 import org.graalvm.compiler.lir.alloc.lsra.LinearScanLifetimeAnalysisPhase;
 import org.graalvm.compiler.lir.ssa.SSAUtil;

@@ -51,21 +54,43 @@
     protected void addRegisterHint(final LIRInstruction op, final Value targetValue, OperandMode mode, EnumSet<OperandFlag> flags, final boolean hintAtDef) {
         super.addRegisterHint(op, targetValue, mode, flags, hintAtDef);
 
         if (hintAtDef && op instanceof LabelOp) {
             LabelOp label = (LabelOp) op;
+            if (!label.isPhiIn()) {
+                return;
+            }
 
             Interval to = allocator.getOrCreateInterval((AllocatableValue) targetValue);
 
-            SSAUtil.forEachPhiRegisterHint(allocator.getLIR(), allocator.blockForId(label.id()), label, targetValue, mode, (ValueConsumer) (registerHint, valueMode, valueFlags) -> {
-                if (LinearScan.isVariableOrRegister(registerHint)) {
-                    Interval from = allocator.getOrCreateInterval((AllocatableValue) registerHint);
-
-                    setHint(debug, op, to, from);
-                    setHint(debug, op, from, to);
+            LIR lir = allocator.getLIR();
+            AbstractBlockBase<?> block = allocator.blockForId(label.id());
+            assert mode == OperandMode.DEF : "Wrong operand mode: " + mode;
+            assert lir.getLIRforBlock(block).get(0).equals(label) : String.format("Block %s and Label %s do not match!", block, label);
+
+            int idx = SSAUtil.indexOfValue(label, targetValue);
+            assert idx >= 0 : String.format("Value %s not in label %s", targetValue, label);
+
+            BitSet blockLiveIn = allocator.getBlockData(block).liveIn;
+
+            AbstractBlockBase<?> selectedPredecessor = null;
+            AllocatableValue selectedSource = null;
+            for (AbstractBlockBase<?> pred : block.getPredecessors()) {
+                if (selectedPredecessor == null || pred.getRelativeFrequency() > selectedPredecessor.getRelativeFrequency()) {
+                    StandardOp.JumpOp jump = SSAUtil.phiOut(lir, pred);
+                    Value sourceValue = jump.getOutgoingValue(idx);
+                    if (LinearScan.isVariableOrRegister(sourceValue) && !blockLiveIn.get(getOperandNumber(sourceValue))) {
+                        selectedSource = (AllocatableValue) sourceValue;
+                        selectedPredecessor = pred;
+                    }
                 }
-            });
+            }
+            if (selectedSource != null) {
+                Interval from = allocator.getOrCreateInterval(selectedSource);
+                setHint(debug, op, to, from);
+                setHint(debug, op, from, to);
+            }
         }
     }
 
     public static void setHint(DebugContext debug, final LIRInstruction op, Interval target, Interval source) {
         Interval currentHint = target.locationHint(false);
< prev index next >