Debug("bv-rewrite") << "RewriteRule<ExtractExtract>(" << node << ")" << std::endl;
// x[i:j][k:l] ~> x[k+j:l+j]
+ uint32_t j = 0;
Node child = node[0];
- unsigned k = utils::getExtractHigh(node);
- unsigned l = utils::getExtractLow(node);
- unsigned j = utils::getExtractLow(child);
-
- Node result = utils::mkExtract(child[0], k + j, l + j);
+ do
+ {
+ j += utils::getExtractLow(child);
+ child = child[0];
+ } while (child.getKind() == kind::BITVECTOR_EXTRACT);
+
+ uint32_t k = utils::getExtractHigh(node);
+ uint32_t l = utils::getExtractLow(node);
+ Node result = utils::mkExtract(child, k + j, l + j);
return result;
}
}
}
-
- resultNode = LinearRewriteStrategy
- < RewriteRule<ExtractConstant>,
+ resultNode = LinearRewriteStrategy<
+ // We could have an extract over extract
RewriteRule<ExtractExtract>,
- // We could get another extract over extract
+ // The extract may cover the whole bit-vector
RewriteRule<ExtractWhole>,
- // At this point only Extract-Whole could apply
- RewriteRule<ExtractMultLeadingBit>
- >::apply(node);
-
- return RewriteResponse(REWRITE_DONE, resultNode);
+ // Rewrite extracts over wide multiplications
+ RewriteRule<ExtractMultLeadingBit>,
+ // Perform constant folding last to maximize chances that it applies
+ RewriteRule<ExtractConstant>>::apply(node);
+
+ // There are terms that can be rewritten by repeatedly alternating between
+ // ExtractExtract and ExtractConcat, so we have to be conservative here and
+ // return REWRITE_AGAIN if the node changed.
+ return RewriteResponse(resultNode != node ? REWRITE_AGAIN : REWRITE_DONE,
+ resultNode);
}
RewriteResponse TheoryBVRewriter::RewriteConcat(TNode node, bool prerewrite)