AMD64HotSpotAddressLowering.java revision 12651:6ef01bd40ce2
1130803Smarcel/* 2130803Smarcel * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3130803Smarcel * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4130803Smarcel * 5130803Smarcel * This code is free software; you can redistribute it and/or modify it 6130803Smarcel * under the terms of the GNU General Public License version 2 only, as 7130803Smarcel * published by the Free Software Foundation. 8130803Smarcel * 9130803Smarcel * This code is distributed in the hope that it will be useful, but WITHOUT 10130803Smarcel * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11130803Smarcel * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12130803Smarcel * version 2 for more details (a copy is included in the LICENSE file that 13130803Smarcel * accompanied this code). 14130803Smarcel * 15130803Smarcel * You should have received a copy of the GNU General Public License version 16130803Smarcel * 2 along with this work; if not, write to the Free Software Foundation, 17130803Smarcel * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18130803Smarcel * 19130803Smarcel * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20130803Smarcel * or visit www.oracle.com if you need additional information or have any 21130803Smarcel * questions. 22130803Smarcel */ 23130803Smarcel 24130803Smarcelpackage org.graalvm.compiler.hotspot.amd64; 25130803Smarcel 26130803Smarcelimport static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; 27130803Smarcelimport static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; 28130803Smarcelimport static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; 29130803Smarcel 30130803Smarcelimport org.graalvm.compiler.asm.NumUtil; 31130803Smarcelimport org.graalvm.compiler.asm.amd64.AMD64Address.Scale; 32130803Smarcelimport org.graalvm.compiler.core.amd64.AMD64AddressLowering; 33130803Smarcelimport org.graalvm.compiler.core.amd64.AMD64AddressNode; 34130803Smarcelimport org.graalvm.compiler.core.common.LIRKind; 35130803Smarcelimport org.graalvm.compiler.core.common.type.ObjectStamp; 36130803Smarcelimport org.graalvm.compiler.core.common.type.StampFactory; 37130803Smarcelimport org.graalvm.compiler.graph.NodeClass; 38130803Smarcelimport org.graalvm.compiler.hotspot.CompressEncoding; 39130803Smarcelimport org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 40130803Smarcelimport org.graalvm.compiler.hotspot.nodes.CompressionNode; 41130803Smarcelimport org.graalvm.compiler.hotspot.nodes.CompressionNode.CompressionOp; 42130803Smarcelimport org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; 43130803Smarcelimport org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp; 44130803Smarcelimport org.graalvm.compiler.nodeinfo.NodeInfo; 45130803Smarcelimport org.graalvm.compiler.nodes.ValueNode; 46130803Smarcelimport org.graalvm.compiler.nodes.calc.FloatingNode; 47130803Smarcelimport org.graalvm.compiler.nodes.spi.LIRLowerable; 48130803Smarcelimport org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; 49130803Smarcel 50130803Smarcelimport jdk.vm.ci.code.Register; 51130803Smarcelimport jdk.vm.ci.meta.JavaKind; 52130803Smarcel 53130803Smarcelpublic class AMD64HotSpotAddressLowering extends AMD64AddressLowering { 54130803Smarcel 55130803Smarcel private final long heapBase; 56130803Smarcel private final Register heapBaseRegister; 57130803Smarcel private final GraalHotSpotVMConfig config; 58130803Smarcel 59130803Smarcel @NodeInfo(cycles = CYCLES_0, size = SIZE_0) 60130803Smarcel public static class HeapBaseNode extends FloatingNode implements LIRLowerable { 61130803Smarcel 62130803Smarcel public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class); 63130803Smarcel 64130803Smarcel private final Register heapBaseRegister; 65130803Smarcel 66130803Smarcel public HeapBaseNode(Register heapBaseRegister) { 67130803Smarcel super(TYPE, StampFactory.pointer()); 68130803Smarcel this.heapBaseRegister = heapBaseRegister; 69130803Smarcel } 70130803Smarcel 71130803Smarcel @Override 72130803Smarcel public void generate(NodeLIRBuilderTool generator) { 73130803Smarcel LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp()); 74130803Smarcel generator.setResult(this, heapBaseRegister.asValue(kind)); 75130803Smarcel } 76130803Smarcel } 77130803Smarcel 78130803Smarcel public AMD64HotSpotAddressLowering(GraalHotSpotVMConfig config, Register heapBaseRegister) { 79130803Smarcel this.heapBase = config.getOopEncoding().base; 80130803Smarcel this.config = config; 81130803Smarcel if (heapBase == 0 && !GeneratePIC.getValue()) { 82130803Smarcel this.heapBaseRegister = null; 83130803Smarcel } else { 84130803Smarcel this.heapBaseRegister = heapBaseRegister; 85130803Smarcel } 86130803Smarcel } 87130803Smarcel 88130803Smarcel @Override 89130803Smarcel protected boolean improve(AMD64AddressNode addr) { 90130803Smarcel if (addr.getScale() == Scale.Times1) { 91130803Smarcel if (addr.getBase() == null && addr.getIndex() instanceof CompressionNode) { 92130803Smarcel if (improveUncompression(addr, (CompressionNode) addr.getIndex())) { 93130803Smarcel return true; 94130803Smarcel } 95130803Smarcel } 96130803Smarcel 97130803Smarcel if (addr.getIndex() == null && addr.getBase() instanceof CompressionNode) { 98130803Smarcel if (improveUncompression(addr, (CompressionNode) addr.getBase())) { 99130803Smarcel return true; 100130803Smarcel } 101130803Smarcel } 102130803Smarcel } 103130803Smarcel 104130803Smarcel return super.improve(addr); 105130803Smarcel } 106130803Smarcel 107130803Smarcel private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression) { 108130803Smarcel if (compression.getOp() == CompressionOp.Uncompress) { 109130803Smarcel CompressEncoding encoding = compression.getEncoding(); 110130803Smarcel Scale scale = Scale.fromShift(encoding.shift); 111130803Smarcel if (scale == null) { 112130803Smarcel return false; 113130803Smarcel } 114130803Smarcel 115130803Smarcel if (heapBaseRegister != null && encoding.base == heapBase) { 116130803Smarcel if (!GeneratePIC.getValue() || compression.stamp() instanceof ObjectStamp) { 117130803Smarcel // With PIC it is only legal to do for oops since the base value may be 118130803Smarcel // different at runtime. 119130803Smarcel ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister)); 120130803Smarcel addr.setBase(base); 121130803Smarcel } else { 122130803Smarcel return false; 123130803Smarcel } 124130803Smarcel } else if (encoding.base != 0 || (GeneratePIC.getValue() && compression.stamp() instanceof KlassPointerStamp)) { 125130803Smarcel if (GeneratePIC.getValue()) { 126130803Smarcel ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long)); 127130803Smarcel addr.setBase(base); 128130803Smarcel } else { 129130803Smarcel long disp = addr.getDisplacement() + encoding.base; 130130803Smarcel if (NumUtil.isInt(disp)) { 131130803Smarcel addr.setDisplacement((int) disp); 132130803Smarcel addr.setBase(null); 133130803Smarcel } else { 134130803Smarcel return false; 135130803Smarcel } 136130803Smarcel } 137130803Smarcel } else { 138130803Smarcel addr.setBase(null); 139130803Smarcel } 140130803Smarcel 141130803Smarcel addr.setScale(scale); 142130803Smarcel addr.setIndex(compression.getValue()); 143130803Smarcel return true; 144130803Smarcel } else { 145130803Smarcel return false; 146130803Smarcel } 147130803Smarcel } 148130803Smarcel} 149130803Smarcel