1 /*
2  * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
3  * Copyright (c) 2017, Red Hat Inc. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  */
24 
25 
26 package org.graalvm.compiler.phases.common;
27 
28 import org.graalvm.compiler.core.common.type.Stamp;
29 import org.graalvm.compiler.core.common.type.StampFactory;
30 import org.graalvm.compiler.graph.Node;
31 import org.graalvm.compiler.nodes.NodeView;
32 import org.graalvm.compiler.nodes.PrefetchAllocateNode;
33 import org.graalvm.compiler.nodes.StructuredGraph;
34 import org.graalvm.compiler.nodes.ValueNode;
35 import org.graalvm.compiler.nodes.extended.JavaReadNode;
36 import org.graalvm.compiler.nodes.memory.AbstractWriteNode;
37 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
38 import org.graalvm.compiler.nodes.memory.ReadNode;
39 import org.graalvm.compiler.nodes.memory.address.AddressNode;
40 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
41 import org.graalvm.compiler.nodes.util.GraphUtil;
42 import org.graalvm.compiler.phases.Phase;
43 
44 import jdk.vm.ci.meta.JavaKind;
45 
46 /**
47  * Created by adinn on 09/05/17.
48  */
49 public class AddressLoweringByUsePhase extends Phase {
50     public abstract static class AddressLoweringByUse {
51 
lower(ValueNode use, Stamp stamp, AddressNode address)52         public abstract AddressNode lower(ValueNode use, Stamp stamp, AddressNode address);
53 
lower(AddressNode address)54         public abstract AddressNode lower(AddressNode address);
55     }
56 
57     private final AddressLoweringByUse lowering;
58 
AddressLoweringByUsePhase(AddressLoweringByUse lowering)59     public AddressLoweringByUsePhase(AddressLoweringByUse lowering) {
60         this.lowering = lowering;
61         assert lowering != null;
62     }
63 
64     @Override
run(StructuredGraph graph)65     protected void run(StructuredGraph graph) {
66         // first replace address nodes hanging off known usages
67         for (Node node : graph.getNodes()) {
68             AddressNode address;
69             AddressNode lowered;
70             if (node instanceof ReadNode) {
71                 ReadNode readNode = (ReadNode) node;
72                 Stamp stamp = readNode.getAccessStamp(NodeView.DEFAULT);
73                 address = readNode.getAddress();
74                 lowered = lowering.lower(readNode, stamp, address);
75             } else if (node instanceof JavaReadNode) {
76                 JavaReadNode javaReadNode = (JavaReadNode) node;
77                 Stamp stamp = javaReadNode.stamp(NodeView.DEFAULT);
78                 address = javaReadNode.getAddress();
79                 lowered = lowering.lower(javaReadNode, stamp, address);
80             } else if (node instanceof FloatingReadNode) {
81                 FloatingReadNode floatingReadNode = (FloatingReadNode) node;
82                 Stamp stamp = floatingReadNode.getAccessStamp(NodeView.DEFAULT);
83                 address = floatingReadNode.getAddress();
84                 lowered = lowering.lower(floatingReadNode, stamp, address);
85             } else if (node instanceof AbstractWriteNode) {
86                 AbstractWriteNode abstractWriteNode = (AbstractWriteNode) node;
87                 Stamp stamp = abstractWriteNode.value().stamp(NodeView.DEFAULT);
88                 address = abstractWriteNode.getAddress();
89                 lowered = lowering.lower(abstractWriteNode, stamp, address);
90             } else if (node instanceof PrefetchAllocateNode) {
91                 PrefetchAllocateNode prefetchAllocateNode = (PrefetchAllocateNode) node;
92                 Stamp stamp = StampFactory.forKind(JavaKind.Object);
93                 address = (AddressNode) prefetchAllocateNode.inputs().first();
94                 lowered = lowering.lower(prefetchAllocateNode, stamp, address);
95             } else {
96                 continue;
97             }
98             // the lowered address may already be a replacement
99             // in which case we want to use it not delete it!
100             if (lowered != address) {
101                 // replace original with lowered at this usage only
102                 // n.b. lowered is added unique so repeat lowerings will elide
103                 node.replaceFirstInput(address, lowered);
104                 // if that was the last reference we can kill the old (dead) node
105                 if (address.hasNoUsages()) {
106                     GraphUtil.killWithUnusedFloatingInputs(address);
107                 }
108             }
109         }
110 
111         // now replace any remaining unlowered address nodes
112         for (Node node : graph.getNodes()) {
113             AddressNode lowered;
114             if (node instanceof OffsetAddressNode) {
115                 AddressNode address = (AddressNode) node;
116                 lowered = lowering.lower(address);
117             } else {
118                 continue;
119             }
120             // will always be a new AddresNode
121             node.replaceAtUsages(lowered);
122             GraphUtil.killWithUnusedFloatingInputs(node);
123         }
124     }
125 }
126