changeset 22445:788378056800

TraceRA: add custom TraceLinearScanAssignLocationsPhase.
author Josef Eisl <josef.eisl@jku.at>
date Thu, 13 Aug 2015 11:19:18 +0200
parents 76d3ae762bdf
children 68c0237791e8
files graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java
diffstat 2 files changed, 95 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java	Thu Aug 13 10:10:44 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java	Thu Aug 13 11:19:18 2015 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.lir.alloc.trace.TraceLinearScan.Options.*;
+import static com.oracle.graal.lir.alloc.trace.TraceRegisterAllocationPhase.Options.*;
 
 import java.util.*;
 
@@ -129,6 +130,14 @@
     }
 
     @Override
+    protected LinearScanAssignLocationsPhase createAssignLocationsPhase() {
+        if (TraceRAshareSpillInformation.getValue()) {
+            return new TraceLinearScanAssignLocationsPhase(this, traceBuilderResult);
+        }
+        return new LinearScanAssignLocationsPhase(this);
+    }
+
+    @Override
     public void printIntervals(String label) {
         if (Debug.isDumpEnabled(TraceRegisterAllocationPhase.TRACE_DUMP_LEVEL)) {
             super.printIntervals(label);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java	Thu Aug 13 11:19:18 2015 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, 2015, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.alloc.trace;
+
+import static jdk.internal.jvmci.code.ValueUtil.*;
+import jdk.internal.jvmci.meta.*;
+
+import com.oracle.graal.compiler.common.alloc.TraceBuilder.TraceBuilderResult;
+import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
+import com.oracle.graal.lir.alloc.lsra.*;
+
+/**
+ * TODO(zapster) document me!
+ */
+class TraceLinearScanAssignLocationsPhase extends LinearScanAssignLocationsPhase {
+
+    private final TraceBuilderResult<?> traceBuilderResult;
+
+    TraceLinearScanAssignLocationsPhase(LinearScan allocator, TraceBuilderResult<?> traceBuilderResult) {
+        super(allocator);
+        this.traceBuilderResult = traceBuilderResult;
+    }
+
+    @Override
+    protected Value colorLirOperand(LIRInstruction op, Variable operand, OperandMode mode) {
+        if (!isBlockEndWithEdgeToUnallocatedTrace(op)) {
+            return super.colorLirOperand(op, operand, mode);
+        }
+
+        int opId = op.id();
+        Interval interval = allocator.intervalFor(operand);
+        assert interval != null : "interval must exist";
+
+        /*
+         * Operands are not changed when an interval is split during allocation, so search the right
+         * interval here.
+         */
+        interval = allocator.splitChildAtOpId(interval, opId, mode);
+
+        if (isIllegal(interval.location()) && interval.canMaterialize()) {
+            assert mode != OperandMode.DEF;
+            return interval.getMaterializedValue();
+        }
+        return interval.location();
+    }
+
+    private boolean isBlockEndWithEdgeToUnallocatedTrace(LIRInstruction op) {
+        if (!(op instanceof BlockEndOp)) {
+            return false;
+        }
+        AbstractBlockBase<?> block = allocator.blockForId(op.id());
+        int currentTrace = traceBuilderResult.getTraceForBlock(block);
+
+        for (AbstractBlockBase<?> succ : block.getSuccessors()) {
+            if (currentTrace < traceBuilderResult.getTraceForBlock(succ)) {
+                // succ is not yet allocated
+                return true;
+            }
+        }
+        return false;
+    }
+
+}