Skip to content

Commit ccb4633

Browse files
committed
Optimise byte_update lowering
In the case of updates to a byte array do just a single translation of the update value to an array of bytes.
1 parent 6b1a57c commit ccb4633

File tree

1 file changed

+23
-36
lines changed

1 file changed

+23
-36
lines changed

src/solvers/lowering/byte_operators.cpp

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,13 @@ static exprt lower_byte_update(
628628
const namespacet &ns,
629629
bool negative_offset)
630630
{
631-
assert(src.operands().size()==3);
631+
DATA_INVARIANT(
632+
src.id() == ID_byte_update_little_endian ||
633+
src.id() == ID_byte_update_big_endian,
634+
"byte_update with unknown id " + src.id_string());
635+
636+
const irep_idt extract_opcode = src.id() == ID_byte_update_little_endian
637+
? ID_byte_extract_little_endian : ID_byte_extract_big_endian;
632638

633639
mp_integer element_size=
634640
pointer_offset_size(src.op2().type(), ns);
@@ -657,49 +663,36 @@ static exprt lower_byte_update(
657663
// byte array?
658664
if(sub_size==1)
659665
{
666+
byte_extract_exprt byte_extract_expr(
667+
extract_opcode,
668+
src.op2(),
669+
from_integer(0, src.op1().type()),
670+
array_typet(subtype, from_integer(element_size, size_type())));
671+
672+
array_exprt new_value =
673+
to_array_expr(lower_byte_extract(byte_extract_expr, ns));
674+
CHECK_RETURN(new_value.operands().size() == element_size);
675+
660676
// apply 'array-update-with' element_size times
661677
exprt result=src.op0();
662678

663-
for(mp_integer i=0; i<element_size; ++i)
679+
std::size_t i = 0;
680+
for(const auto &element : new_value.operands())
664681
{
665682
exprt i_expr=from_integer(i, ns.follow(src.op1().type()));
666-
667-
exprt new_value;
668-
669-
if(i==0 && element_size==1) // bytes?
670-
{
671-
new_value=src.op2();
672-
if(new_value.type()!=subtype)
673-
new_value.make_typecast(subtype);
674-
}
675-
else
676-
{
677-
byte_extract_exprt byte_extract_expr(
678-
src.id()==ID_byte_update_little_endian?
679-
ID_byte_extract_little_endian:
680-
src.id()==ID_byte_update_big_endian?
681-
ID_byte_extract_big_endian:
682-
throw "unexpected src.id() in lower_byte_update",
683-
subtype);
684-
685-
byte_extract_expr.op()=src.op2();
686-
byte_extract_expr.offset()=i_expr;
687-
688-
new_value=lower_byte_extract(byte_extract_expr, ns);
689-
}
683+
++i;
690684

691685
const exprt where = simplify_expr(plus_exprt(src.op1(), i_expr), ns);
692686

693687
// skip elements that wouldn't change
694-
if(new_value.id() == ID_index)
688+
if(element.id() == ID_index)
695689
{
696-
const index_exprt &index_expr = to_index_expr(new_value);
690+
const index_exprt &index_expr = to_index_expr(element);
697691
if(index_expr.array() == src.op0() && index_expr.index() == where)
698692
continue;
699693
}
700694

701-
with_exprt with_expr(result, where, new_value);
702-
with_expr.type()=src.type();
695+
with_exprt with_expr(result, where, element);
703696

704697
result.swap(with_expr);
705698
}
@@ -751,12 +744,6 @@ static exprt lower_byte_update(
751744
else
752745
stored_value_offset=minus_exprt(cell_offset, src.op1());
753746

754-
auto extract_opcode=
755-
src.id()==ID_byte_update_little_endian ?
756-
ID_byte_extract_little_endian :
757-
src.id()==ID_byte_update_big_endian ?
758-
ID_byte_extract_big_endian :
759-
throw "unexpected src.id() in lower_byte_update";
760747
byte_extract_exprt byte_extract_expr(
761748
extract_opcode,
762749
element_size<sub_size ? src.op2().type() : subtype);

0 commit comments

Comments
 (0)