1 // Copyright (c) 2017 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Tests for unique type declaration rules validator. 16 17 #include <string> 18 #include <unordered_map> 19 20 #include "test/test_fixture.h" 21 #include "test/unit_spirv.h" 22 #include "tools/stats/spirv_stats.h" 23 24 namespace spvtools { 25 namespace stats { 26 namespace { 27 28 using spvtest::ScopedContext; 29 30 void DiagnosticsMessageHandler(spv_message_level_t level, const char*, 31 const spv_position_t& position, 32 const char* message) { 33 switch (level) { 34 case SPV_MSG_FATAL: 35 case SPV_MSG_INTERNAL_ERROR: 36 case SPV_MSG_ERROR: 37 std::cerr << "error: " << position.index << ": " << message << std::endl; 38 break; 39 case SPV_MSG_WARNING: 40 std::cout << "warning: " << position.index << ": " << message 41 << std::endl; 42 break; 43 case SPV_MSG_INFO: 44 std::cout << "info: " << position.index << ": " << message << std::endl; 45 break; 46 default: 47 break; 48 } 49 } 50 51 // Calls AggregateStats for binary compiled from |code|. 52 void CompileAndAggregateStats(const std::string& code, SpirvStats* stats, 53 spv_target_env env = SPV_ENV_UNIVERSAL_1_1) { 54 spvtools::Context ctx(env); 55 ctx.SetMessageConsumer(DiagnosticsMessageHandler); 56 spv_binary binary; 57 ASSERT_EQ(SPV_SUCCESS, spvTextToBinary(ctx.CContext(), code.c_str(), 58 code.size(), &binary, nullptr)); 59 60 ASSERT_EQ(SPV_SUCCESS, AggregateStats(ctx.CContext(), binary->code, 61 binary->wordCount, nullptr, stats)); 62 spvBinaryDestroy(binary); 63 } 64 65 TEST(AggregateStats, CapabilityHistogram) { 66 const std::string code1 = R"( 67 OpCapability Addresses 68 OpCapability Kernel 69 OpCapability GenericPointer 70 OpCapability Linkage 71 OpMemoryModel Physical32 OpenCL 72 )"; 73 74 const std::string code2 = R"( 75 OpCapability Shader 76 OpCapability Linkage 77 OpMemoryModel Logical GLSL450 78 )"; 79 80 SpirvStats stats; 81 82 CompileAndAggregateStats(code1, &stats); 83 EXPECT_EQ(4u, stats.capability_hist.size()); 84 EXPECT_EQ(0u, stats.capability_hist.count(SpvCapabilityShader)); 85 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityAddresses)); 86 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityKernel)); 87 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityGenericPointer)); 88 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityLinkage)); 89 90 CompileAndAggregateStats(code2, &stats); 91 EXPECT_EQ(5u, stats.capability_hist.size()); 92 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityShader)); 93 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityAddresses)); 94 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityKernel)); 95 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityGenericPointer)); 96 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityLinkage)); 97 98 CompileAndAggregateStats(code1, &stats); 99 EXPECT_EQ(5u, stats.capability_hist.size()); 100 EXPECT_EQ(1u, stats.capability_hist.at(SpvCapabilityShader)); 101 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityAddresses)); 102 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityKernel)); 103 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityGenericPointer)); 104 EXPECT_EQ(3u, stats.capability_hist.at(SpvCapabilityLinkage)); 105 106 CompileAndAggregateStats(code2, &stats); 107 EXPECT_EQ(5u, stats.capability_hist.size()); 108 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityShader)); 109 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityAddresses)); 110 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityKernel)); 111 EXPECT_EQ(2u, stats.capability_hist.at(SpvCapabilityGenericPointer)); 112 EXPECT_EQ(4u, stats.capability_hist.at(SpvCapabilityLinkage)); 113 } 114 115 TEST(AggregateStats, ExtensionHistogram) { 116 const std::string code1 = R"( 117 OpCapability Addresses 118 OpCapability Kernel 119 OpCapability GenericPointer 120 OpCapability Linkage 121 OpExtension "SPV_KHR_16bit_storage" 122 OpMemoryModel Physical32 OpenCL 123 )"; 124 125 const std::string code2 = R"( 126 OpCapability Shader 127 OpCapability Linkage 128 OpExtension "SPV_NV_viewport_array2" 129 OpExtension "greatest_extension_ever" 130 OpMemoryModel Logical GLSL450 131 )"; 132 133 SpirvStats stats; 134 135 CompileAndAggregateStats(code1, &stats); 136 EXPECT_EQ(1u, stats.extension_hist.size()); 137 EXPECT_EQ(0u, stats.extension_hist.count("SPV_NV_viewport_array2")); 138 EXPECT_EQ(1u, stats.extension_hist.at("SPV_KHR_16bit_storage")); 139 140 CompileAndAggregateStats(code2, &stats); 141 EXPECT_EQ(3u, stats.extension_hist.size()); 142 EXPECT_EQ(1u, stats.extension_hist.at("SPV_NV_viewport_array2")); 143 EXPECT_EQ(1u, stats.extension_hist.at("SPV_KHR_16bit_storage")); 144 EXPECT_EQ(1u, stats.extension_hist.at("greatest_extension_ever")); 145 146 CompileAndAggregateStats(code1, &stats); 147 EXPECT_EQ(3u, stats.extension_hist.size()); 148 EXPECT_EQ(1u, stats.extension_hist.at("SPV_NV_viewport_array2")); 149 EXPECT_EQ(2u, stats.extension_hist.at("SPV_KHR_16bit_storage")); 150 EXPECT_EQ(1u, stats.extension_hist.at("greatest_extension_ever")); 151 152 CompileAndAggregateStats(code2, &stats); 153 EXPECT_EQ(3u, stats.extension_hist.size()); 154 EXPECT_EQ(2u, stats.extension_hist.at("SPV_NV_viewport_array2")); 155 EXPECT_EQ(2u, stats.extension_hist.at("SPV_KHR_16bit_storage")); 156 EXPECT_EQ(2u, stats.extension_hist.at("greatest_extension_ever")); 157 } 158 159 TEST(AggregateStats, VersionHistogram) { 160 const std::string code1 = R"( 161 OpCapability Shader 162 OpCapability Linkage 163 OpMemoryModel Logical GLSL450 164 )"; 165 166 SpirvStats stats; 167 168 CompileAndAggregateStats(code1, &stats); 169 EXPECT_EQ(1u, stats.version_hist.size()); 170 EXPECT_EQ(1u, stats.version_hist.at(0x00010100)); 171 172 CompileAndAggregateStats(code1, &stats, SPV_ENV_UNIVERSAL_1_0); 173 EXPECT_EQ(2u, stats.version_hist.size()); 174 EXPECT_EQ(1u, stats.version_hist.at(0x00010100)); 175 EXPECT_EQ(1u, stats.version_hist.at(0x00010000)); 176 177 CompileAndAggregateStats(code1, &stats); 178 EXPECT_EQ(2u, stats.version_hist.size()); 179 EXPECT_EQ(2u, stats.version_hist.at(0x00010100)); 180 EXPECT_EQ(1u, stats.version_hist.at(0x00010000)); 181 182 CompileAndAggregateStats(code1, &stats, SPV_ENV_UNIVERSAL_1_0); 183 EXPECT_EQ(2u, stats.version_hist.size()); 184 EXPECT_EQ(2u, stats.version_hist.at(0x00010100)); 185 EXPECT_EQ(2u, stats.version_hist.at(0x00010000)); 186 } 187 188 TEST(AggregateStats, GeneratorHistogram) { 189 const std::string code1 = R"( 190 OpCapability Shader 191 OpCapability Linkage 192 OpMemoryModel Logical GLSL450 193 )"; 194 195 const uint32_t kGeneratorKhronosAssembler = SPV_GENERATOR_KHRONOS_ASSEMBLER 196 << 16; 197 198 SpirvStats stats; 199 200 CompileAndAggregateStats(code1, &stats); 201 EXPECT_EQ(1u, stats.generator_hist.size()); 202 EXPECT_EQ(1u, stats.generator_hist.at(kGeneratorKhronosAssembler)); 203 204 CompileAndAggregateStats(code1, &stats); 205 EXPECT_EQ(1u, stats.generator_hist.size()); 206 EXPECT_EQ(2u, stats.generator_hist.at(kGeneratorKhronosAssembler)); 207 } 208 209 TEST(AggregateStats, OpcodeHistogram) { 210 const std::string code1 = R"( 211 OpCapability Addresses 212 OpCapability Kernel 213 OpCapability Int64 214 OpCapability Linkage 215 OpMemoryModel Physical32 OpenCL 216 %u64 = OpTypeInt 64 0 217 %u32 = OpTypeInt 32 0 218 %f32 = OpTypeFloat 32 219 )"; 220 221 const std::string code2 = R"( 222 OpCapability Shader 223 OpCapability Linkage 224 OpExtension "SPV_NV_viewport_array2" 225 OpMemoryModel Logical GLSL450 226 )"; 227 228 SpirvStats stats; 229 230 CompileAndAggregateStats(code1, &stats); 231 EXPECT_EQ(4u, stats.opcode_hist.size()); 232 EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpCapability)); 233 EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpMemoryModel)); 234 EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeInt)); 235 EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpTypeFloat)); 236 237 CompileAndAggregateStats(code2, &stats); 238 EXPECT_EQ(5u, stats.opcode_hist.size()); 239 EXPECT_EQ(6u, stats.opcode_hist.at(SpvOpCapability)); 240 EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpMemoryModel)); 241 EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeInt)); 242 EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpTypeFloat)); 243 EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpExtension)); 244 245 CompileAndAggregateStats(code1, &stats); 246 EXPECT_EQ(5u, stats.opcode_hist.size()); 247 EXPECT_EQ(10u, stats.opcode_hist.at(SpvOpCapability)); 248 EXPECT_EQ(3u, stats.opcode_hist.at(SpvOpMemoryModel)); 249 EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpTypeInt)); 250 EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeFloat)); 251 EXPECT_EQ(1u, stats.opcode_hist.at(SpvOpExtension)); 252 253 CompileAndAggregateStats(code2, &stats); 254 EXPECT_EQ(5u, stats.opcode_hist.size()); 255 EXPECT_EQ(12u, stats.opcode_hist.at(SpvOpCapability)); 256 EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpMemoryModel)); 257 EXPECT_EQ(4u, stats.opcode_hist.at(SpvOpTypeInt)); 258 EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpTypeFloat)); 259 EXPECT_EQ(2u, stats.opcode_hist.at(SpvOpExtension)); 260 } 261 262 TEST(AggregateStats, OpcodeMarkovHistogram) { 263 const std::string code1 = R"( 264 OpCapability Shader 265 OpCapability Linkage 266 OpExtension "SPV_NV_viewport_array2" 267 OpMemoryModel Logical GLSL450 268 )"; 269 270 const std::string code2 = R"( 271 OpCapability Addresses 272 OpCapability Kernel 273 OpCapability Int64 274 OpCapability Linkage 275 OpMemoryModel Physical32 OpenCL 276 %u64 = OpTypeInt 64 0 277 %u32 = OpTypeInt 32 0 278 %f32 = OpTypeFloat 32 279 )"; 280 281 SpirvStats stats; 282 stats.opcode_markov_hist.resize(2); 283 284 CompileAndAggregateStats(code1, &stats); 285 ASSERT_EQ(2u, stats.opcode_markov_hist.size()); 286 EXPECT_EQ(2u, stats.opcode_markov_hist[0].size()); 287 EXPECT_EQ(2u, stats.opcode_markov_hist[0].at(SpvOpCapability).size()); 288 EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpExtension).size()); 289 EXPECT_EQ( 290 1u, stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpCapability)); 291 EXPECT_EQ(1u, 292 stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpExtension)); 293 EXPECT_EQ( 294 1u, stats.opcode_markov_hist[0].at(SpvOpExtension).at(SpvOpMemoryModel)); 295 296 EXPECT_EQ(1u, stats.opcode_markov_hist[1].size()); 297 EXPECT_EQ(2u, stats.opcode_markov_hist[1].at(SpvOpCapability).size()); 298 EXPECT_EQ(1u, 299 stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpExtension)); 300 EXPECT_EQ( 301 1u, stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpMemoryModel)); 302 303 CompileAndAggregateStats(code2, &stats); 304 ASSERT_EQ(2u, stats.opcode_markov_hist.size()); 305 EXPECT_EQ(4u, stats.opcode_markov_hist[0].size()); 306 EXPECT_EQ(3u, stats.opcode_markov_hist[0].at(SpvOpCapability).size()); 307 EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpExtension).size()); 308 EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpMemoryModel).size()); 309 EXPECT_EQ(2u, stats.opcode_markov_hist[0].at(SpvOpTypeInt).size()); 310 EXPECT_EQ( 311 4u, stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpCapability)); 312 EXPECT_EQ(1u, 313 stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpExtension)); 314 EXPECT_EQ( 315 1u, stats.opcode_markov_hist[0].at(SpvOpCapability).at(SpvOpMemoryModel)); 316 EXPECT_EQ( 317 1u, stats.opcode_markov_hist[0].at(SpvOpExtension).at(SpvOpMemoryModel)); 318 EXPECT_EQ(1u, 319 stats.opcode_markov_hist[0].at(SpvOpMemoryModel).at(SpvOpTypeInt)); 320 EXPECT_EQ(1u, stats.opcode_markov_hist[0].at(SpvOpTypeInt).at(SpvOpTypeInt)); 321 EXPECT_EQ(1u, 322 stats.opcode_markov_hist[0].at(SpvOpTypeInt).at(SpvOpTypeFloat)); 323 324 EXPECT_EQ(3u, stats.opcode_markov_hist[1].size()); 325 EXPECT_EQ(4u, stats.opcode_markov_hist[1].at(SpvOpCapability).size()); 326 EXPECT_EQ(1u, stats.opcode_markov_hist[1].at(SpvOpMemoryModel).size()); 327 EXPECT_EQ(1u, stats.opcode_markov_hist[1].at(SpvOpTypeInt).size()); 328 EXPECT_EQ( 329 2u, stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpCapability)); 330 EXPECT_EQ(1u, 331 stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpExtension)); 332 EXPECT_EQ( 333 2u, stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpMemoryModel)); 334 EXPECT_EQ(1u, 335 stats.opcode_markov_hist[1].at(SpvOpCapability).at(SpvOpTypeInt)); 336 EXPECT_EQ(1u, 337 stats.opcode_markov_hist[1].at(SpvOpMemoryModel).at(SpvOpTypeInt)); 338 EXPECT_EQ(1u, 339 stats.opcode_markov_hist[1].at(SpvOpTypeInt).at(SpvOpTypeFloat)); 340 } 341 342 TEST(AggregateStats, ConstantLiteralsHistogram) { 343 const std::string code1 = R"( 344 OpCapability Addresses 345 OpCapability Kernel 346 OpCapability GenericPointer 347 OpCapability Linkage 348 OpCapability Float64 349 OpCapability Int16 350 OpCapability Int64 351 OpMemoryModel Physical32 OpenCL 352 %u16 = OpTypeInt 16 0 353 %u32 = OpTypeInt 32 0 354 %u64 = OpTypeInt 64 0 355 %f32 = OpTypeFloat 32 356 %f64 = OpTypeFloat 64 357 %1 = OpConstant %f32 0.1 358 %2 = OpConstant %f32 -2 359 %3 = OpConstant %f64 -2 360 %4 = OpConstant %u16 16 361 %5 = OpConstant %u16 2 362 %6 = OpConstant %u32 32 363 %7 = OpConstant %u64 64 364 )"; 365 366 const std::string code2 = R"( 367 OpCapability Shader 368 OpCapability Linkage 369 OpCapability Int16 370 OpCapability Int64 371 OpMemoryModel Logical GLSL450 372 %f32 = OpTypeFloat 32 373 %u16 = OpTypeInt 16 0 374 %s16 = OpTypeInt 16 1 375 %u32 = OpTypeInt 32 0 376 %s32 = OpTypeInt 32 1 377 %u64 = OpTypeInt 64 0 378 %s64 = OpTypeInt 64 1 379 %1 = OpConstant %f32 0.1 380 %2 = OpConstant %f32 -2 381 %3 = OpConstant %u16 1 382 %4 = OpConstant %u16 16 383 %5 = OpConstant %u16 2 384 %6 = OpConstant %s16 -16 385 %7 = OpConstant %u32 32 386 %8 = OpConstant %s32 2 387 %9 = OpConstant %s32 -32 388 %10 = OpConstant %u64 64 389 %11 = OpConstant %s64 -64 390 )"; 391 392 SpirvStats stats; 393 394 CompileAndAggregateStats(code1, &stats); 395 EXPECT_EQ(2u, stats.f32_constant_hist.size()); 396 EXPECT_EQ(1u, stats.f64_constant_hist.size()); 397 EXPECT_EQ(1u, stats.f32_constant_hist.at(0.1f)); 398 EXPECT_EQ(1u, stats.f32_constant_hist.at(-2.f)); 399 EXPECT_EQ(1u, stats.f64_constant_hist.at(-2)); 400 401 EXPECT_EQ(2u, stats.u16_constant_hist.size()); 402 EXPECT_EQ(0u, stats.s16_constant_hist.size()); 403 EXPECT_EQ(1u, stats.u32_constant_hist.size()); 404 EXPECT_EQ(0u, stats.s32_constant_hist.size()); 405 EXPECT_EQ(1u, stats.u64_constant_hist.size()); 406 EXPECT_EQ(0u, stats.s64_constant_hist.size()); 407 EXPECT_EQ(1u, stats.u16_constant_hist.at(16)); 408 EXPECT_EQ(1u, stats.u16_constant_hist.at(2)); 409 EXPECT_EQ(1u, stats.u32_constant_hist.at(32)); 410 EXPECT_EQ(1u, stats.u64_constant_hist.at(64)); 411 412 CompileAndAggregateStats(code2, &stats); 413 EXPECT_EQ(2u, stats.f32_constant_hist.size()); 414 EXPECT_EQ(1u, stats.f64_constant_hist.size()); 415 EXPECT_EQ(2u, stats.f32_constant_hist.at(0.1f)); 416 EXPECT_EQ(2u, stats.f32_constant_hist.at(-2.f)); 417 EXPECT_EQ(1u, stats.f64_constant_hist.at(-2)); 418 419 EXPECT_EQ(3u, stats.u16_constant_hist.size()); 420 EXPECT_EQ(1u, stats.s16_constant_hist.size()); 421 EXPECT_EQ(1u, stats.u32_constant_hist.size()); 422 EXPECT_EQ(2u, stats.s32_constant_hist.size()); 423 EXPECT_EQ(1u, stats.u64_constant_hist.size()); 424 EXPECT_EQ(1u, stats.s64_constant_hist.size()); 425 EXPECT_EQ(2u, stats.u16_constant_hist.at(16)); 426 EXPECT_EQ(2u, stats.u16_constant_hist.at(2)); 427 EXPECT_EQ(1u, stats.u16_constant_hist.at(1)); 428 EXPECT_EQ(1u, stats.s16_constant_hist.at(-16)); 429 EXPECT_EQ(2u, stats.u32_constant_hist.at(32)); 430 EXPECT_EQ(1u, stats.s32_constant_hist.at(2)); 431 EXPECT_EQ(1u, stats.s32_constant_hist.at(-32)); 432 EXPECT_EQ(2u, stats.u64_constant_hist.at(64)); 433 EXPECT_EQ(1u, stats.s64_constant_hist.at(-64)); 434 } 435 436 } // namespace 437 } // namespace stats 438 } // namespace spvtools 439