1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Note that the empty string is present in the BootImage but the other one is a BSS string. We are 18 // testing both AOT LoadString kinds. 19 20 public class Main { main(String[] args)21 public static void main(String[] args) { 22 $noinline$testLength(); 23 $noinline$testIsEmpty(); 24 } 25 $noinline$testLength()26 private static void $noinline$testLength() { 27 assertEquals(0, $noinline$testLengthEmptyString()); 28 assertEquals(0, $noinline$testLengthEmptyStringWithInline()); 29 assertEquals(32, $noinline$testLengthBssString()); 30 assertEquals(32, $noinline$testLengthBssStringWithInline()); 31 } 32 33 /// CHECK-START: int Main.$noinline$testLengthEmptyString() constant_folding (before) 34 /// CHECK: LoadString load_kind:BootImageRelRo 35 /// CHECK: <<Length:i\d+>> ArrayLength 36 /// CHECK: Return [<<Length>>] 37 38 /// CHECK-START: int Main.$noinline$testLengthEmptyString() constant_folding (after) 39 /// CHECK: <<Const0:i\d+>> IntConstant 0 40 /// CHECK: Return [<<Const0>>] 41 42 /// CHECK-START: int Main.$noinline$testLengthEmptyString() dead_code_elimination$initial (after) 43 /// CHECK-NOT: LoadString 44 45 /// CHECK-START: int Main.$noinline$testLengthEmptyString() dead_code_elimination$initial (after) 46 /// CHECK-NOT: ArrayLength $noinline$testLengthEmptyString()47 private static int $noinline$testLengthEmptyString() { 48 String str = ""; 49 return str.length(); 50 } 51 52 /// CHECK-START: int Main.$noinline$testLengthEmptyStringWithInline() constant_folding$after_inlining (before) 53 /// CHECK: LoadString load_kind:BootImageRelRo 54 /// CHECK: <<Length:i\d+>> ArrayLength 55 /// CHECK: Return [<<Length>>] 56 57 /// CHECK-START: int Main.$noinline$testLengthEmptyStringWithInline() constant_folding$after_inlining (after) 58 /// CHECK: <<Const0:i\d+>> IntConstant 0 59 /// CHECK: Return [<<Const0>>] 60 61 /// CHECK-START: int Main.$noinline$testLengthEmptyStringWithInline() dead_code_elimination$after_inlining (after) 62 /// CHECK-NOT: LoadString 63 64 /// CHECK-START: int Main.$noinline$testLengthEmptyStringWithInline() dead_code_elimination$after_inlining (after) 65 /// CHECK-NOT: ArrayLength $noinline$testLengthEmptyStringWithInline()66 private static int $noinline$testLengthEmptyStringWithInline() { 67 String str = ""; 68 return $inline$returnLength(str); 69 } 70 71 /// CHECK-START: int Main.$noinline$testLengthBssString() constant_folding (before) 72 /// CHECK: LoadString load_kind:BssEntry 73 /// CHECK: <<Length:i\d+>> ArrayLength 74 /// CHECK: Return [<<Length>>] 75 76 /// CHECK-START: int Main.$noinline$testLengthBssString() constant_folding (after) 77 /// CHECK: <<Const32:i\d+>> IntConstant 32 78 /// CHECK: Return [<<Const32>>] 79 80 // We don't remove LoadString load_kind:BssEntry even if they have no uses, since IsRemovable() 81 // returns false for them. 82 /// CHECK-START: int Main.$noinline$testLengthBssString() dead_code_elimination$initial (after) 83 /// CHECK: LoadString load_kind:BssEntry 84 85 /// CHECK-START: int Main.$noinline$testLengthBssString() dead_code_elimination$initial (after) 86 /// CHECK-NOT: ArrayLength $noinline$testLengthBssString()87 private static int $noinline$testLengthBssString() { 88 String str = "2047-checker-const-string-length"; 89 return str.length(); 90 } 91 92 /// CHECK-START: int Main.$noinline$testLengthBssStringWithInline() constant_folding$after_inlining (before) 93 /// CHECK: LoadString load_kind:BssEntry 94 /// CHECK: <<Length:i\d+>> ArrayLength 95 /// CHECK: Return [<<Length>>] 96 97 /// CHECK-START: int Main.$noinline$testLengthBssStringWithInline() constant_folding$after_inlining (after) 98 /// CHECK: <<Const32:i\d+>> IntConstant 32 99 /// CHECK: Return [<<Const32>>] 100 101 // We don't remove LoadString load_kind:BssEntry even if they have no uses, since IsRemovable() 102 // returns false for them. 103 /// CHECK-START: int Main.$noinline$testLengthBssStringWithInline() dead_code_elimination$after_inlining (after) 104 /// CHECK: LoadString load_kind:BssEntry 105 106 /// CHECK-START: int Main.$noinline$testLengthBssStringWithInline() dead_code_elimination$after_inlining (after) 107 /// CHECK-NOT: ArrayLength $noinline$testLengthBssStringWithInline()108 private static int $noinline$testLengthBssStringWithInline() { 109 String str = "2047-checker-const-string-length"; 110 return $inline$returnLength(str); 111 } 112 $inline$returnLength(String str)113 private static int $inline$returnLength(String str) { 114 return str.length(); 115 } 116 $noinline$testIsEmpty()117 private static void $noinline$testIsEmpty() { 118 assertEquals(true, $noinline$testIsEmptyEmptyString()); 119 assertEquals(true, $noinline$testIsEmptyEmptyStringWithInline()); 120 assertEquals(false, $noinline$testIsEmptyBssString()); 121 assertEquals(false, $noinline$testIsEmptyBssStringWithInline()); 122 } 123 124 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyString() constant_folding (before) 125 /// CHECK: <<Const0:i\d+>> IntConstant 0 126 /// CHECK: LoadString load_kind:BootImageRelRo 127 /// CHECK: <<Length:i\d+>> ArrayLength 128 /// CHECK: <<Eq:z\d+>> Equal [<<Length>>,<<Const0>>] 129 /// CHECK: Return [<<Eq>>] 130 131 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyString() constant_folding (after) 132 /// CHECK: <<Const1:i\d+>> IntConstant 1 133 /// CHECK: Return [<<Const1>>] 134 135 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyString() dead_code_elimination$initial (after) 136 /// CHECK-NOT: LoadString 137 138 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyString() dead_code_elimination$initial (after) 139 /// CHECK-NOT: ArrayLength $noinline$testIsEmptyEmptyString()140 private static boolean $noinline$testIsEmptyEmptyString() { 141 String str = ""; 142 return str.isEmpty(); 143 } 144 145 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyStringWithInline() constant_folding$after_inlining (before) 146 /// CHECK: <<Const0:i\d+>> IntConstant 0 147 /// CHECK: LoadString load_kind:BootImageRelRo 148 /// CHECK: <<Length:i\d+>> ArrayLength 149 /// CHECK: <<Eq:z\d+>> Equal [<<Length>>,<<Const0>>] 150 /// CHECK: Return [<<Eq>>] 151 152 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyStringWithInline() constant_folding$after_inlining (after) 153 /// CHECK: <<Const1:i\d+>> IntConstant 1 154 /// CHECK: Return [<<Const1>>] 155 156 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyStringWithInline() dead_code_elimination$after_inlining (after) 157 /// CHECK-NOT: LoadString 158 159 /// CHECK-START: boolean Main.$noinline$testIsEmptyEmptyStringWithInline() dead_code_elimination$after_inlining (after) 160 /// CHECK-NOT: ArrayLength $noinline$testIsEmptyEmptyStringWithInline()161 private static boolean $noinline$testIsEmptyEmptyStringWithInline() { 162 String str = ""; 163 return $inline$returnIsEmpty(str); 164 } 165 166 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssString() constant_folding (before) 167 /// CHECK: <<Const0:i\d+>> IntConstant 0 168 /// CHECK: LoadString load_kind:BssEntry 169 /// CHECK: <<Length:i\d+>> ArrayLength 170 /// CHECK: <<Eq:z\d+>> Equal [<<Length>>,<<Const0>>] 171 /// CHECK: Return [<<Eq>>] 172 173 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssString() constant_folding (after) 174 /// CHECK: <<Const0:i\d+>> IntConstant 0 175 /// CHECK: Return [<<Const0>>] 176 177 // We don't remove LoadString load_kind:BssEntry even if they have no uses, since IsRemovable() 178 // returns false for them. 179 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssString() dead_code_elimination$initial (after) 180 /// CHECK: LoadString load_kind:BssEntry 181 182 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssString() dead_code_elimination$initial (after) 183 /// CHECK-NOT: ArrayLength $noinline$testIsEmptyBssString()184 private static boolean $noinline$testIsEmptyBssString() { 185 String str = "2047-checker-const-string-length"; 186 return str.isEmpty(); 187 } 188 189 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssStringWithInline() constant_folding$after_inlining (before) 190 /// CHECK: <<Const0:i\d+>> IntConstant 0 191 /// CHECK: LoadString load_kind:BssEntry 192 /// CHECK: <<Length:i\d+>> ArrayLength 193 /// CHECK: <<Eq:z\d+>> Equal [<<Length>>,<<Const0>>] 194 /// CHECK: Return [<<Eq>>] 195 196 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssStringWithInline() constant_folding$after_inlining (after) 197 /// CHECK: <<Const0:i\d+>> IntConstant 0 198 /// CHECK: Return [<<Const0>>] 199 200 // We don't remove LoadString load_kind:BssEntry even if they have no uses, since IsRemovable() 201 // returns false for them. 202 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssStringWithInline() dead_code_elimination$after_inlining (after) 203 /// CHECK: LoadString load_kind:BssEntry 204 205 /// CHECK-START: boolean Main.$noinline$testIsEmptyBssStringWithInline() dead_code_elimination$after_inlining (after) 206 /// CHECK-NOT: ArrayLength $noinline$testIsEmptyBssStringWithInline()207 private static boolean $noinline$testIsEmptyBssStringWithInline() { 208 String str = "2047-checker-const-string-length"; 209 return $inline$returnIsEmpty(str); 210 } 211 $inline$returnIsEmpty(String str)212 private static boolean $inline$returnIsEmpty(String str) { 213 return str.isEmpty(); 214 } 215 assertEquals(int expected, int actual)216 static void assertEquals(int expected, int actual) { 217 if (expected != actual) { 218 throw new AssertionError("Expected " + expected + " got " + actual); 219 } 220 } 221 assertEquals(boolean expected, boolean actual)222 static void assertEquals(boolean expected, boolean actual) { 223 if (expected != actual) { 224 throw new AssertionError("Expected " + expected + " got " + actual); 225 } 226 } 227 } 228