1 /*
2  * Copyright (c) 2017, 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 
24 
25 
26 package org.graalvm.compiler.core.amd64;
27 
28 import jdk.vm.ci.code.Register;
29 import org.graalvm.compiler.asm.amd64.AMD64Address;
30 import org.graalvm.compiler.core.common.LIRKind;
31 import org.graalvm.compiler.core.common.type.StampFactory;
32 import org.graalvm.compiler.debug.CounterKey;
33 import org.graalvm.compiler.debug.DebugContext;
34 import org.graalvm.compiler.graph.NodeClass;
35 import org.graalvm.compiler.nodeinfo.NodeInfo;
36 import org.graalvm.compiler.nodes.CompressionNode;
37 import org.graalvm.compiler.nodes.NodeView;
38 import org.graalvm.compiler.nodes.StructuredGraph;
39 import org.graalvm.compiler.nodes.ValueNode;
40 import org.graalvm.compiler.nodes.calc.FloatingNode;
41 import org.graalvm.compiler.nodes.spi.LIRLowerable;
42 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
43 
44 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
45 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
46 
47 public abstract class AMD64CompressAddressLowering extends AMD64AddressLowering {
48     private static final CounterKey counterFoldedUncompressDuringAddressLowering = DebugContext.counter("FoldedUncompressDuringAddressLowering");
49 
50     @Override
improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated)51     protected final boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
52         if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
53             return true;
54         }
55 
56         if (!isBaseNegated && !isIndexNegated && addr.getScale() == AMD64Address.Scale.Times1) {
57             ValueNode base = addr.getBase();
58             ValueNode index = addr.getIndex();
59 
60             if (tryToImproveUncompression(addr, index, base) || tryToImproveUncompression(addr, base, index)) {
61                 counterFoldedUncompressDuringAddressLowering.increment(debug);
62                 return true;
63             }
64         }
65 
66         return false;
67     }
68 
tryToImproveUncompression(AMD64AddressNode addr, ValueNode value, ValueNode other)69     private boolean tryToImproveUncompression(AMD64AddressNode addr, ValueNode value, ValueNode other) {
70         if (value instanceof CompressionNode) {
71             CompressionNode compression = (CompressionNode) value;
72             if (compression.getOp() == CompressionNode.CompressionOp.Uncompress && improveUncompression(addr, compression, other)) {
73                 return true;
74             }
75         }
76 
77         return false;
78     }
79 
improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other)80     protected abstract boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other);
81 
82     @NodeInfo(cycles = CYCLES_0, size = SIZE_0)
83     public static class HeapBaseNode extends FloatingNode implements LIRLowerable {
84 
85         public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class);
86 
87         private final Register heapBaseRegister;
88 
HeapBaseNode(Register heapBaseRegister)89         public HeapBaseNode(Register heapBaseRegister) {
90             super(TYPE, StampFactory.pointer());
91             this.heapBaseRegister = heapBaseRegister;
92         }
93 
94         @Override
generate(NodeLIRBuilderTool generator)95         public void generate(NodeLIRBuilderTool generator) {
96             LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
97             generator.setResult(this, heapBaseRegister.asValue(kind));
98         }
99     }
100 }
101