| 1727 | } |
| 1728 | |
| 1729 | void Transform::preprocess() { |
| 1730 | if (config::tgt_is_asm) { |
| 1731 | tgt.getFnAttrs().set(FnAttrs::Asm); |
| 1732 | |
| 1733 | // there are no #side-effect things in assembly |
| 1734 | vector<Instr*> to_remove; |
| 1735 | for (auto &bb : src.getBBs()) { |
| 1736 | for (auto &i : bb->instrs()) { |
| 1737 | if (auto *call = dynamic_cast<const FnCall*>(&i)) { |
| 1738 | if (call->getFnName() == "#sideeffect") { |
| 1739 | to_remove.emplace_back(const_cast<Instr*>(&i)); |
| 1740 | } |
| 1741 | } |
| 1742 | } |
| 1743 | for (auto &i : to_remove) { |
| 1744 | bb->delInstr(i); |
| 1745 | } |
| 1746 | to_remove.clear(); |
| 1747 | } |
| 1748 | } |
| 1749 | |
| 1750 | remove_unreachable_bbs(src); |
| 1751 | remove_unreachable_bbs(tgt); |
| 1752 | |
| 1753 | // remove store of initializers to global variables that aren't needed to |
| 1754 | // verify the transformation |
| 1755 | // We only remove inits if it's possible to remove from both programs to keep |
| 1756 | // memories syntactically equal |
| 1757 | auto remove_init_tgt = can_remove_init(tgt); |
| 1758 | for (auto &[name, isrc] : can_remove_init(src)) { |
| 1759 | auto Itgt = remove_init_tgt.find(name); |
| 1760 | if (Itgt == remove_init_tgt.end()) |
| 1761 | continue; |
| 1762 | src.getFirstBB().delInstr(isrc); |
| 1763 | tgt.getFirstBB().delInstr(Itgt->second); |
| 1764 | // TODO: check that tgt init refines that of src |
| 1765 | } |
| 1766 | |
| 1767 | // remove constants introduced in target |
| 1768 | auto src_gvs = src.getGlobalVarNames(); |
| 1769 | for (auto &[name, itgt] : remove_init_tgt) { |
| 1770 | if (find(src_gvs.begin(), src_gvs.end(), name.substr(1)) == src_gvs.end()) |
| 1771 | tgt.getFirstBB().delInstr(itgt); |
| 1772 | } |
| 1773 | |
| 1774 | // optimize pointer comparisons |
| 1775 | optimize_ptrcmp(src); |
| 1776 | optimize_ptrcmp(tgt); |
| 1777 | |
| 1778 | // remove side-effect free instructions without users |
| 1779 | vector<Instr*> to_remove; |
| 1780 | for (auto fn : { &src, &tgt }) { |
| 1781 | bool changed; |
| 1782 | do { |
| 1783 | auto users = fn->getUsers(); |
| 1784 | changed = false; |
| 1785 | |
| 1786 | for (auto bb : fn->getBBs()) { |
no test coverage detected