├── .clang-format ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── appveyor.yml └── spirv-stats.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | Standard: Cpp03 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | os: 4 | - linux 5 | - osx 6 | 7 | compiler: 8 | - gcc 9 | - clang 10 | 11 | env: 12 | - CONFIGURATION=Debug 13 | - CONFIGURATION=Release 14 | 15 | script: 16 | - mkdir build 17 | - cd build 18 | - cmake -DCMAKE_BUILD_TYPE=$CONFIGURATION .. 19 | - make 20 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This is free and unencumbered software released into the public domain. 2 | # 3 | # Anyone is free to copy, modify, publish, use, compile, sell, or 4 | # distribute this software, either in source code form or as a compiled 5 | # binary, for any purpose, commercial or non-commercial, and by any 6 | # means. 7 | # 8 | # In jurisdictions that recognize copyright laws, the author or authors 9 | # of this software dedicate any and all copyright interest in the 10 | # software to the public domain. We make this dedication for the benefit 11 | # of the public at large and to the detriment of our heirs and 12 | # successors. We intend this dedication to be an overt act of 13 | # relinquishment in perpetuity of all present and future rights to this 14 | # software under copyright law. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | # OTHER DEALINGS IN THE SOFTWARE. 23 | # 24 | # For more information, please refer to 25 | 26 | project(spirv-stats) 27 | cmake_minimum_required(VERSION 2.8.7) 28 | 29 | add_executable(spirv-stats 30 | spirv-stats.cpp 31 | ) 32 | 33 | if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 34 | set_source_files_properties(spirv-stats.cpp PROPERTIES 35 | COMPILE_FLAGS "-Wall -Wextra -Werror" 36 | ) 37 | elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") 38 | set_source_files_properties(spirv-stats.cpp PROPERTIES 39 | COMPILE_FLAGS "-Wall -Wextra -Weverything -Werror -Wno-c++11-long-long" 40 | ) 41 | elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") 42 | set_source_files_properties(spirv-stats.cpp PROPERTIES 43 | COMPILE_FLAGS "/Wall /WX /wd4350 /wd4514" 44 | ) 45 | else() 46 | message(WARNING "Unknown compiler '${CMAKE_C_COMPILER_ID}'!") 47 | endif() 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spirv-stats # 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/m6teyt0y958xbpy5?svg=true)](https://ci.appveyor.com/project/sheredom/spirv-stats) 4 | 5 | [![Build status](https://api.travis-ci.org/repositories/sheredom/spirv-stats.svg)](https://travis-ci.org/sheredom/spirv-stats) 6 | 7 | spirv-stats is a command line tool to take one or more SPIR-V modules, and output statistics on the composition of the module. 8 | 9 | ## Build ## 10 | 11 | spirv-stats exists in one C++ file - spirv-stats.cpp. Build that with the compiler of your choice. Alternatively, there is a CMakeLists.txt provided within the repository that will build the command line tool for you. 12 | 13 | ## Run ## 14 | 15 | An expected run of spirv-stats is something like the below: 16 | 17 | ``` 18 | Totals: 35 hits 564 bytes 19 | OpDecorate = 5 hits (14.29%) 80 bytes (14.18%) 20 | OpTypePointer = 4 hits (11.43%) 64 bytes (11.35%) 21 | OpVariable = 4 hits (11.43%) 64 bytes (11.35%) 22 | OpLoad = 3 hits ( 8.57%) 48 bytes ( 8.51%) 23 | OpTypeVector = 2 hits ( 5.71%) 32 bytes ( 5.67%) 24 | OpExtInstImport = 1 hits ( 2.86%) 24 bytes ( 4.26%) 25 | OpMemoryModel = 1 hits ( 2.86%) 12 bytes ( 2.13%) 26 | OpEntryPoint = 1 hits ( 2.86%) 32 bytes ( 5.67%) 27 | OpExecutionMode = 1 hits ( 2.86%) 12 bytes ( 2.13%) 28 | OpCapability = 1 hits ( 2.86%) 8 bytes ( 1.42%) 29 | OpTypeVoid = 1 hits ( 2.86%) 8 bytes ( 1.42%) 30 | OpTypeFloat = 1 hits ( 2.86%) 12 bytes ( 2.13%) 31 | OpTypeImage = 1 hits ( 2.86%) 36 bytes ( 6.38%) 32 | OpTypeSampledImage = 1 hits ( 2.86%) 12 bytes ( 2.13%) 33 | OpTypeFunction = 1 hits ( 2.86%) 12 bytes ( 2.13%) 34 | OpFunction = 1 hits ( 2.86%) 20 bytes ( 3.55%) 35 | OpFunctionEnd = 1 hits ( 2.86%) 4 bytes ( 0.71%) 36 | OpStore = 1 hits ( 2.86%) 12 bytes ( 2.13%) 37 | OpImageSampleImplicitLod = 1 hits ( 2.86%) 20 bytes ( 3.55%) 38 | OpFMul = 1 hits ( 2.86%) 20 bytes ( 3.55%) 39 | OpLabel = 1 hits ( 2.86%) 8 bytes ( 1.42%) 40 | OpReturn = 1 hits ( 2.86%) 4 bytes ( 0.71%) 41 | ``` 42 | 43 | It first outputs the total number of opcodes found (hits) and the bytes that this SPIR-V module inhabits. Then, on a per opcode basis, it lists the opcodes found in the module, the number of times that opcode occurred (hits), and the number of bytes that that opcode takes up in the SPIR-V binary. 44 | 45 | ## License ## 46 | 47 | This is free and unencumbered software released into the public domain. 48 | 49 | Anyone is free to copy, modify, publish, use, compile, sell, or 50 | distribute this software, either in source code form or as a compiled 51 | binary, for any purpose, commercial or non-commercial, and by any 52 | means. 53 | 54 | In jurisdictions that recognize copyright laws, the author or authors 55 | of this software dedicate any and all copyright interest in the 56 | software to the public domain. We make this dedication for the benefit 57 | of the public at large and to the detriment of our heirs and 58 | successors. We intend this dedication to be an overt act of 59 | relinquishment in perpetuity of all present and future rights to this 60 | software under copyright law. 61 | 62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 63 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 64 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 65 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 66 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 67 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 68 | OTHER DEALINGS IN THE SOFTWARE. 69 | 70 | For more information, please refer to 71 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | 3 | skip_tags: true 4 | 5 | install: [] 6 | 7 | environment: 8 | matrix: 9 | - VSVERSION: Visual Studio 11 10 | - VSVERSION: Visual Studio 12 11 | - VSVERSION: Visual Studio 14 12 | 13 | platform: 14 | - Win32 15 | - x64 16 | 17 | configuration: 18 | - Debug 19 | - Release 20 | 21 | build_script: 22 | - md build 23 | - cd build 24 | - if "%PLATFORM%"=="x64" cmake -G "%VSVERSION% Win64" .. 25 | - if "%PLATFORM%"=="Win32" cmake -G "%VSVERSION%" .. 26 | - msbuild /m /p:Configuration="%CONFIGURATION%" /p:Platform="%PLATFORM%" spirv-stats.sln 27 | -------------------------------------------------------------------------------- /spirv-stats.cpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // 3 | // Anyone is free to copy, modify, publish, use, compile, sell, or 4 | // distribute this software, either in source code form or as a compiled 5 | // binary, for any purpose, commercial or non-commercial, and by any 6 | // means. 7 | // 8 | // In jurisdictions that recognize copyright laws, the author or authors 9 | // of this software dedicate any and all copyright interest in the 10 | // software to the public domain. We make this dedication for the benefit 11 | // of the public at large and to the detriment of our heirs and 12 | // successors. We intend this dedication to be an overt act of 13 | // relinquishment in perpetuity of all present and future rights to this 14 | // software under copyright law. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | // OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | // For more information, please refer to 25 | 26 | #ifdef _MSC_VER 27 | // Disable warning about not inlining inline functions 28 | #pragma warning(disable : 4710) 29 | // Disable warning about inlining non-inline functions 30 | #pragma warning(disable : 4711) 31 | #pragma warning(push, 1) 32 | 33 | // Disable warning in the CRT 34 | #define _CRT_SECURE_NO_WARNINGS 35 | #endif 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #if defined(_MSC_VER) 45 | #undef _CRT_SECURE_NO_WARNINGS 46 | #pragma warning(pop) 47 | #endif 48 | 49 | static const uint32_t magicNumber = 0x07230203u; 50 | static const uint32_t reserveMagicNumber = 0x03022307u; 51 | static const uint32_t numWordsInHeader = 5u; 52 | 53 | static const uint32_t opConstant = 43u; 54 | static const uint32_t opVariable = 59u; 55 | static const uint32_t opLoad = 61u; 56 | static const uint32_t opStore = 62u; 57 | static const uint32_t opAccessChain = 65u; 58 | static const uint32_t opDecorate = 71u; 59 | static const uint32_t opMemberDecorate = 72u; 60 | static const uint32_t opVectorShuffle = 79u; 61 | static const uint32_t opCompositeConstruct = 80u; 62 | static const uint32_t opCompositeExtract = 81u; 63 | 64 | int main(const int argc, const char *const argv[]) { 65 | std::map opcodes; 66 | opcodes[0] = "OpNop"; 67 | opcodes[1] = "OpUndef"; 68 | opcodes[2] = "OpSourceContinued"; 69 | opcodes[3] = "OpSource"; 70 | opcodes[4] = "OpSourceExtension"; 71 | opcodes[5] = "OpName"; 72 | opcodes[6] = "OpMemberName"; 73 | opcodes[7] = "OpString"; 74 | opcodes[8] = "OpLine"; 75 | opcodes[10] = "OpExtension"; 76 | opcodes[11] = "OpExtInstImport"; 77 | opcodes[12] = "OpExtInst"; 78 | opcodes[14] = "OpMemoryModel"; 79 | opcodes[15] = "OpEntryPoint"; 80 | opcodes[16] = "OpExecutionMode"; 81 | opcodes[17] = "OpCapability"; 82 | opcodes[19] = "OpTypeVoid"; 83 | opcodes[20] = "OpTypeBool"; 84 | opcodes[21] = "OpTypeInt"; 85 | opcodes[22] = "OpTypeFloat"; 86 | opcodes[23] = "OpTypeVector"; 87 | opcodes[24] = "OpTypeMatrix"; 88 | opcodes[25] = "OpTypeImage"; 89 | opcodes[26] = "OpTypeSampler"; 90 | opcodes[27] = "OpTypeSampledImage"; 91 | opcodes[28] = "OpTypeArray"; 92 | opcodes[29] = "OpTypeRuntimeArray"; 93 | opcodes[30] = "OpTypeStruct"; 94 | opcodes[31] = "OpTypeOpaque"; 95 | opcodes[32] = "OpTypePointer"; 96 | opcodes[33] = "OpTypeFunction"; 97 | opcodes[34] = "OpTypeEvent"; 98 | opcodes[35] = "OpTypeDeviceEvent"; 99 | opcodes[36] = "OpTypeReserveId"; 100 | opcodes[37] = "OpTypeQueue"; 101 | opcodes[38] = "OpTypePipe"; 102 | opcodes[39] = "OpTypeForwardPointer"; 103 | opcodes[41] = "OpConstantTrue"; 104 | opcodes[42] = "OpConstantFalse"; 105 | opcodes[43] = "OpConstant"; 106 | opcodes[44] = "OpConstantComposite"; 107 | opcodes[45] = "OpConstantSampler"; 108 | opcodes[46] = "OpConstantNull"; 109 | opcodes[48] = "OpSpecConstantTrue"; 110 | opcodes[49] = "OpSpecConstantFalse"; 111 | opcodes[50] = "OpSpecConstant"; 112 | opcodes[51] = "OpSpecConstantComposite"; 113 | opcodes[52] = "OpSpecConstantOp"; 114 | opcodes[54] = "OpFunction"; 115 | opcodes[55] = "OpFunctionParameter"; 116 | opcodes[56] = "OpFunctionEnd"; 117 | opcodes[57] = "OpFunctionCall"; 118 | opcodes[59] = "OpVariable"; 119 | opcodes[60] = "OpImageTexelPointer"; 120 | opcodes[61] = "OpLoad"; 121 | opcodes[62] = "OpStore"; 122 | opcodes[63] = "OpCopyMemory"; 123 | opcodes[64] = "OpCopyMemorySized"; 124 | opcodes[65] = "OpAccessChain"; 125 | opcodes[66] = "OpInBoundsAccessChain"; 126 | opcodes[67] = "OpPtrAccessChain"; 127 | opcodes[68] = "OpArrayLength"; 128 | opcodes[69] = "OpGenericPtrMemSemantics"; 129 | opcodes[70] = "OpInBoundsPtrAccessChain"; 130 | opcodes[71] = "OpDecorate"; 131 | opcodes[72] = "OpMemberDecorate"; 132 | opcodes[73] = "OpDecorationGroup"; 133 | opcodes[74] = "OpGroupDecorate"; 134 | opcodes[75] = "OpGroupMemberDecorate"; 135 | opcodes[77] = "OpVectorExtractDynamic"; 136 | opcodes[78] = "OpVectorInsertDynamic"; 137 | opcodes[79] = "OpVectorShuffle"; 138 | opcodes[80] = "OpCompositeConstruct"; 139 | opcodes[81] = "OpCompositeExtract"; 140 | opcodes[82] = "OpCompositeInsert"; 141 | opcodes[83] = "OpCopyObject"; 142 | opcodes[84] = "OpTranspose"; 143 | opcodes[86] = "OpSampledImage"; 144 | opcodes[87] = "OpImageSampleImplicitLod"; 145 | opcodes[88] = "OpImageSampleExplicitLod"; 146 | opcodes[89] = "OpImageSampleDrefImplicitLod"; 147 | opcodes[90] = "OpImageSampleDrefExplicitLod"; 148 | opcodes[91] = "OpImageSampleProjImplicitLod"; 149 | opcodes[92] = "OpImageSampleProjExplicitLod"; 150 | opcodes[93] = "OpImageSampleProjDrefImplicitLod"; 151 | opcodes[94] = "OpImageSampleProjDrefExplicitLod"; 152 | opcodes[95] = "OpImageFetch"; 153 | opcodes[96] = "OpImageGather"; 154 | opcodes[97] = "OpImageDrefGather"; 155 | opcodes[98] = "OpImageRead"; 156 | opcodes[99] = "OpImageWrite"; 157 | opcodes[100] = "OpImage"; 158 | opcodes[101] = "OpImageQueryFormat"; 159 | opcodes[102] = "OpImageQueryOrder"; 160 | opcodes[103] = "OpImageQuerySizeLod"; 161 | opcodes[104] = "OpImageQuerySize"; 162 | opcodes[105] = "OpImageQueryLod"; 163 | opcodes[106] = "OpImageQueryLevels"; 164 | opcodes[107] = "OpImageQuerySamples"; 165 | opcodes[109] = "OpConvertFToU"; 166 | opcodes[110] = "OpConvertFToS"; 167 | opcodes[111] = "OpConvertSToF"; 168 | opcodes[112] = "OpConvertUToF"; 169 | opcodes[113] = "OpUConvert"; 170 | opcodes[114] = "OpSConvert"; 171 | opcodes[115] = "OpFConvert"; 172 | opcodes[116] = "OpQuantizeToF16"; 173 | opcodes[117] = "OpConvertPtrToU"; 174 | opcodes[118] = "OpSatConvertSToU"; 175 | opcodes[119] = "OpSatConvertUToS"; 176 | opcodes[120] = "OpConvertUToPtr"; 177 | opcodes[121] = "OpPtrCastToGeneric"; 178 | opcodes[122] = "OpGenericCastToPtr"; 179 | opcodes[123] = "OpGenericCastToPtrExplicit"; 180 | opcodes[124] = "OpBitcast"; 181 | opcodes[126] = "OpSNegate"; 182 | opcodes[127] = "OpFNegate"; 183 | opcodes[128] = "OpIAdd"; 184 | opcodes[129] = "OpFAdd"; 185 | opcodes[130] = "OpISub"; 186 | opcodes[131] = "OpFSub"; 187 | opcodes[132] = "OpIMul"; 188 | opcodes[133] = "OpFMul"; 189 | opcodes[134] = "OpUDiv"; 190 | opcodes[135] = "OpSDiv"; 191 | opcodes[136] = "OpFDiv"; 192 | opcodes[137] = "OpUMod"; 193 | opcodes[138] = "OpSRem"; 194 | opcodes[139] = "OpSMod"; 195 | opcodes[140] = "OpFRem"; 196 | opcodes[141] = "OpFMod"; 197 | opcodes[142] = "OpVectorTimesScalar"; 198 | opcodes[143] = "OpMatrixTimesScalar"; 199 | opcodes[144] = "OpVectorTimesMatrix"; 200 | opcodes[145] = "OpMatrixTimesVector"; 201 | opcodes[146] = "OpMatrixTimesMatrix"; 202 | opcodes[147] = "OpOuterProduct"; 203 | opcodes[148] = "OpDot"; 204 | opcodes[149] = "OpIAddCarry"; 205 | opcodes[150] = "OpISubBorrow"; 206 | opcodes[151] = "OpUMulExtended"; 207 | opcodes[152] = "OpSMulExtended"; 208 | opcodes[154] = "OpAny"; 209 | opcodes[155] = "OpAll"; 210 | opcodes[156] = "OpIsNan"; 211 | opcodes[157] = "OpIsInf"; 212 | opcodes[158] = "OpIsFinite"; 213 | opcodes[159] = "OpIsNormal"; 214 | opcodes[160] = "OpSignBitSet"; 215 | opcodes[161] = "OpLessOrGreater"; 216 | opcodes[162] = "OpOrdered"; 217 | opcodes[163] = "OpUnordered"; 218 | opcodes[164] = "OpLogicalEqual"; 219 | opcodes[165] = "OpLogicalNotEqual"; 220 | opcodes[166] = "OpLogicalOr"; 221 | opcodes[167] = "OpLogicalAnd"; 222 | opcodes[168] = "OpLogicalNot"; 223 | opcodes[169] = "OpSelect"; 224 | opcodes[170] = "OpIEqual"; 225 | opcodes[171] = "OpINotEqual"; 226 | opcodes[172] = "OpUGreaterThan"; 227 | opcodes[173] = "OpSGreaterThan"; 228 | opcodes[174] = "OpUGreaterThanEqual"; 229 | opcodes[175] = "OpSGreaterThanEqual"; 230 | opcodes[176] = "OpULessThan"; 231 | opcodes[177] = "OpSLessThan"; 232 | opcodes[178] = "OpULessThanEqual"; 233 | opcodes[179] = "OpSLessThanEqual"; 234 | opcodes[180] = "OpFOrdEqual"; 235 | opcodes[181] = "OpFUnordEqual"; 236 | opcodes[182] = "OpFOrdNotEqual"; 237 | opcodes[183] = "OpFUnordNotEqual"; 238 | opcodes[184] = "OpFOrdLessThan"; 239 | opcodes[185] = "OpFUnordLessThan"; 240 | opcodes[186] = "OpFOrdGreaterThan"; 241 | opcodes[187] = "OpFUnordGreaterThan"; 242 | opcodes[188] = "OpFOrdLessThanEqual"; 243 | opcodes[189] = "OpFUnordLessThanEqual"; 244 | opcodes[190] = "OpFOrdGreaterThanEqual"; 245 | opcodes[191] = "OpFUnordGreaterThanEqual"; 246 | opcodes[194] = "OpShiftRightLogical"; 247 | opcodes[195] = "OpShiftRightArithmetic"; 248 | opcodes[196] = "OpShiftLeftLogical"; 249 | opcodes[197] = "OpBitwiseOr"; 250 | opcodes[198] = "OpBitwiseXor"; 251 | opcodes[199] = "OpBitwiseAnd"; 252 | opcodes[200] = "OpNot"; 253 | opcodes[201] = "OpBitFieldInsert"; 254 | opcodes[202] = "OpBitFieldSExtract"; 255 | opcodes[203] = "OpBitFieldUExtract"; 256 | opcodes[204] = "OpBitReverse"; 257 | opcodes[205] = "OpBitCount"; 258 | opcodes[207] = "OpDPdx"; 259 | opcodes[208] = "OpDPdy"; 260 | opcodes[209] = "OpFwidth"; 261 | opcodes[210] = "OpDPdxFine"; 262 | opcodes[211] = "OpDPdyFine"; 263 | opcodes[212] = "OpFwidthFine"; 264 | opcodes[213] = "OpDPdxCoarse"; 265 | opcodes[214] = "OpDPdyCoarse"; 266 | opcodes[215] = "OpFwidthCoarse"; 267 | opcodes[218] = "OpEmitVertex"; 268 | opcodes[219] = "OpEndPrimitive"; 269 | opcodes[220] = "OpEmitStreamVertex"; 270 | opcodes[221] = "OpEndStreamPrimitive"; 271 | opcodes[224] = "OpControlBarrier"; 272 | opcodes[225] = "OpMemoryBarrier"; 273 | opcodes[227] = "OpAtomicLoad"; 274 | opcodes[228] = "OpAtomicStore"; 275 | opcodes[229] = "OpAtomicExchange"; 276 | opcodes[230] = "OpAtomicCompareExchange"; 277 | opcodes[231] = "OpAtomicCompareExchangeWeak"; 278 | opcodes[232] = "OpAtomicIIncrement"; 279 | opcodes[233] = "OpAtomicIDecrement"; 280 | opcodes[234] = "OpAtomicIAdd"; 281 | opcodes[235] = "OpAtomicISub"; 282 | opcodes[236] = "OpAtomicSMin"; 283 | opcodes[237] = "OpAtomicUMin"; 284 | opcodes[238] = "OpAtomicSMax"; 285 | opcodes[239] = "OpAtomicUMax"; 286 | opcodes[240] = "OpAtomicAnd"; 287 | opcodes[241] = "OpAtomicOr"; 288 | opcodes[242] = "OpAtomicXor"; 289 | opcodes[245] = "OpPhi"; 290 | opcodes[246] = "OpLoopMerge"; 291 | opcodes[247] = "OpSelectionMerge"; 292 | opcodes[248] = "OpLabel"; 293 | opcodes[249] = "OpBranch"; 294 | opcodes[250] = "OpBranchConditional"; 295 | opcodes[251] = "OpSwitch"; 296 | opcodes[252] = "OpKill"; 297 | opcodes[253] = "OpReturn"; 298 | opcodes[254] = "OpReturnValue"; 299 | opcodes[255] = "OpUnreachable"; 300 | opcodes[256] = "OpLifetimeStart"; 301 | opcodes[257] = "OpLifetimeStop"; 302 | opcodes[259] = "OpGroupAsyncCopy"; 303 | opcodes[260] = "OpGroupWaitEvents"; 304 | opcodes[261] = "OpGroupAll"; 305 | opcodes[262] = "OpGroupAny"; 306 | opcodes[263] = "OpGroupBroadcast"; 307 | opcodes[264] = "OpGroupIAdd"; 308 | opcodes[265] = "OpGroupFAdd"; 309 | opcodes[266] = "OpGroupFMin"; 310 | opcodes[267] = "OpGroupUMin"; 311 | opcodes[268] = "OpGroupSMin"; 312 | opcodes[269] = "OpGroupFMax"; 313 | opcodes[270] = "OpGroupUMax"; 314 | opcodes[271] = "OpGroupSMax"; 315 | opcodes[274] = "OpReadPipe"; 316 | opcodes[275] = "OpWritePipe"; 317 | opcodes[276] = "OpReservedReadPipe"; 318 | opcodes[277] = "OpReservedWritePipe"; 319 | opcodes[278] = "OpReserveReadPipePackets"; 320 | opcodes[279] = "OpReserveWritePipePackets"; 321 | opcodes[280] = "OpCommitReadPipe"; 322 | opcodes[281] = "OpCommitWritePipe"; 323 | opcodes[282] = "OpIsValidReserveId"; 324 | opcodes[283] = "OpGetNumPipePackets"; 325 | opcodes[284] = "OpGetMaxPipePackets"; 326 | opcodes[285] = "OpGroupReserveReadPipePackets"; 327 | opcodes[286] = "OpGroupReserveWritePipePackets"; 328 | opcodes[287] = "OpGroupCommitReadPipe"; 329 | opcodes[288] = "OpGroupCommitWritePipe"; 330 | opcodes[291] = "OpEnqueueMarker"; 331 | opcodes[292] = "OpEnqueueKernel"; 332 | opcodes[293] = "OpGetKernelNDrangeSubGroupCount"; 333 | opcodes[294] = "OpGetKernelNDrangeMaxSubGroupSize"; 334 | opcodes[295] = "OpGetKernelWorkGroupSize"; 335 | opcodes[296] = "OpGetKernelPreferredWorkGroupSizeMultiple"; 336 | opcodes[297] = "OpRetainEvent"; 337 | opcodes[298] = "OpReleaseEvent"; 338 | opcodes[299] = "OpCreateUserEvent"; 339 | opcodes[300] = "OpIsValidEvent"; 340 | opcodes[301] = "OpSetUserEventStatus"; 341 | opcodes[302] = "OpCaptureEventProfilingInfo"; 342 | opcodes[303] = "OpGetDefaultQueue"; 343 | opcodes[304] = "OpBuildNDRange"; 344 | opcodes[305] = "OpImageSparseSampleImplicitLod"; 345 | opcodes[306] = "OpImageSparseSampleExplicitLod"; 346 | opcodes[307] = "OpImageSparseSampleDrefImplicitLod"; 347 | opcodes[308] = "OpImageSparseSampleDrefExplicitLod"; 348 | opcodes[309] = "OpImageSparseSampleProjImplicitLod"; 349 | opcodes[310] = "OpImageSparseSampleProjExplicitLod"; 350 | opcodes[311] = "OpImageSparseSampleProjDrefImplicitLod"; 351 | opcodes[312] = "OpImageSparseSampleProjDrefExplicitLod"; 352 | opcodes[313] = "OpImageSparseFetch"; 353 | opcodes[314] = "OpImageSparseGather"; 354 | opcodes[315] = "OpImageSparseDrefGather"; 355 | opcodes[316] = "OpImageSparseTexelsResident"; 356 | opcodes[317] = "OpNoLine"; 357 | opcodes[318] = "OpAtomicFlagTestAndSet"; 358 | opcodes[319] = "OpAtomicFlagClear"; 359 | opcodes[320] = "OpImageSparseRead"; 360 | opcodes[4421] = "OpSubgroupBallotKHR"; 361 | opcodes[4422] = "OpSubgroupFirstInvocationKHR"; 362 | 363 | std::map > hits; 364 | uint64_t totalHits = 0; 365 | uint64_t totalBytes = 0; 366 | 367 | uint64_t loadsWithMemoryAccess = 0; 368 | uint64_t storesWithMemoryAccess = 0; 369 | uint64_t decorateWithLiteral = 0; 370 | uint64_t decorateWithTwoOrMoreLiterals = 0; 371 | const unsigned decorationMax = 45; 372 | uint64_t decorationUsed[decorationMax] = {0}; 373 | uint64_t memberDecorateWithLiteral = 0; 374 | uint64_t memberDecorateWithTwoOrMoreLiterals = 0; 375 | const unsigned memberDecorationMax = 45; 376 | uint64_t memberDecorationUsed[memberDecorationMax] = {0}; 377 | const unsigned accessChainMax = 6; 378 | uint64_t accessChainNumIndices[accessChainMax] = {0}; 379 | uint64_t variableHasInitializer = 0; 380 | uint64_t constantHasTwoOrMoreLiterals = 0; 381 | const unsigned vectorShuffleMax = 6; 382 | uint64_t vectorShuffleNumLiterals[vectorShuffleMax] = {0}; 383 | uint64_t vectorShuffleHasUndefLiteral = 0; 384 | uint64_t vectorShuffleHasAllLiteralsLessThan4 = 0; 385 | uint64_t vectorShuffleHasAllLiteralsLessThan8 = 0; 386 | uint64_t vectorShuffleUsesTheSameVectorTwice = 0; 387 | const unsigned compositeConstructMax = 6; 388 | uint64_t compositeConstructNumLiterals[compositeConstructMax] = {0}; 389 | const unsigned compositeExtractMax = 4; 390 | uint64_t compositeExtractNumLiterals[compositeExtractMax] = {0}; 391 | const unsigned compositeExtractFirstLiteralMax = 5; 392 | uint64_t compositeExtractFirstLiteral[compositeExtractFirstLiteralMax] = {0}; 393 | 394 | for (int i = 1; i < argc; i++) { 395 | FILE *file = fopen(argv[i], "rb"); 396 | 397 | if (0 == file) { 398 | fprintf(stderr, "Error: couldn't open input file '%s' for reading!\n", 399 | argv[i]); 400 | return 1; 401 | } 402 | 403 | uint32_t header[numWordsInHeader]; 404 | 405 | if (numWordsInHeader != 406 | fread(header, sizeof(uint32_t), numWordsInHeader, file)) { 407 | fprintf(stderr, "Error: SPIR-V input file was too short to be valid!\n"); 408 | return 1; 409 | } 410 | 411 | // the header is part of the total bytes we record 412 | totalBytes += sizeof(uint32_t) * numWordsInHeader; 413 | 414 | if ((magicNumber != header[0]) && (reserveMagicNumber != header[0])) { 415 | fprintf( 416 | stderr, 417 | "Error: magic number identifying file as SPIR-V was incorrect!\n"); 418 | return 1; 419 | } 420 | 421 | const bool wrongEndian = reserveMagicNumber == header[0]; 422 | 423 | uint32_t word; 424 | while (1 == fread(&word, sizeof(word), 1, file)) { 425 | if (wrongEndian) { 426 | word = (0x000000ffu & (word >> 24)) | (0x0000ff00u & (word >> 8)) | 427 | (0x00ff0000u & (word << 8)) | (0xff000000u & (word << 24)); 428 | } 429 | const uint32_t wordCount = word >> 16; 430 | const uint32_t opcode = word & 0xFFFFu; 431 | 432 | switch (opcode) { 433 | default: 434 | break; 435 | case opLoad: 436 | if (5 == wordCount) { 437 | loadsWithMemoryAccess++; 438 | } 439 | break; 440 | case opStore: 441 | if (4 == wordCount) { 442 | storesWithMemoryAccess++; 443 | } 444 | break; 445 | case opDecorate: 446 | if (4 == wordCount) { 447 | decorateWithLiteral++; 448 | } else if (4 < wordCount) { 449 | decorateWithTwoOrMoreLiterals++; 450 | } 451 | break; 452 | case opMemberDecorate: 453 | if (5 == wordCount) { 454 | memberDecorateWithLiteral++; 455 | } else if (5 < wordCount) { 456 | memberDecorateWithTwoOrMoreLiterals++; 457 | } 458 | break; 459 | case opAccessChain: 460 | accessChainNumIndices[(wordCount - 4) < accessChainMax 461 | ? wordCount - 4 462 | : accessChainMax - 1]++; 463 | break; 464 | case opVariable: 465 | if (5 == wordCount) { 466 | variableHasInitializer++; 467 | } 468 | break; 469 | case opConstant: 470 | if (4 < wordCount) { 471 | constantHasTwoOrMoreLiterals++; 472 | } 473 | break; 474 | case opVectorShuffle: 475 | vectorShuffleNumLiterals[(wordCount - 5) < vectorShuffleMax 476 | ? wordCount - 5 477 | : vectorShuffleMax - 1]++; 478 | break; 479 | case opCompositeConstruct: 480 | compositeConstructNumLiterals[(wordCount - 4) < compositeConstructMax 481 | ? wordCount - 4 482 | : compositeConstructMax - 1]++; 483 | break; 484 | case opCompositeExtract: 485 | compositeExtractNumLiterals[(wordCount - 4) < compositeExtractMax 486 | ? wordCount - 4 487 | : compositeExtractMax - 1]++; 488 | break; 489 | } 490 | 491 | hits[opcode].first++; 492 | hits[opcode].second += sizeof(uint32_t) * wordCount; 493 | 494 | totalHits++; 495 | totalBytes += sizeof(uint32_t) * wordCount; 496 | 497 | switch (opcode) { 498 | default: 499 | // skip the remaining words in the opcode 500 | fseek(file, static_cast(sizeof(uint32_t) * (wordCount - 1)), 501 | SEEK_CUR); 502 | break; 503 | case opVectorShuffle: { 504 | // skip the start of the opcode 505 | 506 | fseek(file, static_cast(sizeof(uint32_t) * 2), SEEK_CUR); 507 | 508 | if (1 != fread(&word, sizeof(word), 1, file)) { 509 | fprintf(stderr, "fread failed!\n"); 510 | return 1; 511 | } 512 | const uint32_t temp = word; 513 | if (1 != fread(&word, sizeof(word), 1, file)) { 514 | fprintf(stderr, "fread failed!\n"); 515 | return 1; 516 | } 517 | 518 | if (temp == word) { 519 | vectorShuffleUsesTheSameVectorTwice++; 520 | } 521 | 522 | bool aLiteralIsUndef = false; 523 | bool aLiteralIsGreaterThanOrEqualTo4 = false; 524 | bool aLiteralIsGreaterThanOrEqualTo8 = false; 525 | for (uint32_t k = 5; k < wordCount; k++) { 526 | if (1 != fread(&word, sizeof(word), 1, file)) { 527 | fprintf(stderr, "fread failed!\n"); 528 | return 1; 529 | } 530 | 531 | aLiteralIsUndef |= (0xFFFFFFFFu == word); 532 | aLiteralIsGreaterThanOrEqualTo4 |= 4 <= word; 533 | aLiteralIsGreaterThanOrEqualTo8 |= 8 <= word; 534 | } 535 | 536 | if (aLiteralIsUndef) { 537 | vectorShuffleHasUndefLiteral++; 538 | } 539 | 540 | if (!aLiteralIsGreaterThanOrEqualTo4) { 541 | vectorShuffleHasAllLiteralsLessThan4++; 542 | } else if (!aLiteralIsGreaterThanOrEqualTo8) { 543 | vectorShuffleHasAllLiteralsLessThan8++; 544 | } 545 | } break; 546 | case opCompositeExtract: 547 | // skip the start of the opcode 548 | 549 | fseek(file, static_cast(sizeof(uint32_t) * 3), SEEK_CUR); 550 | if (5 == wordCount) { 551 | if (1 != fread(&word, sizeof(word), 1, file)) { 552 | fprintf(stderr, "fread failed!\n"); 553 | return 1; 554 | } 555 | 556 | if (word < compositeExtractFirstLiteralMax) { 557 | compositeExtractFirstLiteral[word]++; 558 | } 559 | } else { 560 | // skip the rest of the opcode 561 | fseek(file, static_cast(sizeof(uint32_t) * (wordCount - 4)), 562 | SEEK_CUR); 563 | } 564 | break; 565 | case opDecorate: 566 | fseek(file, static_cast(sizeof(uint32_t) * 1), SEEK_CUR); 567 | if (1 != fread(&word, sizeof(word), 1, file)) { 568 | fprintf(stderr, "fread failed!\n"); 569 | return 1; 570 | } 571 | 572 | if (word < decorationMax) { 573 | decorationUsed[word]++; 574 | } 575 | 576 | fseek(file, static_cast(sizeof(uint32_t) * (wordCount - 3)), 577 | SEEK_CUR); 578 | break; 579 | case opMemberDecorate: 580 | fseek(file, static_cast(sizeof(uint32_t) * 2), SEEK_CUR); 581 | if (1 != fread(&word, sizeof(word), 1, file)) { 582 | fprintf(stderr, "fread failed!\n"); 583 | return 1; 584 | } 585 | 586 | if (word < memberDecorationMax) { 587 | memberDecorationUsed[word]++; 588 | } 589 | 590 | fseek(file, static_cast(sizeof(uint32_t) * (wordCount - 4)), 591 | SEEK_CUR); 592 | break; 593 | } 594 | } 595 | 596 | fclose(file); 597 | } 598 | 599 | typedef std::pair > MapPair; 600 | 601 | std::vector hitsVector(hits.begin(), hits.end()); 602 | 603 | struct Helper { 604 | static bool _(MapPair a, MapPair b) { 605 | return a.second.first > b.second.first; 606 | } 607 | }; 608 | 609 | std::sort(hitsVector.begin(), hitsVector.end(), Helper::_); 610 | 611 | printf("Totals: %llu hits %llu bytes\n", 612 | static_cast(totalHits), 613 | static_cast(totalBytes)); 614 | 615 | for (std::vector::iterator i = hitsVector.begin(), 616 | i_e = hitsVector.end(); 617 | i != i_e; ++i) { 618 | printf("%30s[%3u] = %6llu hits (%5.2f%%) %6llu bytes (%5.2f%%)\n", 619 | opcodes.at(i->first), i->first, 620 | static_cast(i->second.first), 621 | static_cast(i->second.first) / totalHits * 100.0, 622 | static_cast(i->second.second), 623 | static_cast(i->second.second) / totalBytes * 100.0); 624 | 625 | switch (i->first) { 626 | default: 627 | break; 628 | case opStore: 629 | printf("%30s %6llu hits with memory access %5.2f%%\n", "", 630 | static_cast(storesWithMemoryAccess), 631 | static_cast(storesWithMemoryAccess) / i->second.first * 632 | 100.0); 633 | break; 634 | case opLoad: 635 | printf("%30s %6llu hits with memory access %5.2f%%\n", "", 636 | static_cast(loadsWithMemoryAccess), 637 | static_cast(loadsWithMemoryAccess) / i->second.first * 638 | 100.0); 639 | break; 640 | case opDecorate: 641 | printf("%30s %6llu hits with no literals %5.2f%%\n", "", 642 | static_cast(i->second.first - 643 | decorateWithLiteral - 644 | decorateWithTwoOrMoreLiterals), 645 | static_cast(i->second.first - decorateWithLiteral - 646 | decorateWithTwoOrMoreLiterals) / 647 | i->second.first * 100.0); 648 | printf("%30s %6llu hits with 1 literal %5.2f%%\n", "", 649 | static_cast(decorateWithLiteral), 650 | static_cast(decorateWithLiteral) / i->second.first * 651 | 100.0); 652 | printf("%30s %6llu hits with 2+ literals %5.2f%%\n", "", 653 | static_cast(decorateWithTwoOrMoreLiterals), 654 | static_cast(decorateWithTwoOrMoreLiterals) / 655 | i->second.first * 100.0); 656 | 657 | printf("%32s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", ""); 658 | for (unsigned k = 0; k < decorationMax; k++) { 659 | if (0 < decorationUsed[k]) { 660 | printf("%30s %6llu hits of decoration %2u %5.2f%%\n", "", 661 | static_cast(decorationUsed[k]), k, 662 | static_cast(decorationUsed[k]) / i->second.first * 663 | 100.0); 664 | } 665 | } 666 | break; 667 | case opMemberDecorate: 668 | printf("%30s %6llu hits with no literals %5.2f%%\n", "", 669 | static_cast( 670 | i->second.first - memberDecorateWithLiteral - 671 | memberDecorateWithTwoOrMoreLiterals), 672 | static_cast(i->second.first - memberDecorateWithLiteral - 673 | memberDecorateWithTwoOrMoreLiterals) / 674 | i->second.first * 100.0); 675 | printf("%30s %6llu hits with 1 literal %5.2f%%\n", "", 676 | static_cast(memberDecorateWithLiteral), 677 | static_cast(memberDecorateWithLiteral) / i->second.first * 678 | 100.0); 679 | printf( 680 | "%30s %6llu hits with 2+ literals %5.2f%%\n", "", 681 | static_cast(memberDecorateWithTwoOrMoreLiterals), 682 | static_cast(memberDecorateWithTwoOrMoreLiterals) / 683 | i->second.first * 100.0); 684 | 685 | printf("%32s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", ""); 686 | for (unsigned k = 0; k < memberDecorationMax; k++) { 687 | if (0 < memberDecorationUsed[k]) { 688 | printf("%30s %6llu hits of decoration %2u %5.2f%%\n", "", 689 | static_cast(memberDecorationUsed[k]), k, 690 | static_cast(memberDecorationUsed[k]) / 691 | i->second.first * 100.0); 692 | } 693 | } 694 | break; 695 | case opAccessChain: 696 | for (unsigned k = 0; k < accessChainMax - 1; k++) { 697 | printf("%30s %6llu hits with %u %s %5.2f%%\n", "", 698 | static_cast(accessChainNumIndices[k]), k, 699 | (k == 1) ? "index " : "indices", 700 | static_cast(accessChainNumIndices[k]) / i->second.first * 701 | 100.0); 702 | } 703 | printf("%30s %6llu hits with %u+ indices %5.2f%%\n", "", 704 | static_cast( 705 | accessChainNumIndices[accessChainMax - 1]), 706 | accessChainMax - 1, 707 | static_cast(accessChainNumIndices[accessChainMax - 1]) / 708 | i->second.first * 100.0); 709 | break; 710 | case opVariable: 711 | printf("%30s %6llu hits with initializer %5.2f%%\n", "", 712 | static_cast(variableHasInitializer), 713 | static_cast(variableHasInitializer) / i->second.first * 714 | 100.0); 715 | break; 716 | case opConstant: 717 | printf( 718 | "%30s %6llu hits have 1 literal %6.2f%%\n", "", 719 | static_cast(i->second.first - 720 | constantHasTwoOrMoreLiterals), 721 | static_cast(i->second.first - constantHasTwoOrMoreLiterals) / 722 | i->second.first * 100.0); 723 | printf("%30s %6llu hits have 2+ literals %6.2f%%\n", "", 724 | static_cast(constantHasTwoOrMoreLiterals), 725 | static_cast(constantHasTwoOrMoreLiterals) / 726 | i->second.first * 100.0); 727 | break; 728 | case opVectorShuffle: 729 | for (unsigned k = 0; k < vectorShuffleMax - 1; k++) { 730 | printf("%30s %6llu hits with %u %s %5.2f%%\n", "", 731 | static_cast(vectorShuffleNumLiterals[k]), k, 732 | (k == 1) ? "literal " : "literals", 733 | static_cast(vectorShuffleNumLiterals[k]) / 734 | i->second.first * 100.0); 735 | } 736 | printf( 737 | "%30s %6llu hits with %u+ literals %5.2f%%\n", "", 738 | static_cast( 739 | vectorShuffleNumLiterals[vectorShuffleMax - 1]), 740 | vectorShuffleMax - 1, 741 | static_cast(vectorShuffleNumLiterals[vectorShuffleMax - 1]) / 742 | i->second.first * 100.0); 743 | printf("%32s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", ""); 744 | printf("%30s %6llu hits with undef literal%6.2f%%\n", "", 745 | static_cast(vectorShuffleHasUndefLiteral), 746 | static_cast(vectorShuffleHasUndefLiteral) / 747 | i->second.first * 100.0); 748 | printf( 749 | "%30s %6llu hits with literals < 4 %6.2f%%\n", "", 750 | static_cast(vectorShuffleHasAllLiteralsLessThan4), 751 | static_cast(vectorShuffleHasAllLiteralsLessThan4) / 752 | i->second.first * 100.0); 753 | printf( 754 | "%30s %6llu hits with literals < 8 %6.2f%%\n", "", 755 | static_cast(vectorShuffleHasAllLiteralsLessThan8), 756 | static_cast(vectorShuffleHasAllLiteralsLessThan8) / 757 | i->second.first * 100.0); 758 | printf("%32s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", ""); 759 | printf( 760 | "%30s %6llu hits with same vector %6.2f%%\n", "", 761 | static_cast(vectorShuffleUsesTheSameVectorTwice), 762 | static_cast(vectorShuffleUsesTheSameVectorTwice) / 763 | i->second.first * 100.0); 764 | break; 765 | case opCompositeConstruct: 766 | for (unsigned k = 0; k < compositeConstructMax - 1; k++) { 767 | printf( 768 | "%30s %6llu hits with %u %s %5.2f%%\n", "", 769 | static_cast(compositeConstructNumLiterals[k]), 770 | k, (k == 1) ? "literal " : "literals", 771 | static_cast(compositeConstructNumLiterals[k]) / 772 | i->second.first * 100.0); 773 | } 774 | printf("%30s %6llu hits with %u+ literals %5.2f%%\n", "", 775 | static_cast( 776 | compositeConstructNumLiterals[compositeConstructMax - 1]), 777 | compositeConstructMax - 1, 778 | static_cast( 779 | vectorShuffleNumLiterals[compositeConstructMax - 1]) / 780 | i->second.first * 100.0); 781 | break; 782 | case opCompositeExtract: 783 | for (unsigned k = 0; k < compositeExtractMax - 1; k++) { 784 | printf("%30s %6llu hits with %u %s %5.2f%%\n", "", 785 | static_cast(compositeExtractNumLiterals[k]), 786 | k, (k == 1) ? "literal " : "literals", 787 | static_cast(compositeExtractNumLiterals[k]) / 788 | i->second.first * 100.0); 789 | } 790 | printf("%30s %6llu hits with %u+ literals %5.2f%%\n", "", 791 | static_cast( 792 | compositeExtractNumLiterals[compositeExtractMax - 1]), 793 | compositeExtractMax - 1, 794 | static_cast( 795 | vectorShuffleNumLiterals[compositeExtractMax - 1]) / 796 | i->second.first * 100.0); 797 | printf("%32s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", ""); 798 | for (unsigned k = 0; k < compositeExtractFirstLiteralMax; k++) { 799 | printf("%30s %6llu hits with literal = %2u %6.2f%%\n", "", 800 | static_cast(compositeExtractFirstLiteral[k]), 801 | k, static_cast(compositeExtractFirstLiteral[k]) / 802 | i->second.first * 100.0); 803 | } 804 | break; 805 | } 806 | } 807 | } 808 | --------------------------------------------------------------------------------