001/* 002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.lir.alloc.trace; 024 025import static com.oracle.graal.lir.LIRValueUtil.*; 026import static com.oracle.graal.lir.alloc.trace.TraceRegisterAllocationPhase.*; 027 028import java.util.*; 029 030import jdk.internal.jvmci.code.*; 031import jdk.internal.jvmci.meta.*; 032 033import com.oracle.graal.compiler.common.alloc.*; 034import com.oracle.graal.compiler.common.alloc.TraceBuilder.TraceBuilderResult; 035import com.oracle.graal.compiler.common.cfg.*; 036import com.oracle.graal.lir.*; 037import com.oracle.graal.lir.StandardOp.BlockEndOp; 038import com.oracle.graal.lir.StandardOp.LabelOp; 039import com.oracle.graal.lir.gen.*; 040import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; 041import com.oracle.graal.lir.phases.*; 042import com.oracle.graal.lir.ssi.*; 043import com.oracle.graal.lir.util.*; 044 045/** 046 * Allocates a trivial trace i.e. a trace consisting of a single block with no instructions other 047 * than the {@link LabelOp} and the {@link BlockEndOp}. 048 */ 049public class TraceTrivialAllocator extends AllocationPhase { 050 051 private final TraceBuilderResult<?> resultTraces; 052 053 public TraceTrivialAllocator(TraceBuilderResult<?> resultTraces) { 054 this.resultTraces = resultTraces; 055 } 056 057 @Override 058 protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> trace, SpillMoveFactory spillMoveFactory, 059 RegisterAllocationConfig registerAllocationConfig) { 060 LIR lir = lirGenRes.getLIR(); 061 assert isTrivialTrace(lir, trace) : "Not a trivial trace! " + trace; 062 B block = trace.iterator().next(); 063 064 AbstractBlockBase<?> pred = TraceUtil.getBestTraceInterPredecessor(resultTraces, block); 065 066 VariableVirtualStackValueMap<Variable, Value> variableMap = new VariableVirtualStackValueMap<>(lir.nextVariable(), 0); 067 SSIUtil.forEachValuePair(lir, block, pred, (to, from) -> { 068 if (isVariable(to)) { 069 variableMap.put(asVariable(to), from); 070 } 071 }); 072 073 ValueProcedure outputConsumer = (value, mode, flags) -> { 074 if (isVariable(value)) { 075 return variableMap.get(asVariable(value)); 076 } 077 return value; 078 }; 079 080 List<LIRInstruction> instructions = lir.getLIRforBlock(block); 081 for (LIRInstruction op : instructions) { 082 083 op.forEachOutput(outputConsumer); 084 op.forEachTemp(outputConsumer); 085 op.forEachAlive(outputConsumer); 086 op.forEachInput(outputConsumer); 087 op.forEachState(outputConsumer); 088 } 089 } 090}