2121
2222#include < libyul/backends/evm/EVMObjectCompiler.h>
2323
24+ #include < libyul/backends/evm/ssa/CodeTransform.h>
25+ #include < libyul/backends/evm/ssa/SSACFGBuilder.h>
26+ #include < libyul/backends/evm/ssa/ControlFlow.h>
27+
2428#include < libyul/backends/evm/EVMCodeTransform.h>
2529#include < libyul/backends/evm/EVMDialect.h>
2630#include < libyul/backends/evm/OptimizedEVMCodeTransform.h>
@@ -37,14 +41,15 @@ using namespace solidity::yul;
3741void EVMObjectCompiler::compile (
3842 Object const & _object,
3943 AbstractAssembly& _assembly,
40- bool _optimize
44+ bool _optimize,
45+ bool _viaSSACFG
4146)
4247{
4348 EVMObjectCompiler compiler (_assembly);
44- compiler.run (_object, _optimize);
49+ compiler.run (_object, _optimize, _viaSSACFG );
4550}
4651
47- void EVMObjectCompiler::run (Object const & _object, bool _optimize)
52+ void EVMObjectCompiler::run (Object const & _object, bool _optimize, bool _viaSSACFG )
4853{
4954 yulAssert (_object.dialect ());
5055 auto const * evmDialect = dynamic_cast <EVMDialect const *>(_object.dialect ());
@@ -61,7 +66,7 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize)
6166 auto subAssemblyAndID = m_assembly.createSubAssembly (isCreation, subObject->name );
6267 context.subIDs [subObject->name ] = subAssemblyAndID.second ;
6368 subObject->subId = subAssemblyAndID.second ;
64- compile (*subObject, *subAssemblyAndID.first , _optimize);
69+ compile (*subObject, *subAssemblyAndID.first , _optimize, _viaSSACFG );
6570 }
6671 else
6772 {
@@ -82,33 +87,51 @@ void EVMObjectCompiler::run(Object const& _object, bool _optimize)
8287 }
8388 if (_optimize && evmDialect->evmVersion ().canOverchargeGasForCall ())
8489 {
85- auto stackErrors = OptimizedEVMCodeTransform::run (
86- m_assembly,
87- *_object.analysisInfo ,
88- _object.code ()->root (),
89- *evmDialect,
90- context,
91- OptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName
92- );
93- if (!stackErrors.empty ())
90+ if (_viaSSACFG)
9491 {
95- yulAssert (evmDialect->providesObjectAccess ());
96- auto const memoryGuardHandle = evmDialect->findBuiltin (" memoryguard" );
97- yulAssert (memoryGuardHandle, " Compiling with object access, memoryguard should be available as builtin." );
98- std::vector<FunctionCall const *> memoryGuardCalls = findFunctionCalls (
92+ std::unique_ptr<ssa::ControlFlow> controlFlow = ssa::SSACFGBuilder::build (
93+ *_object.analysisInfo ,
94+ *_object.dialect (),
9995 _object.code ()->root (),
100- *memoryGuardHandle
96+ false
10197 );
102- auto stackError = stackErrors.front ();
103- std::string msg = stackError.comment () ? *stackError.comment () : " " ;
104- if (memoryGuardCalls.empty ())
105- msg += " \n No memoryguard was present. "
106- " Consider using memory-safe assembly only and annotating it via "
107- " 'assembly (\" memory-safe\" ) { ... }'." ;
108- else
109- msg += " \n memoryguard was present." ;
110- stackError << util::errinfo_comment (msg);
111- BOOST_THROW_EXCEPTION (stackError);
98+ ssa::ControlFlowLiveness const liveness (*controlFlow);
99+ ssa::CodeTransform::run (
100+ m_assembly,
101+ liveness,
102+ context
103+ );
104+ }
105+ else
106+ {
107+ auto stackErrors = OptimizedEVMCodeTransform::run (
108+ m_assembly,
109+ *_object.analysisInfo ,
110+ _object.code ()->root (),
111+ *evmDialect,
112+ context,
113+ OptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName
114+ );
115+ if (!stackErrors.empty ())
116+ {
117+ yulAssert (evmDialect->providesObjectAccess ());
118+ auto const memoryGuardHandle = evmDialect->findBuiltin (" memoryguard" );
119+ yulAssert (memoryGuardHandle, " Compiling with object access, memoryguard should be available as builtin." );
120+ std::vector<FunctionCall const *> memoryGuardCalls = findFunctionCalls (
121+ _object.code ()->root (),
122+ *memoryGuardHandle
123+ );
124+ auto stackError = stackErrors.front ();
125+ std::string msg = stackError.comment () ? *stackError.comment () : " " ;
126+ if (memoryGuardCalls.empty ())
127+ msg += " \n No memoryguard was present. "
128+ " Consider using memory-safe assembly only and annotating it via "
129+ " 'assembly (\" memory-safe\" ) { ... }'." ;
130+ else
131+ msg += " \n memoryguard was present." ;
132+ stackError << util::errinfo_comment (msg);
133+ BOOST_THROW_EXCEPTION (stackError);
134+ }
112135 }
113136 }
114137 else
0 commit comments