# HG changeset patch # User Tom Rodriguez # Date 1438114754 25200 # Node ID bdfd42480dc9c9e610bd751186cbbe04ac3874ff # Parent 59a2f85de5c7633880f5539eb64df10af788eb8a# Parent 88b62301053750892b16f4d01126f95b264605e4 Merge diff -r 59a2f85de5c7 -r bdfd42480dc9 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java Tue Jul 28 13:00:32 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java Tue Jul 28 13:19:14 2015 -0700 @@ -46,7 +46,7 @@ public static class Options { // @formatter:off - @Option(help = "", type = OptionType.Debug) + @Option(help = "Use simplified lifetime analysis.", type = OptionType.Debug) public static final OptionValue TraceRAsimpleLifetimeAnalysis = new OptionValue<>(true); // @formatter:on } diff -r 59a2f85de5c7 -r bdfd42480dc9 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java Tue Jul 28 13:00:32 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java Tue Jul 28 13:19:14 2015 -0700 @@ -22,6 +22,7 @@ */ package com.oracle.graal.lir.alloc.trace; +import static com.oracle.graal.lir.alloc.trace.TraceRegisterAllocationPhase.Options.*; import static jdk.internal.jvmci.code.ValueUtil.*; import java.util.*; @@ -46,10 +47,14 @@ // @formatter:off @Option(help = "Use inter-trace register hints.", type = OptionType.Debug) public static final OptionValue TraceRAuseInterTraceHints = new OptionValue<>(true); + @Option(help = "Use special allocator for trivial blocks.", type = OptionType.Debug) + public static final OptionValue TraceRAtrivialBlockAllocator = new OptionValue<>(true); // @formatter:on } static final int TRACE_DUMP_LEVEL = 3; + private static final DebugMetric trivialTracesMetric = Debug.metric("TraceRA[trivialTraces]"); + private static final DebugMetric tracesMetric = Debug.metric("TraceRA[traces]"); @Override protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, SpillMoveFactory spillMoveFactory, @@ -64,9 +69,17 @@ int traceNumber = 0; for (List trace : resultTraces.getTraces()) { try (Indent i = Debug.logAndIndent("Allocating Trace%d: %s", traceNumber, trace); Scope s = Debug.scope("AllocateTrace", trace)) { + tracesMetric.increment(); + if (trivialTracesMetric.isEnabled() && isTrivialTrace(lir, trace)) { + trivialTracesMetric.increment(); + } Debug.dump(TRACE_DUMP_LEVEL, trace, "Trace" + traceNumber + ": " + trace); - TraceLinearScan allocator = new TraceLinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, trace, resultTraces); - allocator.allocate(target, lirGenRes, codeEmittingOrder, linearScanOrder, spillMoveFactory, registerAllocationConfig); + if (TraceRAtrivialBlockAllocator.getValue() && isTrivialTrace(lir, trace)) { + new TraceTrivialAllocator(resultTraces).apply(target, lirGenRes, codeEmittingOrder, trace, new AllocationContext(spillMoveFactory, registerAllocationConfig), false); + } else { + TraceLinearScan allocator = new TraceLinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, trace, resultTraces); + allocator.allocate(target, lirGenRes, codeEmittingOrder, linearScanOrder, spillMoveFactory, registerAllocationConfig); + } Debug.dump(TRACE_DUMP_LEVEL, trace, "After Trace" + traceNumber + ": " + trace); traceNumber++; } catch (Throwable e) { @@ -95,6 +108,10 @@ } } + static boolean isTrivialTrace(LIR lir, List> trace) { + return trace.size() == 1 && lir.getLIRforBlock(trace.iterator().next()).size() == 2; + } + /** * Fixup stack to stack moves introduced by stack arguments. * diff -r 59a2f85de5c7 -r bdfd42480dc9 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java Tue Jul 28 13:19:14 2015 -0700 @@ -0,0 +1,90 @@ +/* + * 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 com.oracle.graal.lir.LIRValueUtil.*; +import static com.oracle.graal.lir.alloc.trace.TraceRegisterAllocationPhase.*; + +import java.util.*; + +import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.meta.*; + +import com.oracle.graal.compiler.common.alloc.*; +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.StandardOp.BlockEndOp; +import com.oracle.graal.lir.StandardOp.LabelOp; +import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; +import com.oracle.graal.lir.phases.*; +import com.oracle.graal.lir.ssi.*; +import com.oracle.graal.lir.util.*; + +/** + * Allocates a trivial trace i.e. a trace consisting of a single block with no instructions other + * than the {@link LabelOp} and the {@link BlockEndOp}. + */ +public class TraceTrivialAllocator extends AllocationPhase { + + private final TraceBuilderResult resultTraces; + + public TraceTrivialAllocator(TraceBuilderResult resultTraces) { + this.resultTraces = resultTraces; + } + + @Override + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List trace, SpillMoveFactory spillMoveFactory, + RegisterAllocationConfig registerAllocationConfig) { + LIR lir = lirGenRes.getLIR(); + assert isTrivialTrace(lir, trace) : "Not a trivial trace! " + trace; + B block = trace.iterator().next(); + + AbstractBlockBase pred = TraceUtil.getBestTraceInterPredecessor(resultTraces, block); + + VariableVirtualStackValueMap variableMap = new VariableVirtualStackValueMap<>(lir.nextVariable(), 0); + SSIUtil.forEachValuePair(lir, block, pred, (to, from) -> { + if (isVariable(to)) { + variableMap.put(asVariable(to), from); + } + }); + + ValueProcedure outputConsumer = (value, mode, flags) -> { + if (isVariable(value)) { + return variableMap.get(asVariable(value)); + } + return value; + }; + + List instructions = lir.getLIRforBlock(block); + for (LIRInstruction op : instructions) { + + op.forEachOutput(outputConsumer); + op.forEachTemp(outputConsumer); + op.forEachAlive(outputConsumer); + op.forEachInput(outputConsumer); + op.forEachState(outputConsumer); + } + } +} diff -r 59a2f85de5c7 -r bdfd42480dc9 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceUtil.java Tue Jul 28 13:19:14 2015 -0700 @@ -0,0 +1,42 @@ +/* + * 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 com.oracle.graal.compiler.common.alloc.TraceBuilder.TraceBuilderResult; +import com.oracle.graal.compiler.common.cfg.*; + +class TraceUtil { + + static AbstractBlockBase getBestTraceInterPredecessor(TraceBuilderResult traceResult, AbstractBlockBase block) { + AbstractBlockBase bestPred = null; + int bestTraceId = traceResult.getTraceForBlock(block); + for (AbstractBlockBase pred : block.getPredecessors()) { + int predTraceId = traceResult.getTraceForBlock(pred); + if (predTraceId < bestTraceId) { + bestPred = pred; + bestTraceId = predTraceId; + } + } + return bestPred; + } +} diff -r 59a2f85de5c7 -r bdfd42480dc9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Tue Jul 28 13:00:32 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Tue Jul 28 13:19:14 2015 -0700 @@ -47,6 +47,7 @@ this.type = type; assert type != null; assert type.isConcrete() || type.isArray(); + assert ((ObjectStamp) object.stamp()).nonNull(); } public static LogicNode create(ResolvedJavaType type, ValueNode object) { @@ -71,7 +72,6 @@ return this; } ObjectStamp objectStamp = (ObjectStamp) forValue.stamp(); - assert objectStamp.nonNull(); ResolvedJavaType stampType = objectStamp.type(); if (stampType != null) {