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 jdk.internal.jvmci.code.ValueUtil.*; 026 027import java.util.*; 028 029import jdk.internal.jvmci.code.*; 030import jdk.internal.jvmci.meta.*; 031 032import com.oracle.graal.compiler.common.alloc.*; 033import com.oracle.graal.compiler.common.alloc.TraceBuilder.TraceBuilderResult; 034import com.oracle.graal.compiler.common.cfg.*; 035import com.oracle.graal.debug.*; 036import com.oracle.graal.lir.*; 037import com.oracle.graal.lir.gen.*; 038import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; 039import com.oracle.graal.lir.phases.*; 040import com.oracle.graal.lir.ssa.SSAUtil.PhiValueVisitor; 041import com.oracle.graal.lir.ssi.*; 042 043public class TraceGlobalMoveResolutionPhase extends AllocationPhase { 044 045 private final TraceBuilderResult<?> resultTraces; 046 047 public TraceGlobalMoveResolutionPhase(TraceBuilderResult<?> resultTraces) { 048 this.resultTraces = resultTraces; 049 } 050 051 @Override 052 protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory, 053 RegisterAllocationConfig registerAllocationConfig) { 054 resolveGlobalDataFlow(resultTraces, lirGenRes, spillMoveFactory, target.arch); 055 } 056 057 private static <B extends AbstractBlockBase<B>> void resolveGlobalDataFlow(TraceBuilderResult<B> resultTraces, LIRGenerationResult lirGenRes, SpillMoveFactory spillMoveFactory, Architecture arch) { 058 LIR lir = lirGenRes.getLIR(); 059 /* Resolve trace global data-flow mismatch. */ 060 TraceGlobalMoveResolver moveResolver = new TraceGlobalMoveResolver(lirGenRes, spillMoveFactory, arch); 061 PhiValueVisitor visitor = (Value phiIn, Value phiOut) -> { 062 if (!isIllegal(phiIn) && !TraceGlobalMoveResolver.isMoveToSelf(phiOut, phiIn)) { 063 moveResolver.addMapping(phiOut, (AllocatableValue) phiIn); 064 } 065 }; 066 067 try (Indent indent = Debug.logAndIndent("Trace global move resolution")) { 068 for (List<B> trace : resultTraces.getTraces()) { 069 for (AbstractBlockBase<?> fromBlock : trace) { 070 for (AbstractBlockBase<?> toBlock : fromBlock.getSuccessors()) { 071 if (resultTraces.getTraceForBlock(fromBlock) != resultTraces.getTraceForBlock(toBlock)) { 072 try (Indent indent0 = Debug.logAndIndent("Handle trace edge from %s (Trace%d) to %s (Trace%d)", fromBlock, resultTraces.getTraceForBlock(fromBlock), toBlock, 073 resultTraces.getTraceForBlock(toBlock))) { 074 075 final List<LIRInstruction> instructions; 076 final int insertIdx; 077 if (fromBlock.getSuccessorCount() == 1) { 078 instructions = lir.getLIRforBlock(fromBlock); 079 insertIdx = instructions.size() - 1; 080 } else { 081 assert toBlock.getPredecessorCount() == 1; 082 instructions = lir.getLIRforBlock(toBlock); 083 insertIdx = 1; 084 } 085 086 moveResolver.setInsertPosition(instructions, insertIdx); 087 SSIUtil.forEachValuePair(lir, toBlock, fromBlock, visitor); 088 moveResolver.resolveAndAppendMoves(); 089 } 090 } 091 } 092 } 093 } 094 } 095 } 096}