1 /* 2 * Copyright (c) 2021, 2022, 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 package compiler.lib.ir_framework; 25 26 import compiler.lib.ir_framework.driver.irmatching.IRMatcher; 27 import compiler.lib.ir_framework.shared.*; 28 import jdk.test.lib.Platform; 29 import sun.hotspot.WhiteBox; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** 35 * This class provides default regex strings that can be used in {@link IR @IR} annotations to specify IR constraints. 36 * <p> 37 * There are two types of default regexes: 38 * <ul> 39 * <li><p>Standalone regexes: Use them directly.</li> 40 * <li><p>Composite regexes: Their names contain "{@code _OF}" and expect another string in a list in 41 * {@link IR#failOn()} and {@link IR#counts()}. They cannot be use as standalone regex and will result in a 42 * {@link TestFormatException} when doing so.</li> 43 * </ul> 44 * 45 * @see IR 46 */ 47 public class IRNode { 48 private static final String START = "(\\d+(\\s){2}("; 49 private static final String MID = ".*)+(\\s){2}===.*"; 50 private static final String END = ")"; 51 private static final String COMPOSITE_PREFIX = "#PRE#"; // Prefix for regexes that require an additional user-defined string. 52 private static final String IS_REPLACED = "#IS_REPLACED#"; // Is replaced by an additional user-defined string. 53 private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; 54 private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; 55 56 public static final String ALLOC = "(.*precise .*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END; 57 public static final String ALLOC_OF = COMPOSITE_PREFIX + "(.*precise .*" + IS_REPLACED + ":.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END; 58 public static final String ALLOC_ARRAY = "(.*precise \\[.*\\R((.*(?i:mov|xor|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END; 59 public static final String ALLOC_ARRAY_OF = COMPOSITE_PREFIX + "(.*precise \\[.*" + IS_REPLACED + ":.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END; 60 61 public static final String CHECKCAST_ARRAY = "(((?i:cmp|CLFI|CLR).*precise \\[.*:|.*(?i:mov|or).*precise \\[.*:.*\\R.*(cmp|CMP|CLR))" + END; 62 public static final String CHECKCAST_ARRAY_OF = COMPOSITE_PREFIX + "(((?i:cmp|CLFI|CLR).*precise \\[.*" + IS_REPLACED + ":|.*(?i:mov|or).*precise \\[.*" + IS_REPLACED + ":.*\\R.*(cmp|CMP|CLR))" + END; 63 // Does not work on s390 (a rule containing this regex will be skipped on s390). 64 public static final String CHECKCAST_ARRAYCOPY = "(.*((?i:call_leaf_nofp,runtime)|CALL,\\s?runtime leaf nofp|BCTRL.*.leaf call).*checkcast_arraycopy.*" + END; 65 66 public static final String FIELD_ACCESS = "(.*Field: *" + END; 67 68 public static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + END; 69 public static final String STORE_B = START + "StoreB" + MID + END; // Store to boolean is also mapped to byte 70 public static final String STORE_C = START + "StoreC" + MID + END; 71 public static final String STORE_I = START + "StoreI" + MID + END; // Store to short is also mapped to int 72 public static final String STORE_L = START + "StoreL" + MID + END; 73 public static final String STORE_F = START + "StoreF" + MID + END; 74 public static final String STORE_D = START + "StoreD" + MID + END; 75 public static final String STORE_P = START + "StoreP" + MID + END; 76 public static final String STORE_N = START + "StoreN" + MID + END; 77 public static final String STORE_VECTOR = START + "StoreVector" + MID + END; 78 public static final String STORE_OF_CLASS = COMPOSITE_PREFIX + START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 79 public static final String STORE_B_OF_CLASS = COMPOSITE_PREFIX + START + "StoreB" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 80 public static final String STORE_C_OF_CLASS = COMPOSITE_PREFIX + START + "StoreC" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 81 public static final String STORE_I_OF_CLASS = COMPOSITE_PREFIX + START + "StoreI" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 82 public static final String STORE_L_OF_CLASS = COMPOSITE_PREFIX + START + "StoreL" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 83 public static final String STORE_F_OF_CLASS = COMPOSITE_PREFIX + START + "StoreF" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 84 public static final String STORE_D_OF_CLASS = COMPOSITE_PREFIX + START + "StoreD" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 85 public static final String STORE_P_OF_CLASS = COMPOSITE_PREFIX + START + "StoreP" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 86 public static final String STORE_N_OF_CLASS = COMPOSITE_PREFIX + START + "StoreN" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; 87 public static final String STORE_OF_FIELD = COMPOSITE_PREFIX + START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name=" + IS_REPLACED + ",.*" + END; 88 89 public static final String LOAD = START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + END; 90 public static final String LOAD_B = START + "LoadB" + MID + END; 91 public static final String LOAD_UB = START + "LoadUB" + MID + END; // Load from boolean 92 public static final String LOAD_S = START + "LoadS" + MID + END; 93 public static final String LOAD_US = START + "LoadUS" + MID + END; // Load from char 94 public static final String LOAD_I = START + "LoadI" + MID + END; 95 public static final String LOAD_L = START + "LoadL" + MID + END; 96 public static final String LOAD_F = START + "LoadF" + MID + END; 97 public static final String LOAD_D = START + "LoadD" + MID + END; 98 public static final String LOAD_P = START + "LoadP" + MID + END; 99 public static final String LOAD_N = START + "LoadN" + MID + END; 100 public static final String LOAD_VECTOR = START + "LoadVector" + MID + END; 101 public static final String LOAD_OF_CLASS = COMPOSITE_PREFIX + START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + "@\\S*"+ IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 102 public static final String LOAD_B_OF_CLASS = COMPOSITE_PREFIX + START + "LoadB" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 103 public static final String LOAD_UB_OF_CLASS = COMPOSITE_PREFIX + START + "LoadUB" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 104 public static final String LOAD_S_OF_CLASS = COMPOSITE_PREFIX + START + "LoadS" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 105 public static final String LOAD_US_OF_CLASS = COMPOSITE_PREFIX + START + "LoadUS" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 106 public static final String LOAD_I_OF_CLASS = COMPOSITE_PREFIX + START + "LoadI" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 107 public static final String LOAD_L_OF_CLASS = COMPOSITE_PREFIX + START + "LoadL" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 108 public static final String LOAD_F_OF_CLASS = COMPOSITE_PREFIX + START + "LoadF" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 109 public static final String LOAD_D_OF_CLASS = COMPOSITE_PREFIX + START + "LoadD" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 110 public static final String LOAD_P_OF_CLASS = COMPOSITE_PREFIX + START + "LoadP" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 111 public static final String LOAD_N_OF_CLASS = COMPOSITE_PREFIX + START + "LoadN" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; 112 public static final String LOAD_OF_FIELD = COMPOSITE_PREFIX + START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*name=" + IS_REPLACED + ",.*" + END; 113 public static final String LOAD_KLASS = START + "LoadK" + MID + END; 114 115 public static final String LOOP = START + "Loop" + MID + END; 116 public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + END; 117 public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; 118 public static final String OUTERSTRIPMINEDLOOP = START + "OuterStripMinedLoop\\b" + MID + END; 119 public static final String IF = START + "If\\b" + MID + END; 120 121 public static final String CALL = START + "Call.*Java" + MID + END; 122 public static final String CALL_OF_METHOD = COMPOSITE_PREFIX + START + "Call.*Java" + MID + IS_REPLACED + " " + END; 123 public static final String DYNAMIC_CALL_OF_METHOD = COMPOSITE_PREFIX + START + "CallDynamicJava" + MID + IS_REPLACED + " " + END; 124 public static final String STATIC_CALL_OF_METHOD = COMPOSITE_PREFIX + START + "CallStaticJava" + MID + IS_REPLACED + " " + END; 125 public static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*reason" + END; 126 public static final String PREDICATE_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*predicate" + END; 127 public static final String UNSTABLE_IF_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unstable_if" + END; 128 public static final String CLASS_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*class_check" + END; 129 public static final String NULL_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_check" + END; 130 public static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END; 131 public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; 132 public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; 133 public static final String INTRINSIC_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*intrinsic" + END; 134 public static final String DIV_BY_ZERO_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*div0_check" + END; 135 // Does not work for VM builds without JVMCI like x86_32 (a rule containing this regex will be skipped without having JVMCI built). 136 public static final String INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*intrinsic_or_type_checked_inlining" + END; 137 138 public static final String SCOPE_OBJECT = "(.*# ScObj.*" + END; 139 public static final String MEMBAR = START + "MemBar" + MID + END; 140 public static final String SAFEPOINT = START + "SafePoint" + MID + END; 141 142 public static final String ABS_I = START + "AbsI" + MID + END; 143 public static final String ABS_L = START + "AbsL" + MID + END; 144 public static final String ABS_F = START + "AbsF" + MID + END; 145 public static final String ABS_D = START + "AbsD" + MID + END; 146 public static final String AND = START + "And(I|L)" + MID + END; 147 public static final String AND_I = START + "AndI" + MID + END; 148 public static final String AND_L = START + "AndL" + MID + END; 149 public static final String XOR_I = START + "XorI" + MID + END; 150 public static final String XOR_L = START + "XorL" + MID + END; 151 public static final String LSHIFT = START + "LShift(I|L)" + MID + END; 152 public static final String LSHIFT_I = START + "LShiftI" + MID + END; 153 public static final String LSHIFT_L = START + "LShiftL" + MID + END; 154 public static final String RSHIFT = START + "RShift(I|L)" + MID + END; 155 public static final String RSHIFT_I = START + "RShiftI" + MID + END; 156 public static final String RSHIFT_L = START + "RShiftL" + MID + END; 157 public static final String URSHIFT = START + "URShift(B|S|I|L)" + MID + END; 158 public static final String URSHIFT_I = START + "URShiftI" + MID + END; 159 public static final String URSHIFT_L = START + "URShiftL" + MID + END; 160 public static final String ADD = START + "Add(I|L|F|D|P)" + MID + END; 161 public static final String ADD_I = START + "AddI" + MID + END; 162 public static final String ADD_L = START + "AddL" + MID + END; 163 public static final String ADD_VD = START + "AddVD" + MID + END; 164 public static final String SUB = START + "Sub(I|L|F|D)" + MID + END; 165 public static final String SUB_I = START + "SubI" + MID + END; 166 public static final String SUB_L = START + "SubL" + MID + END; 167 public static final String SUB_F = START + "SubF" + MID + END; 168 public static final String SUB_D = START + "SubD" + MID + END; 169 public static final String MUL = START + "Mul(I|L|F|D)" + MID + END; 170 public static final String MUL_I = START + "MulI" + MID + END; 171 public static final String MUL_L = START + "MulL" + MID + END; 172 public static final String DIV = START + "(NoOvf)?Div(I|L|F|D)" + MID + END; 173 public static final String DIV_L = START + "(NoOvf)?DivL" + MID + END; 174 public static final String CON_I = START + "ConI" + MID + END; 175 public static final String CON_L = START + "ConL" + MID + END; 176 public static final String CONV_I2L = START + "ConvI2L" + MID + END; 177 public static final String CONV_L2I = START + "ConvL2I" + MID + END; 178 public static final String POPCOUNT_L = START + "PopCountL" + MID + END; 179 180 public static final String VECTOR_CAST_B2X = START + "VectorCastB2X" + MID + END; 181 public static final String VECTOR_CAST_S2X = START + "VectorCastS2X" + MID + END; 182 public static final String VECTOR_CAST_I2X = START + "VectorCastI2X" + MID + END; 183 public static final String VECTOR_CAST_L2X = START + "VectorCastL2X" + MID + END; 184 public static final String VECTOR_CAST_F2X = START + "VectorCastF2X" + MID + END; 185 public static final String VECTOR_CAST_D2X = START + "VectorCastD2X" + MID + END; 186 public static final String VECTOR_UCAST_B2X = START + "VectorUCastB2X" + MID + END; 187 public static final String VECTOR_UCAST_S2X = START + "VectorUCastS2X" + MID + END; 188 public static final String VECTOR_UCAST_I2X = START + "VectorUCastI2X" + MID + END; 189 public static final String VECTOR_REINTERPRET = START + "VectorReinterpret" + MID + END; 190 191 /** 192 * Called by {@link IRMatcher} to merge special composite nodes together with additional user-defined input. 193 */ 194 public static List<String> mergeNodes(String[] nodes) { 195 List<String> mergedNodes = new ArrayList<>(); 196 for (int i = 0; i < nodes.length; i += 2) { 197 String node = nodes[i]; 198 if (node.startsWith(COMPOSITE_PREFIX)) { 199 if (i + 1 == nodes.length) { 200 reportMissingCompositeValue(node, i); 201 } 202 // Replace placeholder with user defined string. 203 node = node.substring(COMPOSITE_PREFIX.length()).replaceAll(IS_REPLACED, nodes[i + 1]); 204 } else { 205 i--; // No composite node, do not increment by 2. 206 } 207 mergedNodes.add(node); 208 } 209 return mergedNodes; 210 } 211 212 /** 213 * Is default regex supported on current platform, used VM build, etc.? 214 * Throws a {@link CheckedTestFrameworkException} if the default regex is unsupported. 215 */ 216 public static void checkDefaultRegexSupported(String node) throws CheckedTestFrameworkException { 217 switch (node) { 218 case INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP -> { 219 if (!WhiteBox.getWhiteBox().isJVMCISupportedByGC()) { 220 throw new CheckedTestFrameworkException("INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP is unsupported in builds without JVMCI."); 221 } 222 } 223 case CHECKCAST_ARRAYCOPY -> { 224 if (Platform.isS390x()) { 225 throw new CheckedTestFrameworkException("CHECKCAST_ARRAYCOPY is unsupported on s390."); 226 } 227 } 228 // default: do nothing -> default regex is supported 229 } 230 } 231 232 /** 233 * Mapping from string variable value to string variable name for better error reporting. 234 */ 235 private static void reportMissingCompositeValue(String node, int i) { 236 String varName = switch (node) { 237 case ALLOC_OF -> "ALLOC_OF"; 238 case ALLOC_ARRAY_OF -> "ALLOC_ARRAY_OF"; 239 case CHECKCAST_ARRAY_OF -> "CHECKCAST_ARRAY_OF"; 240 case STORE_OF_CLASS -> "STORE_OF_CLASS"; 241 case STORE_B_OF_CLASS -> "STORE_B_OF_CLASS"; 242 case STORE_C_OF_CLASS -> "STORE_C_OF_CLASS"; 243 case STORE_D_OF_CLASS -> "STORE_D_OF_CLASS"; 244 case STORE_F_OF_CLASS -> "STORE_F_OF_CLASS"; 245 case STORE_I_OF_CLASS -> "STORE_I_OF_CLASS"; 246 case STORE_L_OF_CLASS -> "STORE_L_OF_CLASS"; 247 case STORE_N_OF_CLASS -> "STORE_N_OF_CLASS"; 248 case STORE_P_OF_CLASS -> "STORE_P_OF_CLASS"; 249 case STORE_OF_FIELD -> "STORE_OF_FIELD"; 250 case LOAD_OF_CLASS -> "LOAD_OF_CLASS"; 251 case LOAD_B_OF_CLASS -> "LOAD_B_OF_CLASS"; 252 case LOAD_UB_OF_CLASS -> "LOAD_UB_OF_CLASS"; 253 case LOAD_D_OF_CLASS -> "LOAD_D_OF_CLASS"; 254 case LOAD_F_OF_CLASS -> "LOAD_F_OF_CLASS"; 255 case LOAD_I_OF_CLASS -> "LOAD_I_OF_CLASS"; 256 case LOAD_L_OF_CLASS -> "LOAD_L_OF_CLASS"; 257 case LOAD_N_OF_CLASS -> "LOAD_N_OF_CLASS"; 258 case LOAD_P_OF_CLASS -> "LOAD_P_OF_CLASS"; 259 case LOAD_S_OF_CLASS -> "LOAD_S_OF_CLASS"; 260 case LOAD_US_OF_CLASS -> "LOAD_US_OF_CLASS"; 261 case LOAD_OF_FIELD -> "LOAD_OF_FIELD"; 262 default -> throw new TestFrameworkException("Missing variable mapping for " + node); 263 }; 264 TestFormat.fail("Must provide additional value at index " + (i + 1) + " right after " + varName); 265 } 266 }