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