| 2302 | } |
| 2303 | |
| 2304 | void Differ::MatchTypeIds() { |
| 2305 | // Bunch all of type ids as potential matches. |
| 2306 | PotentialIdMap potential_id_map; |
| 2307 | auto get_result_id = [](const opt::Instruction& inst) { |
| 2308 | return inst.result_id(); |
| 2309 | }; |
| 2310 | auto accept_type_ops = [](const opt::Instruction& inst) { |
| 2311 | return spvOpcodeGeneratesType(inst.opcode()); |
| 2312 | }; |
| 2313 | |
| 2314 | PoolPotentialIds(src_->types_values(), potential_id_map.src_ids, true, |
| 2315 | accept_type_ops, get_result_id); |
| 2316 | PoolPotentialIds(dst_->types_values(), potential_id_map.dst_ids, false, |
| 2317 | accept_type_ops, get_result_id); |
| 2318 | |
| 2319 | // Then match the ids. Start with exact matches, then match the leftover with |
| 2320 | // gradually loosening degrees of strictness. For example, in the absence of |
| 2321 | // debug info, two block types will be matched if they differ only in a few of |
| 2322 | // the fields. |
| 2323 | for (uint32_t flexibility = 0; flexibility < 2; ++flexibility) { |
| 2324 | MatchIds(potential_id_map, [this, flexibility]( |
| 2325 | const opt::Instruction* src_inst, |
| 2326 | const opt::Instruction* dst_inst) { |
| 2327 | const spv::Op src_op = src_inst->opcode(); |
| 2328 | const spv::Op dst_op = dst_inst->opcode(); |
| 2329 | |
| 2330 | // Don't match if the opcode is not the same. |
| 2331 | if (src_op != dst_op) { |
| 2332 | return false; |
| 2333 | } |
| 2334 | |
| 2335 | switch (src_op) { |
| 2336 | case spv::Op::OpTypeVoid: |
| 2337 | case spv::Op::OpTypeBool: |
| 2338 | case spv::Op::OpTypeSampler: |
| 2339 | case spv::Op::OpTypeAccelerationStructureNV: |
| 2340 | case spv::Op::OpTypeRayQueryKHR: |
| 2341 | // the above types have no operands and are unique, match them. |
| 2342 | return true; |
| 2343 | case spv::Op::OpTypeInt: |
| 2344 | case spv::Op::OpTypeFloat: |
| 2345 | case spv::Op::OpTypeVector: |
| 2346 | case spv::Op::OpTypeMatrix: |
| 2347 | case spv::Op::OpTypeSampledImage: |
| 2348 | case spv::Op::OpTypeRuntimeArray: |
| 2349 | case spv::Op::OpTypePointer: |
| 2350 | // Match these instructions when all operands match. |
| 2351 | assert(src_inst->NumInOperandWords() == |
| 2352 | dst_inst->NumInOperandWords()); |
| 2353 | return DoOperandsMatch(src_inst, dst_inst, 0, |
| 2354 | src_inst->NumInOperandWords()); |
| 2355 | |
| 2356 | case spv::Op::OpTypeFunction: |
| 2357 | case spv::Op::OpTypeImage: |
| 2358 | // Match function types only if they have the same number of operands, |
| 2359 | // and they all match. |
| 2360 | // Match image types similarly, expecting the optional final parameter |
| 2361 | // to match (if provided in both) |
no test coverage detected