1/*
2 * Copyright (c) 2015, 2015, 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.microbenchmarks.graal;
24
25import java.util.HashMap;
26
27import org.openjdk.jmh.annotations.Benchmark;
28import org.openjdk.jmh.annotations.Warmup;
29import org.openjdk.jmh.infra.Blackhole;
30
31import org.graalvm.compiler.graph.Node;
32import org.graalvm.compiler.graph.NodeBitMap;
33import org.graalvm.compiler.microbenchmarks.graal.util.GraalState;
34import org.graalvm.compiler.microbenchmarks.graal.util.MethodSpec;
35import org.graalvm.compiler.microbenchmarks.graal.util.NodesState;
36import org.graalvm.compiler.microbenchmarks.graal.util.NodesState.NodePair;
37import org.graalvm.compiler.nodes.ConstantNode;
38import org.graalvm.compiler.nodes.calc.AddNode;
39import org.graalvm.compiler.nodes.util.GraphUtil;
40
41public class NodeBenchmark extends GraalBenchmark {
42
43    @MethodSpec(declaringClass = String.class, name = "equals")
44    public static class StringEquals extends NodesState {
45    }
46
47    @Benchmark
48    @Warmup(iterations = 20)
49    public int getNodeClass(StringEquals s) {
50        int sum = 0;
51        for (Node n : s.nodes) {
52            sum += n.getNodeClass().iterableId();
53        }
54        return sum;
55    }
56
57    @Benchmark
58    public void dataEquals(StringEquals s, Blackhole bh) {
59        for (Node n : s.nodes) {
60            bh.consume(n.getNodeClass().dataEquals(n, n));
61        }
62    }
63
64    @Benchmark
65    public void replaceFirstInput(StringEquals s, Blackhole bh) {
66        for (Node n : s.nodes) {
67            bh.consume(n.getNodeClass().replaceFirstInput(n, n, n));
68        }
69    }
70
71    @Benchmark
72    public void inputsEquals(StringEquals s, Blackhole bh) {
73        for (Node n : s.nodes) {
74            bh.consume(n.getNodeClass().equalInputs(n, n));
75        }
76    }
77
78    @Benchmark
79    public void inputs(StringEquals s, Blackhole bh) {
80        for (Node n : s.nodes) {
81            for (Node input : n.inputs()) {
82                bh.consume(input);
83            }
84        }
85    }
86
87    @Benchmark
88    public void acceptInputs(StringEquals s, Blackhole bh) {
89        Node.EdgeVisitor consumer = new Node.EdgeVisitor() {
90            @Override
91            public Node apply(Node t, Node u) {
92                bh.consume(u);
93                return u;
94            }
95        };
96        for (Node n : s.nodes) {
97            n.applyInputs(consumer);
98        }
99    }
100
101    @Benchmark
102    public void createAndDeleteAdd(StringEquals s, Blackhole bh) {
103        AddNode addNode = new AddNode(ConstantNode.forInt(40), ConstantNode.forInt(2));
104        s.graph.addOrUniqueWithInputs(addNode);
105        GraphUtil.killWithUnusedFloatingInputs(addNode);
106        bh.consume(addNode);
107    }
108
109    @Benchmark
110    public void createAndDeleteConstant(StringEquals s, Blackhole bh) {
111        ConstantNode constantNode = ConstantNode.forInt(42);
112        s.graph.addOrUnique(constantNode);
113        GraphUtil.killWithUnusedFloatingInputs(constantNode);
114        bh.consume(constantNode);
115    }
116
117    @Benchmark
118    public void usages(StringEquals s, Blackhole bh) {
119        for (Node n : s.nodes) {
120            for (Node input : n.usages()) {
121                bh.consume(input);
122            }
123        }
124    }
125
126    @Benchmark
127    @Warmup(iterations = 20)
128    public void nodeBitmap(StringEquals s, @SuppressWarnings("unused") GraalState g) {
129        NodeBitMap bitMap = s.graph.createNodeBitMap();
130        for (Node node : s.graph.getNodes()) {
131            if (!bitMap.isMarked(node)) {
132                bitMap.mark(node);
133            }
134        }
135        for (Node node : s.graph.getNodes()) {
136            if (bitMap.isMarked(node)) {
137                bitMap.clear(node);
138            }
139        }
140    }
141
142    @MethodSpec(declaringClass = HashMap.class, name = "computeIfAbsent")
143    public static class HashMapComputeIfAbsent extends NodesState {
144    }
145
146    // Checkstyle: stop method name check
147    @Benchmark
148    @Warmup(iterations = 20)
149    public int valueEquals_STRING_EQUALS(StringEquals s) {
150        int result = 0;
151        for (NodePair np : s.valueEqualsNodePairs) {
152            if (np.n1.valueEquals(np.n2)) {
153                result += 27;
154            } else {
155                result += 31;
156            }
157        }
158        return result;
159    }
160
161    @Benchmark
162    @Warmup(iterations = 20)
163    public int valueEquals_HASHMAP_COMPUTE_IF_ABSENT(HashMapComputeIfAbsent s) {
164        int result = 0;
165        for (NodePair np : s.valueEqualsNodePairs) {
166            if (np.n1.valueEquals(np.n2)) {
167                result += 27;
168            } else {
169                result += 31;
170            }
171        }
172        return result;
173    }
174
175    @Benchmark
176    @Warmup(iterations = 20)
177    public int valueNumberLeaf_HASHMAP_COMPUTE_IF_ABSENT(HashMapComputeIfAbsent s) {
178        int result = 0;
179        for (Node n : s.valueNumberableLeafNodes) {
180            result += (n.getNodeClass().isLeafNode() ? 1 : 0);
181        }
182        return result;
183    }
184
185    @Benchmark
186    @Warmup(iterations = 20)
187    public int valueNumberLeaf_STRING_EQUALS(StringEquals s) {
188        int result = 0;
189        for (Node n : s.valueNumberableLeafNodes) {
190            result += (n.getNodeClass().isLeafNode() ? 1 : 0);
191        }
192        return result;
193    }
194    // Checkstyle: resume method name check
195}
196