@@ -990,29 +990,23 @@ void bit_blaster_tpl<Cfg>::mk_ext_rotate_left_right(unsigned sz, expr * const *
990990            mk_rotate_right (sz, a_bits, static_cast <unsigned >(k.get_uint64 ()), out_bits);
991991    }
992992    else  {
993-         // 
994-         //  Review: a better tuned implementation is possible by using shifts by power of two.
995-         //  e.g., looping over the bits of b_bits, then rotate by a power of two depending
996-         //  on the bit-position. This would get rid of the mk_urem.
997-         // 
998-         expr_ref_vector sz_bits (m ());
999-         expr_ref_vector masked_b_bits (m ());
1000-         expr_ref_vector eqs (m ());
1001-         numeral sz_numeral (sz);
1002-         num2bits (sz_numeral, sz, sz_bits);
1003-         mk_urem (sz, b_bits, sz_bits.data (), masked_b_bits);
1004-         mk_eqs (sz, masked_b_bits.data (), eqs);
1005-         for  (unsigned  i = 0 ; i < sz; i++) {
1006-             checkpoint ();
1007-             expr_ref out (m ());
1008-             out = a_bits[i];
1009-             for  (unsigned  j = 1 ; j < sz; j++) {
1010-                 expr_ref new_out (m ());
1011-                 unsigned  src = (Left ? (sz + i - j) : (i + j)) % sz;
1012-                 mk_ite (eqs.get (j), a_bits[src], out, new_out);
1013-                 out = new_out;
993+         for  (unsigned  j = 0 ; j < sz; ++j)
994+             out_bits.push_back (a_bits[j]);
995+         expr_ref_vector out (m ());
996+         for  (unsigned  i = 0 , p = 1 ; i < sz; ++i) {
997+             auto  bit_i = b_bits[i];
998+             //  rotate by p if bit_i is set.
999+             out.reset ();
1000+             for  (unsigned  j = 0 ; j < sz; ++j) {
1001+                 unsigned  src = (Left ? (sz + j - p) : (j + p)) % sz;
1002+                 out.push_back (m ().mk_ite (bit_i, out_bits.get (src), out_bits.get (j)));
10141003            }
1015-             out_bits.push_back (out);
1004+             out_bits.reset ();
1005+             out_bits.append (out);        
1006+             p *= 2 ;
1007+             if  (is_power_of_two (sz) && sz == p)
1008+                 break ;
1009+             p %= sz;
10161010        }
10171011    }
10181012}
0 commit comments