1/*
2 * Copyright (c) 2015, 2016, 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 */
23package org.graalvm.compiler.hotspot.replacements.arraycopy;
24
25import jdk.vm.ci.meta.JavaKind;
26
27import static org.graalvm.word.LocationIdentity.any;
28
29import org.graalvm.compiler.core.common.type.StampFactory;
30import org.graalvm.compiler.graph.NodeClass;
31import org.graalvm.compiler.nodeinfo.InputType;
32import org.graalvm.compiler.nodeinfo.NodeInfo;
33import org.graalvm.compiler.nodes.NamedLocationIdentity;
34import org.graalvm.compiler.nodes.ValueNode;
35import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
36import org.graalvm.compiler.nodes.memory.MemoryAccess;
37import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
38import org.graalvm.compiler.nodes.memory.MemoryNode;
39import org.graalvm.compiler.nodes.spi.Lowerable;
40import org.graalvm.compiler.nodes.spi.LoweringTool;
41import org.graalvm.word.LocationIdentity;
42
43@NodeInfo(allowedUsageTypes = InputType.Memory)
44public class ArrayCopyUnrollNode extends ArrayRangeWriteNode implements MemoryCheckpoint.Single, Lowerable, MemoryAccess {
45
46    public static final NodeClass<ArrayCopyUnrollNode> TYPE = NodeClass.create(ArrayCopyUnrollNode.class);
47
48    @Input protected ValueNode src;
49    @Input protected ValueNode srcPos;
50    @Input protected ValueNode dest;
51    @Input protected ValueNode destPos;
52    @Input protected ValueNode length;
53
54    private JavaKind elementKind;
55
56    private int unrolledLength;
57
58    @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess;
59
60    public ArrayCopyUnrollNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, int unrolledLength, JavaKind elementKind) {
61        super(TYPE, StampFactory.forKind(JavaKind.Void));
62        this.src = src;
63        this.srcPos = srcPos;
64        this.dest = dest;
65        this.destPos = destPos;
66        this.length = length;
67        this.unrolledLength = unrolledLength;
68        assert elementKind != null && elementKind != JavaKind.Illegal;
69        this.elementKind = elementKind;
70    }
71
72    public ValueNode getSource() {
73        return src;
74    }
75
76    public ValueNode getSourcePosition() {
77        return srcPos;
78    }
79
80    public ValueNode getDestination() {
81        return dest;
82    }
83
84    public ValueNode getDestinationPosition() {
85        return destPos;
86    }
87
88    @Override
89    public ValueNode getLength() {
90        return length;
91    }
92
93    @Override
94    public ValueNode getArray() {
95        return dest;
96    }
97
98    @Override
99    public ValueNode getIndex() {
100        return destPos;
101    }
102
103    @Override
104    public boolean isObjectArray() {
105        return elementKind == JavaKind.Object;
106    }
107
108    @Override
109    public boolean isInitialization() {
110        return false;
111    }
112
113    @NodeIntrinsic
114    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantNodeParameter int unrolledLength,
115                    @ConstantNodeParameter JavaKind elementKind);
116
117    public int getUnrollLength() {
118        return unrolledLength;
119    }
120
121    public JavaKind getElementKind() {
122        return elementKind;
123    }
124
125    @Override
126    public LocationIdentity getLocationIdentity() {
127        if (elementKind != null) {
128            return NamedLocationIdentity.getArrayLocation(elementKind);
129        }
130        return any();
131    }
132
133    @Override
134    public void lower(LoweringTool tool) {
135        tool.getLowerer().lower(this, tool);
136    }
137
138    @Override
139    public MemoryNode getLastLocationAccess() {
140        return lastLocationAccess;
141    }
142
143    @Override
144    public void setLastLocationAccess(MemoryNode lla) {
145        updateUsagesInterface(lastLocationAccess, lla);
146        lastLocationAccess = lla;
147    }
148}
149