1 /*
2  * Copyright (c) 2014, 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 package org.openjdk.bench.vm.compiler;
24 
25 import org.openjdk.jmh.annotations.Benchmark;
26 import org.openjdk.jmh.annotations.BenchmarkMode;
27 import org.openjdk.jmh.annotations.Mode;
28 import org.openjdk.jmh.annotations.OutputTimeUnit;
29 import org.openjdk.jmh.annotations.Scope;
30 import org.openjdk.jmh.annotations.Setup;
31 import org.openjdk.jmh.annotations.State;
32 
33 import java.util.Random;
34 import java.util.concurrent.TimeUnit;
35 
36 /**
37  * Various small benchmarks testing how well the optimizer straightens code.
38  */
39 @BenchmarkMode(Mode.AverageTime)
40 @OutputTimeUnit(TimeUnit.NANOSECONDS)
41 @State(Scope.Thread)
42 public class Straighten {
43 
44     private int[] intArr;
45     private long[] longArr;
46 
47     @Setup
setupSubclass()48     public void setupSubclass() {
49         int TEST_SIZE = 300;
50 
51         Random r = new Random(453543);
52 
53         /*
54          * initialize arrays with some values between 0 and 7.
55          */
56         intArr = new int[TEST_SIZE];
57         for (int i = 0; i < TEST_SIZE; i++) {
58             intArr[i] = r.nextInt(8);
59         }
60 
61         longArr = new long[TEST_SIZE];
62         for (int i = 0; i < TEST_SIZE; i++) {
63             longArr[i] = (long) r.nextInt(8);
64         }
65 
66     }
67 
innerCandidate1int(int i)68     private int innerCandidate1int(int i) {
69         int j = 0;
70 
71         if (i == 5) {
72             /* we know that i isn't 4 and is less than 7 here. */
73             j++;
74         }
75         if (i == 4) {
76             /* we know that i is less than 7 here. */
77             j += 2;
78         }
79         if (i < 7) {
80             /* we know that i is less than 7, so it isn't greater than 7. */
81             j += 4;
82         }
83         if (i > 7) {
84             j += 8;
85         }
86         return j;
87     }
88 
89     /** Tests how well serial constant integer compares are straightened. */
90     @Benchmark
testStraighten1int()91     public int testStraighten1int() throws Exception {
92         int dummy = 0;
93         int[] arr = intArr;
94         for (int i : arr) {
95             dummy += innerCandidate1int(i);
96         }
97         return dummy;
98     }
99 
innerCandidate1long(long l)100     private long innerCandidate1long(long l) {
101         long j = 0;
102 
103         if (l == 5) {
104             /* we know that l isn't 4 and is less than 7 here. */
105             j++;
106         }
107         if (l == 4) {
108             /* we know that l is less than 7 here. */
109             j += 2;
110         }
111         if (l < 7) {
112             /* we know that l is less than 7, so it isn't greater than 7. */
113             j += 4;
114         }
115         if (l > 7) {
116             j += 8;
117         }
118         return j;
119     }
120 
121     /** Tests how well serial constant long compares are straightened. */
122     @Benchmark
testStraighten1long()123     public int testStraighten1long() throws Exception {
124         int dummy = 0;
125         long[] arr = longArr;
126         for (long l : arr) {
127             dummy += innerCandidate1long(l);
128         }
129         return dummy;
130     }
131 
innerCandidate2int(int i)132     private int innerCandidate2int(int i) {
133         int j;
134 
135         if (i < 5) {
136             /* j becomes 3, so it should be straightened to j == 3 case below. */
137             j = 3;
138         } else {
139             /* j becomes 4, so it should be straightened to j == 4 case below. */
140             j = 4;
141         }
142 
143         if (j == 4) {
144             i += 2;
145         }
146         if (j == 3) {
147             i += 4;
148         }
149         return i;
150     }
151 
152     /** Tests how well constant integer definitions are straightened. */
153     @Benchmark
testStraighten2int()154     public int testStraighten2int() throws Exception {
155         int[] arr = intArr;
156         int dummy = 0;
157         for (int i : arr) {
158             dummy += innerCandidate2int(i);
159         }
160         return dummy;
161     }
162 
innerCandidate2long(long l)163     private long innerCandidate2long(long l) {
164         long j;
165 
166         if (l < 5) {
167             /* j becomes 3, so it should be straightened to j == 3 case below. */
168             j = 3;
169         } else {
170             /* j becomes 4, so it should be straightened to j == 4 case below. */
171             j = 4;
172         }
173 
174         if (j == 4) {
175             l += 2;
176         }
177         if (j == 3) {
178             l += 4;
179         }
180         return l;
181     }
182 
183     /** Tests how well constant long definitions are straightened. */
184     @Benchmark
testStraighten2long()185     public int testStraighten2long() throws Exception {
186         int dummy = 0;
187         long[] arr = longArr;
188         for (long l : arr) {
189             dummy += innerCandidate2long(l);
190         }
191         return dummy;
192     }
193 
innerCandidate3int(int i, int j)194     private int innerCandidate3int(int i, int j) {
195         int k = 0;
196 
197         if (i == j) {
198             k++;
199         }
200         if (i != j) {
201             k += 2;
202         }
203         if (i < j) {
204             k += 4;
205         }
206         return k;
207     }
208 
209     /**
210      * Tests how well variable integer compares are straightened.
211      */
212     @Benchmark
testStraighten3int()213     public int testStraighten3int() throws Exception {
214         int dummy = 0;
215         int[] arr = intArr;
216         for (int i = 0; i < arr.length - 1; i++) {
217             dummy += innerCandidate3int(arr[i], arr[i + 1]);
218         }
219         return dummy;
220     }
221 
innerCandidate3long(long i, long j)222     private long innerCandidate3long(long i, long j) {
223         long k = 0;
224 
225         if (i == j) {
226             k++;
227         }
228         if (i != j) {
229             k += 2;
230         }
231         if (i < j) {
232             k += 4;
233         }
234         return k;
235     }
236 
237     /** Tests how well variable long compares are straightened. */
238     @Benchmark
testStraighten3long()239     public int testStraighten3long() throws Exception {
240         int dummy = 0;
241         long[] arr = longArr;
242         for (int i = 0; i < arr.length - 1; i++) {
243             dummy += innerCandidate3long(arr[i], arr[i + 1]);
244         }
245         return dummy;
246     }
247 
248 }
249