| 472 | } |
| 473 | |
| 474 | static void |
| 475 | rauw_op(const unordered_map<const Value*, |
| 476 | vector<pair<BasicBlock*, Value*>>> &vmap, |
| 477 | const unordered_set<const Value *> &phis_from_orig_bb, |
| 478 | Value *i, Value *op) { |
| 479 | auto it = vmap.find(op); |
| 480 | if (it != vmap.end()) { |
| 481 | // consider this case: |
| 482 | // loop: |
| 483 | // %op = phi ... |
| 484 | // %k = phi [%op, %loop], ... |
| 485 | // |
| 486 | // In iteration i, %k should point to iteration (i-1)'s %k. |
| 487 | // If is_phi_to_phi is true, %op is the phi in this block. |
| 488 | bool is_phi_to_phi = dynamic_cast<const Phi *>(i) && |
| 489 | phis_from_orig_bb.count(op); |
| 490 | if (is_phi_to_phi) { |
| 491 | if (it->second.size() >= 2) { |
| 492 | i->rauw(*op, *it->second[it->second.size()-2].second); |
| 493 | } |
| 494 | } else { |
| 495 | i->rauw(*op, *it->second.back().second); |
| 496 | } |
| 497 | return; |
| 498 | } |
| 499 | |
| 500 | if (auto *agg = dynamic_cast<AggregateValue*>(op)) { |
| 501 | for (auto &v : agg->getVals()) { |
| 502 | rauw_op(vmap, phis_from_orig_bb, op, v); |
| 503 | } |
| 504 | } |
| 505 | } |
| 506 | |
| 507 | static BasicBlock& |
| 508 | cloneBB(Function &F, const BasicBlock &BB, const char *suffix, |
no test coverage detected