1 /* 2 * Copyright (c) 2015, 2016, 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 */ 23 package org.graalvm.compiler.lir.alloc.trace; 24 25 import static org.graalvm.compiler.lir.LIRValueUtil.asVariable; 26 import static org.graalvm.compiler.lir.LIRValueUtil.isVariable; 27 import static org.graalvm.compiler.lir.alloc.trace.TraceUtil.isTrivialTrace; 28 29 import java.util.EnumSet; 30 31 import org.graalvm.compiler.core.common.alloc.Trace; 32 import org.graalvm.compiler.core.common.alloc.TraceBuilderResult; 33 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; 34 import org.graalvm.compiler.lir.LIR; 35 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag; 36 import org.graalvm.compiler.lir.LIRInstruction.OperandMode; 37 import org.graalvm.compiler.lir.StandardOp.JumpOp; 38 import org.graalvm.compiler.lir.StandardOp.LabelOp; 39 import org.graalvm.compiler.lir.ValueProcedure; 40 import org.graalvm.compiler.lir.gen.LIRGenerationResult; 41 import org.graalvm.compiler.lir.ssa.SSAUtil; 42 43 import jdk.vm.ci.code.TargetDescription; 44 import jdk.vm.ci.meta.Value; 45 46 /** 47 * Allocates a trivial trace i.e. a trace consisting of a single block with no instructions other 48 * than the {@link LabelOp} and the {@link JumpOp}. 49 */ 50 final class TrivialTraceAllocator extends TraceAllocationPhase<TraceAllocationPhase.TraceAllocationContext> { 51 52 @Override 53 protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Trace trace, TraceAllocationContext context) { 54 LIR lir = lirGenRes.getLIR(); 55 TraceBuilderResult resultTraces = context.resultTraces; 56 assert isTrivialTrace(lir, trace) : "Not a trivial trace! " + trace; 57 AbstractBlockBase<?> block = trace.getBlocks()[0]; 58 59 AbstractBlockBase<?> pred = TraceUtil.getBestTraceInterPredecessor(resultTraces, block); 60 61 Value[] variableMap = new Value[lir.numVariables()]; 62 GlobalLivenessInfo livenessInfo = context.livenessInfo; 63 collectMapping(block, pred, livenessInfo, variableMap); 64 assignLocations(lir, block, livenessInfo, variableMap); 65 } 66 67 /** 68 * Collects the mapping from variable to location. Additionally the 69 * {@link GlobalLivenessInfo#setInLocations incoming location array} is set. 70 */ 71 private static void collectMapping(AbstractBlockBase<?> block, AbstractBlockBase<?> pred, GlobalLivenessInfo livenessInfo, Value[] variableMap) { 72 final int[] blockIn = livenessInfo.getBlockIn(block); 73 final Value[] predLocOut = livenessInfo.getOutLocation(pred); 74 final Value[] locationIn = new Value[blockIn.length]; 75 for (int i = 0; i < blockIn.length; i++) { 76 int varNum = blockIn[i]; 77 if (varNum >= 0) { 78 Value location = predLocOut[i]; 79 variableMap[varNum] = location; 80 locationIn[i] = location; 81 } else { 82 locationIn[i] = Value.ILLEGAL; 83 } 84 } 85 livenessInfo.setInLocations(block, locationIn); 86 } 87 88 /** 89 * Assigns the outgoing locations according to the {@link #collectMapping variable mapping}. 90 */ 91 private static void assignLocations(LIR lir, AbstractBlockBase<?> block, GlobalLivenessInfo livenessInfo, Value[] variableMap) { 92 final int[] blockOut = livenessInfo.getBlockOut(block); 93 final Value[] locationOut = new Value[blockOut.length]; 94 for (int i = 0; i < blockOut.length; i++) { 95 int varNum = blockOut[i]; 96 locationOut[i] = variableMap[varNum]; 97 } 98 livenessInfo.setOutLocations(block, locationOut); 99 100 // handle outgoing phi values 101 ValueProcedure outputConsumer = new ValueProcedure() { 102 @Override 103 public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { 104 if (isVariable(value)) { 105 return variableMap[asVariable(value).index]; 106 } 107 return value; 108 } 109 }; 110 111 JumpOp jump = SSAUtil.phiOut(lir, block); 112 // Jumps have only alive values (outgoing phi values) 113 jump.forEachAlive(outputConsumer); 114 } 115 116 }