1 /*
2  * Copyright (c) 2016, 2018, 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 package org.graalvm.compiler.nodeinfo;
26 
27 /**
28  * Constants representing an estimation of of the size needed to represent a compiler node in
29  * machine code.
30  */
31 public enum NodeSize {
32 
33     /**
34      * The default value of the {@link NodeInfo#size()} property.
35      * <p>
36      * For further information about the use of {@code SIZE_UNSET} see {@link NodeInfo#size()}.
37      */
38     SIZE_UNSET(0),
39     /**
40      * Nodes for which, due to arbitrary reasons, no estimation can be made either (1) statically
41      * without inspecting the properties of a node or (2) at all (like e.g. for an invocation).
42      * <p>
43      * Nodes annotated with {@code SIZE_UNKNOWN} should specify the {@link NodeInfo#sizeRationale()}
44      * property to clarify why an estimation cannot be done.
45      */
46     SIZE_UNKNOWN(0),
47     /**
48      * Nodes for which code size information is irrelevant and can be ignored, e.g. for test nodes.
49      */
50     SIZE_IGNORED(0),
51     /**
52      * Nodes that do not require any code to be generated in order to be "executed", e.g. a pinode
53      * node.
54      */
55     SIZE_0(0),
56     SIZE_1(1),
57     SIZE_2(2),
58     SIZE_4(4),
59     SIZE_8(8),
60     SIZE_16(16),
61     SIZE_32(32),
62     SIZE_64(64),
63     SIZE_128(128),
64     SIZE_256(256),
65     SIZE_512(512),
66     SIZE_1024(1024);
67 
68     private static final NodeSize[] VALUES = values();
69 
70     public final int value;
71 
NodeSize(int value)72     NodeSize(int value) {
73         this.value = value;
74     }
75 
76     public static final int IGNORE_SIZE_CONTRACT_FACTOR = 0xFFFF;
77 
compute(NodeSize base, int opCount)78     public static NodeSize compute(NodeSize base, int opCount) {
79         assert opCount >= 0;
80         if (opCount == 0) {
81             return SIZE_0;
82         }
83         assert base.ordinal() > SIZE_0.ordinal();
84         int log2 = log2(base.value * opCount);
85         for (int i = base.ordinal(); i < VALUES.length; i++) {
86             if (log2(VALUES[i].value) == log2) {
87                 return VALUES[i];
88             }
89         }
90         return SIZE_1024;
91     }
92 
compute(int rawValue)93     public static NodeSize compute(int rawValue) {
94         assert rawValue >= 0;
95         if (rawValue == 0) {
96             return SIZE_0;
97         }
98         assert rawValue > 0;
99         for (int i = SIZE_0.ordinal(); i < VALUES.length - 1; i++) {
100             if (VALUES[i].value >= rawValue && rawValue <= VALUES[i + 1].value) {
101                 int r1 = VALUES[i].value;
102                 int r2 = VALUES[i + 1].value;
103                 int diff = r2 - r1;
104                 return rawValue - r1 > diff / 2 ? VALUES[i + 1] : VALUES[i];
105             }
106         }
107         return SIZE_1024;
108     }
109 
log2(int val)110     private static int log2(int val) {
111         return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(val);
112     }
113 }
114