001/* 002 * Copyright (c) 2014, 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.stackslotalloc; 024 025import static jdk.internal.jvmci.code.ValueUtil.*; 026 027import java.util.*; 028 029import jdk.internal.jvmci.code.*; 030import jdk.internal.jvmci.common.*; 031import com.oracle.graal.debug.*; 032import com.oracle.graal.debug.Debug.*; 033 034import com.oracle.graal.compiler.common.alloc.*; 035import com.oracle.graal.compiler.common.cfg.*; 036import com.oracle.graal.lir.*; 037import com.oracle.graal.lir.framemap.*; 038import com.oracle.graal.lir.gen.*; 039import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory; 040import com.oracle.graal.lir.phases.*; 041 042public class SimpleStackSlotAllocator extends AllocationPhase implements StackSlotAllocator { 043 044 @Override 045 protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory, 046 RegisterAllocationConfig registerAllocationConfig) { 047 lirGenRes.buildFrameMap(this); 048 } 049 050 public void allocateStackSlots(FrameMapBuilderTool builder, LIRGenerationResult res) { 051 StackSlot[] mapping = new StackSlot[builder.getNumberOfStackSlots()]; 052 long currentFrameSize = allocatedFramesize.isEnabled() ? builder.getFrameMap().currentFrameSize() : 0; 053 for (VirtualStackSlot virtualSlot : builder.getStackSlots()) { 054 final StackSlot slot; 055 if (virtualSlot instanceof SimpleVirtualStackSlot) { 056 slot = mapSimpleVirtualStackSlot(builder, (SimpleVirtualStackSlot) virtualSlot); 057 virtualFramesize.add(builder.getFrameMap().spillSlotSize(virtualSlot.getLIRKind())); 058 } else if (virtualSlot instanceof VirtualStackSlotRange) { 059 VirtualStackSlotRange slotRange = (VirtualStackSlotRange) virtualSlot; 060 slot = mapVirtualStackSlotRange(builder, slotRange); 061 virtualFramesize.add(builder.getFrameMap().spillSlotRangeSize(slotRange.getSlots())); 062 } else { 063 throw JVMCIError.shouldNotReachHere("Unknown VirtualStackSlot: " + virtualSlot); 064 } 065 allocatedSlots.increment(); 066 mapping[virtualSlot.getId()] = slot; 067 } 068 updateLIR(res, mapping); 069 if (allocatedFramesize.isEnabled()) { 070 allocatedFramesize.add(builder.getFrameMap().currentFrameSize() - currentFrameSize); 071 } 072 } 073 074 protected void updateLIR(LIRGenerationResult res, StackSlot[] mapping) { 075 try (Scope scope = Debug.scope("StackSlotMappingLIR")) { 076 ValueProcedure updateProc = (value, mode, flags) -> { 077 if (isVirtualStackSlot(value)) { 078 StackSlot stackSlot = mapping[asVirtualStackSlot(value).getId()]; 079 Debug.log("map %s -> %s", value, stackSlot); 080 return stackSlot; 081 } 082 return value; 083 }; 084 for (AbstractBlockBase<?> block : res.getLIR().getControlFlowGraph().getBlocks()) { 085 try (Indent indent0 = Debug.logAndIndent("block: %s", block)) { 086 for (LIRInstruction inst : res.getLIR().getLIRforBlock(block)) { 087 try (Indent indent1 = Debug.logAndIndent("Inst: %d: %s", inst.id(), inst)) { 088 inst.forEachAlive(updateProc); 089 inst.forEachInput(updateProc); 090 inst.forEachOutput(updateProc); 091 inst.forEachTemp(updateProc); 092 inst.forEachState(updateProc); 093 } 094 } 095 } 096 } 097 } 098 } 099 100 protected StackSlot mapSimpleVirtualStackSlot(FrameMapBuilderTool builder, SimpleVirtualStackSlot virtualStackSlot) { 101 return builder.getFrameMap().allocateSpillSlot(virtualStackSlot.getLIRKind()); 102 } 103 104 protected StackSlot mapVirtualStackSlotRange(FrameMapBuilderTool builder, VirtualStackSlotRange virtualStackSlot) { 105 return builder.getFrameMap().allocateStackSlots(virtualStackSlot.getSlots(), virtualStackSlot.getObjects()); 106 } 107}