| 2168 | } |
| 2169 | |
| 2170 | void Differ::MatchEntryPointIds() { |
| 2171 | // Match OpEntryPoint ids (at index 1) by ExecutionModel (at index 0) and |
| 2172 | // possibly name (at index 2). OpEntryPoint doesn't produce a result id, so |
| 2173 | // this function doesn't use the helpers the other functions use. |
| 2174 | |
| 2175 | // Map from execution model to OpEntryPoint instructions of that model. |
| 2176 | using ExecutionModelMap = |
| 2177 | std::unordered_map<uint32_t, std::vector<const opt::Instruction*>>; |
| 2178 | ExecutionModelMap src_entry_points_map; |
| 2179 | ExecutionModelMap dst_entry_points_map; |
| 2180 | std::set<uint32_t> all_execution_models; |
| 2181 | |
| 2182 | for (const opt::Instruction& src_inst : src_->entry_points()) { |
| 2183 | uint32_t execution_model = src_inst.GetSingleWordOperand(0); |
| 2184 | src_entry_points_map[execution_model].push_back(&src_inst); |
| 2185 | all_execution_models.insert(execution_model); |
| 2186 | } |
| 2187 | for (const opt::Instruction& dst_inst : dst_->entry_points()) { |
| 2188 | uint32_t execution_model = dst_inst.GetSingleWordOperand(0); |
| 2189 | dst_entry_points_map[execution_model].push_back(&dst_inst); |
| 2190 | all_execution_models.insert(execution_model); |
| 2191 | } |
| 2192 | |
| 2193 | // Go through each model and match the ids. |
| 2194 | for (const uint32_t execution_model : all_execution_models) { |
| 2195 | auto& src_insts = src_entry_points_map[execution_model]; |
| 2196 | auto& dst_insts = dst_entry_points_map[execution_model]; |
| 2197 | |
| 2198 | // If there is only one entry point in src and dst with that model, match |
| 2199 | // them unconditionally. |
| 2200 | if (src_insts.size() == 1 && dst_insts.size() == 1) { |
| 2201 | uint32_t src_id = src_insts[0]->GetSingleWordOperand(1); |
| 2202 | uint32_t dst_id = dst_insts[0]->GetSingleWordOperand(1); |
| 2203 | id_map_.MapIds(src_id, dst_id); |
| 2204 | id_map_.MapInsts(src_insts[0], dst_insts[0]); |
| 2205 | continue; |
| 2206 | } |
| 2207 | |
| 2208 | // Otherwise match them by name. |
| 2209 | for (const opt::Instruction* src_inst : src_insts) { |
| 2210 | for (const opt::Instruction* dst_inst : dst_insts) { |
| 2211 | if (id_map_.IsDstMapped(dst_inst)) continue; |
| 2212 | |
| 2213 | const opt::Operand& src_name = src_inst->GetOperand(2); |
| 2214 | const opt::Operand& dst_name = dst_inst->GetOperand(2); |
| 2215 | |
| 2216 | if (src_name.AsString() == dst_name.AsString()) { |
| 2217 | uint32_t src_id = src_inst->GetSingleWordOperand(1); |
| 2218 | uint32_t dst_id = dst_inst->GetSingleWordOperand(1); |
| 2219 | id_map_.MapIds(src_id, dst_id); |
| 2220 | id_map_.MapInsts(src_inst, dst_inst); |
| 2221 | break; |
| 2222 | } |
| 2223 | } |
| 2224 | } |
| 2225 | } |
| 2226 | } |
| 2227 |
no test coverage detected