1616*/
1717
1818#include < libyul/optimiser/ReasoningBasedSimplifier.h>
19+ #include < libyul/optimiser/SMTSolver.h>
1920
20- #include < libyul/optimiser/OptimizerUtilities.h>
2121#include < libyul/optimiser/SSAValueTracker.h>
2222#include < libyul/optimiser/Semantics.h>
2323#include < libyul/AST.h>
@@ -56,14 +56,7 @@ std::optional<string> ReasoningBasedSimplifier::invalidInCurrentEnvironment()
5656
5757void ReasoningBasedSimplifier::operator ()(VariableDeclaration& _varDecl)
5858{
59- if (_varDecl.variables .size () != 1 || !_varDecl.value )
60- return ;
61- YulString varName = _varDecl.variables .front ().name ;
62- if (!m_ssaVariables.count (varName))
63- return ;
64- bool const inserted = m_variables.insert ({varName, m_solver->newVariable (" yul_" + varName.str (), defaultSort ())}).second ;
65- yulAssert (inserted, " " );
66- m_solver->addAssertion (m_variables.at (varName) == encodeExpression (*_varDecl.value ));
59+ SMTSolver::encodeVariableDeclaration (_varDecl);
6760}
6861
6962void ReasoningBasedSimplifier::operator ()(If& _if)
@@ -111,37 +104,11 @@ ReasoningBasedSimplifier::ReasoningBasedSimplifier(
111104 Dialect const & _dialect,
112105 set<YulString> const & _ssaVariables
113106):
114- m_dialect(_dialect),
115- m_ssaVariables(_ssaVariables),
116- m_solver(make_unique<smtutil::SMTPortfolio>())
107+ SMTSolver(_ssaVariables, _dialect),
108+ m_dialect(_dialect)
117109{
118110}
119111
120- smtutil::Expression ReasoningBasedSimplifier::encodeExpression (yul::Expression const & _expression)
121- {
122- return std::visit (GenericVisitor{
123- [&](FunctionCall const & _functionCall)
124- {
125- if (auto instruction = toEVMInstruction (m_dialect, _functionCall.functionName .name ))
126- return encodeEVMBuiltin (*instruction, _functionCall.arguments );
127- return newRestrictedVariable ();
128- },
129- [&](Identifier const & _identifier)
130- {
131- if (
132- m_ssaVariables.count (_identifier.name ) &&
133- m_variables.count (_identifier.name )
134- )
135- return m_variables.at (_identifier.name );
136- else
137- return newRestrictedVariable ();
138- },
139- [&](Literal const & _literal)
140- {
141- return literalValue (_literal);
142- }
143- }, _expression);
144- }
145112
146113smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin (
147114 evmasm::Instruction _instruction,
@@ -172,10 +139,10 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin(
172139 constantValue (0 ),
173140 // No `wrap()` needed here, because -2**255 / -1 results
174141 // in 2**255 which is "converted" to its two's complement
175- // representation 2**255 in `signedToUnsigned `
176- signedToUnsigned (smtutil::signedDivisionEVM (
177- unsignedToSigned (arguments.at (0 )),
178- unsignedToSigned (arguments.at (1 ))
142+ // representation 2**255 in `signedToTwosComplement `
143+ signedToTwosComplement (smtutil::signedDivisionEVM (
144+ twosComplementToSigned (arguments.at (0 )),
145+ twosComplementToSigned (arguments.at (1 ))
179146 ))
180147 );
181148 case evmasm::Instruction::MOD:
@@ -188,19 +155,19 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin(
188155 return smtutil::Expression::ite (
189156 arguments.at (1 ) == constantValue (0 ),
190157 constantValue (0 ),
191- signedToUnsigned (signedModuloEVM (
192- unsignedToSigned (arguments.at (0 )),
193- unsignedToSigned (arguments.at (1 ))
158+ signedToTwosComplement (signedModuloEVM (
159+ twosComplementToSigned (arguments.at (0 )),
160+ twosComplementToSigned (arguments.at (1 ))
194161 ))
195162 );
196163 case evmasm::Instruction::LT:
197164 return booleanValue (arguments.at (0 ) < arguments.at (1 ));
198165 case evmasm::Instruction::SLT:
199- return booleanValue (unsignedToSigned (arguments.at (0 )) < unsignedToSigned (arguments.at (1 )));
166+ return booleanValue (twosComplementToSigned (arguments.at (0 )) < twosComplementToSigned (arguments.at (1 )));
200167 case evmasm::Instruction::GT:
201168 return booleanValue (arguments.at (0 ) > arguments.at (1 ));
202169 case evmasm::Instruction::SGT:
203- return booleanValue (unsignedToSigned (arguments.at (0 )) > unsignedToSigned (arguments.at (1 )));
170+ return booleanValue (twosComplementToSigned (arguments.at (0 )) > twosComplementToSigned (arguments.at (1 )));
204171 case evmasm::Instruction::EQ:
205172 return booleanValue (arguments.at (0 ) == arguments.at (1 ));
206173 case evmasm::Instruction::ISZERO:
@@ -259,76 +226,3 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin(
259226 }
260227 return newRestrictedVariable ();
261228}
262-
263- smtutil::Expression ReasoningBasedSimplifier::int2bv (smtutil::Expression _arg) const
264- {
265- return smtutil::Expression::int2bv (std::move (_arg), 256 );
266- }
267-
268- smtutil::Expression ReasoningBasedSimplifier::bv2int (smtutil::Expression _arg) const
269- {
270- return smtutil::Expression::bv2int (std::move (_arg));
271- }
272-
273- smtutil::Expression ReasoningBasedSimplifier::newVariable ()
274- {
275- return m_solver->newVariable (uniqueName (), defaultSort ());
276- }
277-
278- smtutil::Expression ReasoningBasedSimplifier::newRestrictedVariable ()
279- {
280- smtutil::Expression var = newVariable ();
281- m_solver->addAssertion (0 <= var && var < smtutil::Expression (bigint (1 ) << 256 ));
282- return var;
283- }
284-
285- string ReasoningBasedSimplifier::uniqueName ()
286- {
287- return " expr_" + to_string (m_varCounter++);
288- }
289-
290- shared_ptr<Sort> ReasoningBasedSimplifier::defaultSort () const
291- {
292- return SortProvider::intSort ();
293- }
294-
295- smtutil::Expression ReasoningBasedSimplifier::booleanValue (smtutil::Expression _value) const
296- {
297- return smtutil::Expression::ite (_value, constantValue (1 ), constantValue (0 ));
298- }
299-
300- smtutil::Expression ReasoningBasedSimplifier::constantValue (size_t _value) const
301- {
302- return _value;
303- }
304-
305- smtutil::Expression ReasoningBasedSimplifier::literalValue (Literal const & _literal) const
306- {
307- return smtutil::Expression (valueOfLiteral (_literal));
308- }
309-
310- smtutil::Expression ReasoningBasedSimplifier::unsignedToSigned (smtutil::Expression _value)
311- {
312- return smtutil::Expression::ite (
313- _value < smtutil::Expression (bigint (1 ) << 255 ),
314- _value,
315- _value - smtutil::Expression (bigint (1 ) << 256 )
316- );
317- }
318-
319- smtutil::Expression ReasoningBasedSimplifier::signedToUnsigned (smtutil::Expression _value)
320- {
321- return smtutil::Expression::ite (
322- _value >= 0 ,
323- _value,
324- _value + smtutil::Expression (bigint (1 ) << 256 )
325- );
326- }
327-
328- smtutil::Expression ReasoningBasedSimplifier::wrap (smtutil::Expression _value)
329- {
330- smtutil::Expression rest = newRestrictedVariable ();
331- smtutil::Expression multiplier = newVariable ();
332- m_solver->addAssertion (_value == multiplier * smtutil::Expression (bigint (1 ) << 256 ) + rest);
333- return rest;
334- }
0 commit comments