| 844 | } |
| 845 | |
| 846 | VarNode* ArithFusePass::Impl::process_mul_term(MulTermArray& terms) { |
| 847 | mgb_assert(!terms.empty()); |
| 848 | SumVars sum_vars; |
| 849 | while (terms.size() >= 2) { |
| 850 | auto b = terms.back(); |
| 851 | terms.pop_back(); |
| 852 | auto a = terms.back(); |
| 853 | terms.pop_back(); |
| 854 | ++m_nr_fma4; |
| 855 | sum_vars.add(Elemwise::make( |
| 856 | {a.first, a.second, b.first, b.second}, Mode::FUSE_MUL_ADD4)); |
| 857 | } |
| 858 | if (!terms.empty()) { |
| 859 | auto t = terms.back(); |
| 860 | terms.pop_back(); |
| 861 | auto bias = find_pop_bias_term(t.first->shape()); |
| 862 | if (!bias) |
| 863 | bias = find_pop_bias_term(t.second->shape()); |
| 864 | if (bias) { |
| 865 | ++m_nr_fma3; |
| 866 | sum_vars.add( |
| 867 | Elemwise::make({t.first, t.second, bias}, Mode::FUSE_MUL_ADD3)); |
| 868 | } else { |
| 869 | sum_vars.add(opr::mul(t.first, t.second)); |
| 870 | } |
| 871 | } |
| 872 | return sum_vars.get(); |
| 873 | } |
| 874 | |
| 875 | bool ArithFusePass::Impl::on_opr_visit_finished(Elemwise* opr) { |
| 876 | if (opr->input().size() != 1) |