| 438 | } |
| 439 | |
| 440 | std::unordered_map<instruction_ref, std::unordered_set<instruction_ref>> |
| 441 | get_conflicts(module& m) |
| 442 | { |
| 443 | |
| 444 | using conflict_table_type = |
| 445 | std::unordered_map<instruction_ref, std::unordered_set<instruction_ref>>; |
| 446 | conflict_table_type conflict_table; |
| 447 | auto concur_ins = this->find_concurrent_instructions(m); |
| 448 | |
| 449 | // Compute an index for each instruction |
| 450 | std::unordered_map<instruction_ref, std::size_t> ins2index; |
| 451 | std::size_t index_total = 0; |
| 452 | for(auto ins : iterator_for(m)) |
| 453 | ins2index[ins] = index_total++; |
| 454 | |
| 455 | std::vector<conflict_table_type> thread_conflict_tables( |
| 456 | std::thread::hardware_concurrency()); |
| 457 | std::vector<instruction_ref> index_to_ins; |
| 458 | index_to_ins.reserve(concur_ins.size()); |
| 459 | std::transform(concur_ins.begin(), |
| 460 | concur_ins.end(), |
| 461 | std::back_inserter(index_to_ins), |
| 462 | [](auto&& it) { return it.first; }); |
| 463 | |
| 464 | simple_par_for(concur_ins.size(), [&](auto ins_index, auto tid) { |
| 465 | auto merge_first = index_to_ins[ins_index]; |
| 466 | assert(concur_ins.count(merge_first) > 0); |
| 467 | auto& merge_second = concur_ins.at(merge_first); |
| 468 | |
| 469 | // ensure there are enough elements for different threads |
| 470 | assert(tid < thread_conflict_tables.size()); |
| 471 | auto& thrd_table = thread_conflict_tables.at(tid); |
| 472 | |
| 473 | std::unordered_set<instruction_ref> checked_ins_set; |
| 474 | auto range_i = range(merge_second.begin(), std::prev(merge_second.end())); |
| 475 | for(auto it_i : iterator_for(range_i)) |
| 476 | { |
| 477 | std::unordered_set<instruction_ref> ins1_set; |
| 478 | std::copy_if(it_i->begin(), |
| 479 | it_i->end(), |
| 480 | std::inserter(ins1_set, ins1_set.end()), |
| 481 | [&](auto i) { return not contains(checked_ins_set, i); }); |
| 482 | checked_ins_set.insert(ins1_set.begin(), ins1_set.end()); |
| 483 | |
| 484 | auto range_j = range(std::next(it_i), merge_second.end()); |
| 485 | std::unordered_set<instruction_ref> ins2_set; |
| 486 | for(auto it_j : iterator_for(range_j)) |
| 487 | { |
| 488 | std::copy_if(it_j->begin(), |
| 489 | it_j->end(), |
| 490 | std::inserter(ins2_set, ins2_set.end()), |
| 491 | [&](auto i) { return not contains(checked_ins_set, i); }); |
| 492 | } |
| 493 | |
| 494 | for(auto ins1 : ins1_set) |
| 495 | { |
| 496 | auto p1 = ins2index.at(ins1); |
| 497 | for(auto ins2 : ins2_set) |
no test coverage detected