diff --git a/libyul/YulControlFlowGraphExporter.cpp b/libyul/YulControlFlowGraphExporter.cpp index 65c0805f984a..1ce7f58fc5bf 100644 --- a/libyul/YulControlFlowGraphExporter.cpp +++ b/libyul/YulControlFlowGraphExporter.cpp @@ -177,12 +177,20 @@ Json YulControlFlowGraphExporter::toJson(SSACFG const& _cfg, SSACFG::BlockId _bl Json YulControlFlowGraphExporter::toJson(Json& _ret, SSACFG const& _cfg, SSACFG::Operation const& _operation) { Json opJson = Json::object(); - std::visit(util::GenericVisitor{ - [&](SSACFG::Call const& _call) { + std::visit(GenericVisitor{ + [&](SSACFG::Call const& _call) + { _ret["type"] = "FunctionCall"; opJson["op"] = _call.function.get().name.str(); }, - [&](SSACFG::BuiltinCall const& _call) { + [&](SSACFG::LiteralAssignment const&) + { + yulAssert(_operation.inputs.size() == 1); + yulAssert(_cfg.isLiteralValue(_operation.inputs.back())); + _ret["type"] = "LiteralAssignment"; + }, + [&](SSACFG::BuiltinCall const& _call) + { _ret["type"] = "BuiltinCall"; Json builtinArgsJson = Json::array(); auto const& builtin = _call.builtin.get(); diff --git a/libyul/YulStack.cpp b/libyul/YulStack.cpp index 5adb8d6d5c9a..85709b987c59 100644 --- a/libyul/YulStack.cpp +++ b/libyul/YulStack.cpp @@ -394,11 +394,15 @@ Json YulStack::cfgJson() const yulAssert(m_parserResult->analysisInfo, ""); // FIXME: we should not regenerate the cfg, but for now this is sufficient for testing purposes auto exportCFGFromObject = [&](Object const& _object) -> Json { + // with this set to `true`, assignments of the type `let x := 42` are preserved and added as assignment + // operations to the control flow graphs + bool constexpr keepLiteralAssignments = true; // NOTE: The block Ids are reset for each object std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( - *_object.analysisInfo.get(), + *_object.analysisInfo, languageToDialect(m_language, m_evmVersion, m_eofVersion), - _object.code()->root() + _object.code()->root(), + keepLiteralAssignments ); std::unique_ptr liveness = std::make_unique(*controlFlow); YulControlFlowGraphExporter exporter(*controlFlow, liveness.get()); diff --git a/libyul/backends/evm/SSAControlFlowGraph.cpp b/libyul/backends/evm/SSAControlFlowGraph.cpp index 733f4967d806..215fe7358b2b 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.cpp +++ b/libyul/backends/evm/SSAControlFlowGraph.cpp @@ -168,17 +168,28 @@ class SSACFGPrinter [&](SSACFG::BuiltinCall const& _call) { return _call.builtin.get().name; }, + [&](SSACFG::LiteralAssignment const&) + { + yulAssert(operation.inputs.size() == 1); + return varToString(m_cfg, operation.inputs.back()); + } }, operation.kind); if (!operation.outputs.empty()) m_result << fmt::format( "{} := ", fmt::join(operation.outputs | ranges::views::transform(valueToString), ", ") ); - m_result << fmt::format( - "{}({})\\l\\\n", - escape(label), - fmt::join(operation.inputs | ranges::views::transform(valueToString), ", ") - ); + if (std::holds_alternative(operation.kind)) + m_result << fmt::format( + "{}\\l\\\n", + escape(label) + ); + else + m_result << fmt::format( + "{}({})\\l\\\n", + escape(label), + fmt::join(operation.inputs | ranges::views::transform(valueToString), ", ") + ); } m_result << "\"];\n"; std::visit(GenericVisitor{ diff --git a/libyul/backends/evm/SSAControlFlowGraph.h b/libyul/backends/evm/SSAControlFlowGraph.h index 9397e0e207c1..ee1bdf3b4ecb 100644 --- a/libyul/backends/evm/SSAControlFlowGraph.h +++ b/libyul/backends/evm/SSAControlFlowGraph.h @@ -78,10 +78,14 @@ class SSACFG std::reference_wrapper call; bool canContinue; }; + struct LiteralAssignment + { + langutil::DebugData::ConstPtr debugData; + }; struct Operation { std::vector outputs{}; - std::variant kind; + std::variant kind; std::vector inputs{}; }; struct BasicBlock @@ -199,7 +203,7 @@ class SSACFG } ValueId newLiteral(langutil::DebugData::ConstPtr _debugData, u256 _value) { - auto [it, inserted] = m_literals.emplace(_value, SSACFG::ValueId{m_valueInfos.size()}); + auto [it, inserted] = m_literals.emplace(_value, ValueId{m_valueInfos.size()}); if (inserted) m_valueInfos.emplace_back(LiteralValue{std::move(_debugData), _value}); else diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp index 69e9e3052104..19308617cd5f 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.cpp @@ -20,16 +20,18 @@ */ #include -#include -#include + #include +#include #include +#include #include #include #include #include +#include #include #include #include @@ -49,26 +51,29 @@ SSAControlFlowGraphBuilder::SSAControlFlowGraphBuilder( SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect + Dialect const& _dialect, + bool _keepLiteralAssignments ): m_controlFlow(_controlFlow), m_graph(_graph), m_info(_analysisInfo), m_sideEffects(_sideEffects), - m_dialect(_dialect) + m_dialect(_dialect), + m_keepLiteralAssignments(_keepLiteralAssignments) { } std::unique_ptr SSAControlFlowGraphBuilder::build( AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, - Block const& _block + Block const& _block, + bool _keepLiteralAssignments ) { ControlFlowSideEffectsCollector sideEffects(_dialect, _block); auto controlFlow = std::make_unique(); - SSAControlFlowGraphBuilder builder(*controlFlow, *controlFlow->mainGraph, _analysisInfo, sideEffects, _dialect); + SSAControlFlowGraphBuilder builder(*controlFlow, *controlFlow->mainGraph, _analysisInfo, sideEffects, _dialect, _keepLiteralAssignments); builder.m_currentBlock = controlFlow->mainGraph->makeBlock(debugDataOf(_block)); builder.sealBlock(builder.m_currentBlock); builder(_block); @@ -147,8 +152,8 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::tryRemoveTrivialPhi(SSACFG::ValueId [](SSACFG::BasicBlock::Terminated&) {} }, block.exit); } - for (auto& [_, currentVariableDefs]: m_currentDef) - std::replace(currentVariableDefs.begin(), currentVariableDefs.end(), _phi, same); + for (auto& currentVariableDefs: m_currentDef | ranges::views::values) + ranges::replace(currentVariableDefs, _phi, same); for (auto phiUse: phiUses) tryRemoveTrivialPhi(phiUse); @@ -178,11 +183,6 @@ void SSAControlFlowGraphBuilder::cleanUnreachable() }, block.exit); }); - auto isUnreachableValue = [&](SSACFG::ValueId const& _value) -> bool { - auto* valueInfo = std::get_if(&m_graph.valueInfo(_value)); - return (valueInfo) ? true : false; - }; - // Remove all entries from unreachable nodes from the graph. for (SSACFG::BlockId blockId: reachabilityCheck.visited) { @@ -197,7 +197,7 @@ void SSAControlFlowGraphBuilder::cleanUnreachable() for (auto phi: block.phis) if (auto* phiInfo = std::get_if(&m_graph.valueInfo(phi))) std::erase_if(phiInfo->arguments, [&](SSACFG::ValueId _arg) { - if (isUnreachableValue(_arg)) + if (std::holds_alternative(m_graph.valueInfo(_arg))) { maybeTrivialPhi.insert(phi); return true; @@ -240,7 +240,7 @@ void SSAControlFlowGraphBuilder::buildFunctionGraph( cfg.arguments = arguments; cfg.returns = returns; - SSAControlFlowGraphBuilder builder(m_controlFlow, cfg, m_info, m_sideEffects, m_dialect); + SSAControlFlowGraphBuilder builder(m_controlFlow, cfg, m_info, m_sideEffects, m_dialect, m_keepLiteralAssignments); builder.m_currentBlock = cfg.entry; builder.m_functionDefinitions = m_functionDefinitions; for (auto&& [var, varId]: cfg.arguments) @@ -273,6 +273,11 @@ void SSAControlFlowGraphBuilder::operator()(Assignment const& _assignment) void SSAControlFlowGraphBuilder::operator()(VariableDeclaration const& _variableDeclaration) { + // if we have no value (like in `let a` without right-hand side), we can just skip this. the variable(s) will be + // added when first needed + if (!_variableDeclaration.value) + return; + assign( _variableDeclaration.variables | ranges::views::transform([&](auto& _var) { return std::ref(lookupVariable(_var.name)); }) | ranges::to, _variableDeclaration.value.get() @@ -533,15 +538,27 @@ void SSAControlFlowGraphBuilder::assign(std::vector std::vector { if (auto const* functionCall = std::get_if(_expression)) return visitFunctionCall(*functionCall); - else if (_expression) + if (_expression) return {std::visit(*this, *_expression)}; - else - return {_variables.size(), zero()}; + return {_variables.size(), zero()}; }(); yulAssert(rhs.size() == _variables.size()); for (auto const& [var, value]: ranges::zip_view(_variables, rhs)) - writeVariable(var, m_currentBlock, value); + { + if (m_keepLiteralAssignments && m_graph.isLiteralValue(value)) + { + SSACFG::Operation assignment{ + .outputs = {m_graph.newVariable(m_currentBlock)}, + .kind = SSACFG::LiteralAssignment{}, + .inputs = {value} + }; + currentBlock().operations.emplace_back(assignment); + writeVariable(var, m_currentBlock, assignment.outputs.back()); + } + else + writeVariable(var, m_currentBlock, value); + } } @@ -610,7 +627,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::readVariableRecursive(Scope::Variabl // incomplete block val = m_graph.newPhi(_block); block.phis.insert(val); - info.incompletePhis.emplace_back(val, std::ref(_variable)); + info.incompletePhis.emplace_back(val, _variable); } else if (block.entries.size() == 1) // one predecessor: no phi needed @@ -633,7 +650,7 @@ SSACFG::ValueId SSAControlFlowGraphBuilder::addPhiOperands(Scope::Variable const { yulAssert(std::holds_alternative(m_graph.valueInfo(_phi))); auto& phi = std::get(m_graph.valueInfo(_phi)); - for (auto pred: m_graph.block(phi.block).entries) + for (auto const& pred: m_graph.block(phi.block).entries) phi.arguments.emplace_back(readVariable(_variable, pred)); // we call tryRemoveTrivialPhi explicitly to avoid removing trivial phis in unsealed blocks return _phi; @@ -660,14 +677,14 @@ Scope::Variable const& SSAControlFlowGraphBuilder::lookupVariable(YulName _name) yulAssert(m_scope, ""); Scope::Variable const* var = nullptr; if (m_scope->lookup(_name, util::GenericVisitor{ - [&](Scope::Variable& _var) { var = &_var; }, - [](Scope::Function&) + [&](Scope::Variable const& _var) { var = &_var; }, + [](Scope::Function const&) { yulAssert(false, "Function not removed during desugaring."); } })) { - yulAssert(var, ""); + yulAssert(var); return *var; }; yulAssert(false, "External identifier access unimplemented."); diff --git a/libyul/backends/evm/SSAControlFlowGraphBuilder.h b/libyul/backends/evm/SSAControlFlowGraphBuilder.h index a3a723f67c42..8cd214146260 100644 --- a/libyul/backends/evm/SSAControlFlowGraphBuilder.h +++ b/libyul/backends/evm/SSAControlFlowGraphBuilder.h @@ -44,7 +44,8 @@ class SSAControlFlowGraphBuilder SSACFG& _graph, AsmAnalysisInfo const& _analysisInfo, ControlFlowSideEffectsCollector const& _sideEffects, - Dialect const& _dialect + Dialect const& _dialect, + bool _keepLiteralAssignments ); public: SSAControlFlowGraphBuilder(SSAControlFlowGraphBuilder const&) = delete; @@ -52,7 +53,8 @@ class SSAControlFlowGraphBuilder static std::unique_ptr build( AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, - Block const& _block + Block const& _block, + bool _keepLiteralAssignments ); void operator()(ExpressionStatement const& _statement); @@ -92,6 +94,7 @@ class SSAControlFlowGraphBuilder AsmAnalysisInfo const& m_info; ControlFlowSideEffectsCollector const& m_sideEffects; Dialect const& m_dialect; + bool const m_keepLiteralAssignments; std::vector> m_functionDefinitions; SSACFG::BlockId m_currentBlock; SSACFG::BasicBlock& currentBlock() { return m_graph.block(m_currentBlock); } diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index 303d51bbbbf4..a9c5ca7a6d4f 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -1221,16 +1221,27 @@ "type": "ConditionalJump" }, "id": "Block18", - "instructions": [], + "instructions": [ + { + "in": [ + "0x00" + ], + "out": [ + "v64" + ] + } + ], "liveness": { "in": [ "v46", "v59" ], "out": [ - "v46" + "v46", + "v64" ] - } + }, + "type": "LiteralAssignment" }, { "exit": { @@ -1297,12 +1308,12 @@ "instructions": [ { "in": [ - "0x00", - "v93" + "v64", + "v95" ], "op": "PhiFunction", "out": [ - "v95" + "v97" ] }, { @@ -1311,13 +1322,13 @@ ], "op": "mload", "out": [ - "v94" + "v96" ] }, { "in": [ - "v95", - "v94" + "v97", + "v96" ], "op": "mstore", "out": [] @@ -1325,7 +1336,7 @@ { "in": [ "0x20", - "v94" + "v96" ], "op": "return", "out": [] @@ -1333,7 +1344,7 @@ ], "liveness": { "in": [ - "v95" + "v97" ], "out": [] }, @@ -1341,7 +1352,7 @@ }, { "exit": { - "cond": "v67", + "cond": "v69", "targets": [ "Block23", "Block22" @@ -1350,21 +1361,29 @@ }, "id": "Block20", "instructions": [ + { + "in": [ + "0x20" + ], + "out": [ + "v67" + ] + }, { "in": [], "op": "returndatasize", "out": [ - "v66" + "v68" ] }, { "in": [ - "v66", + "v68", "0x20" ], "op": "gt", "out": [ - "v67" + "v69" ] } ], @@ -1373,7 +1392,8 @@ "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1384,7 +1404,7 @@ "Block22" ], "exit": { - "cond": "v80", + "cond": "v82", "targets": [ "Block25", "Block24" @@ -1395,12 +1415,12 @@ "instructions": [ { "in": [ - "0x20", - "v68" + "v67", + "v70" ], "op": "PhiFunction", "out": [ - "v71" + "v73" ] }, { @@ -1409,79 +1429,79 @@ ], "op": "not", "out": [ - "v70" + "v72" ] }, { "in": [ "0x1f", - "v71" + "v73" ], "op": "add", "out": [ - "v72" + "v74" ] }, { "in": [ - "v70", - "v72" + "v72", + "v74" ], "op": "and", "out": [ - "v73" + "v75" ] }, { "in": [ - "v73", + "v75", "v46" ], "op": "add", "out": [ - "v77" + "v79" ] }, { "in": [ "v46", - "v77" + "v79" ], "op": "lt", "out": [ - "v78" + "v80" ] }, { "in": [ "0xffffffffffffffff", - "v77" + "v79" ], "op": "gt", "out": [ - "v79" + "v81" ] }, { "in": [ - "v78", - "v79" + "v80", + "v81" ], "op": "or", "out": [ - "v80" + "v82" ] } ], "liveness": { "in": [ "v46", - "v71" + "v73" ], "out": [ "v46", - "v71", - "v77" + "v73", + "v79" ] }, "type": "BuiltinCall" @@ -1499,7 +1519,7 @@ "in": [], "op": "returndatasize", "out": [ - "v68" + "v70" ] } ], @@ -1509,14 +1529,14 @@ ], "out": [ "v46", - "v68" + "v70" ] }, "type": "BuiltinCall" }, { "exit": { - "cond": "v90", + "cond": "v92", "targets": [ "Block28", "Block27" @@ -1527,7 +1547,7 @@ "instructions": [ { "in": [ - "v77", + "v79", "0x40" ], "op": "mstore", @@ -1535,40 +1555,40 @@ }, { "in": [ - "v71", + "v73", "v46" ], "op": "add", "out": [ - "v88" + "v90" ] }, { "in": [ "v46", - "v88" + "v90" ], "op": "sub", "out": [ - "v89" + "v91" ] }, { "in": [ "0x20", - "v89" + "v91" ], "op": "slt", "out": [ - "v90" + "v92" ] } ], "liveness": { "in": [ "v46", - "v71", - "v77" + "v73", + "v79" ], "out": [ "v46" @@ -1589,12 +1609,12 @@ ], "op": "shl", "out": [ - "v81" + "v83" ] }, { "in": [ - "v81", + "v83", "0x00" ], "op": "mstore", @@ -1638,7 +1658,7 @@ ], "op": "mload", "out": [ - "v93" + "v95" ] } ], @@ -1647,7 +1667,7 @@ "v46" ], "out": [ - "v93" + "v95" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 9affc4206939..2620d53a96ab 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -1221,16 +1221,27 @@ Yul Control Flow Graph: "type": "ConditionalJump" }, "id": "Block18", - "instructions": [], + "instructions": [ + { + "in": [ + "0x00" + ], + "out": [ + "v64" + ] + } + ], "liveness": { "in": [ "v46", "v59" ], "out": [ - "v46" + "v46", + "v64" ] - } + }, + "type": "LiteralAssignment" }, { "exit": { @@ -1297,12 +1308,12 @@ Yul Control Flow Graph: "instructions": [ { "in": [ - "0x00", - "v93" + "v64", + "v95" ], "op": "PhiFunction", "out": [ - "v95" + "v97" ] }, { @@ -1311,13 +1322,13 @@ Yul Control Flow Graph: ], "op": "mload", "out": [ - "v94" + "v96" ] }, { "in": [ - "v95", - "v94" + "v97", + "v96" ], "op": "mstore", "out": [] @@ -1325,7 +1336,7 @@ Yul Control Flow Graph: { "in": [ "0x20", - "v94" + "v96" ], "op": "return", "out": [] @@ -1333,7 +1344,7 @@ Yul Control Flow Graph: ], "liveness": { "in": [ - "v95" + "v97" ], "out": [] }, @@ -1341,7 +1352,7 @@ Yul Control Flow Graph: }, { "exit": { - "cond": "v67", + "cond": "v69", "targets": [ "Block23", "Block22" @@ -1350,21 +1361,29 @@ Yul Control Flow Graph: }, "id": "Block20", "instructions": [ + { + "in": [ + "0x20" + ], + "out": [ + "v67" + ] + }, { "in": [], "op": "returndatasize", "out": [ - "v66" + "v68" ] }, { "in": [ - "v66", + "v68", "0x20" ], "op": "gt", "out": [ - "v67" + "v69" ] } ], @@ -1373,7 +1392,8 @@ Yul Control Flow Graph: "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1384,7 +1404,7 @@ Yul Control Flow Graph: "Block22" ], "exit": { - "cond": "v80", + "cond": "v82", "targets": [ "Block25", "Block24" @@ -1395,12 +1415,12 @@ Yul Control Flow Graph: "instructions": [ { "in": [ - "0x20", - "v68" + "v67", + "v70" ], "op": "PhiFunction", "out": [ - "v71" + "v73" ] }, { @@ -1409,79 +1429,79 @@ Yul Control Flow Graph: ], "op": "not", "out": [ - "v70" + "v72" ] }, { "in": [ "0x1f", - "v71" + "v73" ], "op": "add", "out": [ - "v72" + "v74" ] }, { "in": [ - "v70", - "v72" + "v72", + "v74" ], "op": "and", "out": [ - "v73" + "v75" ] }, { "in": [ - "v73", + "v75", "v46" ], "op": "add", "out": [ - "v77" + "v79" ] }, { "in": [ "v46", - "v77" + "v79" ], "op": "lt", "out": [ - "v78" + "v80" ] }, { "in": [ "0xffffffffffffffff", - "v77" + "v79" ], "op": "gt", "out": [ - "v79" + "v81" ] }, { "in": [ - "v78", - "v79" + "v80", + "v81" ], "op": "or", "out": [ - "v80" + "v82" ] } ], "liveness": { "in": [ "v46", - "v71" + "v73" ], "out": [ "v46", - "v71", - "v77" + "v73", + "v79" ] }, "type": "BuiltinCall" @@ -1499,7 +1519,7 @@ Yul Control Flow Graph: "in": [], "op": "returndatasize", "out": [ - "v68" + "v70" ] } ], @@ -1509,14 +1529,14 @@ Yul Control Flow Graph: ], "out": [ "v46", - "v68" + "v70" ] }, "type": "BuiltinCall" }, { "exit": { - "cond": "v90", + "cond": "v92", "targets": [ "Block28", "Block27" @@ -1527,7 +1547,7 @@ Yul Control Flow Graph: "instructions": [ { "in": [ - "v77", + "v79", "0x40" ], "op": "mstore", @@ -1535,40 +1555,40 @@ Yul Control Flow Graph: }, { "in": [ - "v71", + "v73", "v46" ], "op": "add", "out": [ - "v88" + "v90" ] }, { "in": [ "v46", - "v88" + "v90" ], "op": "sub", "out": [ - "v89" + "v91" ] }, { "in": [ "0x20", - "v89" + "v91" ], "op": "slt", "out": [ - "v90" + "v92" ] } ], "liveness": { "in": [ "v46", - "v71", - "v77" + "v73", + "v79" ], "out": [ "v46" @@ -1589,12 +1609,12 @@ Yul Control Flow Graph: ], "op": "shl", "out": [ - "v81" + "v83" ] }, { "in": [ - "v81", + "v83", "0x00" ], "op": "mstore", @@ -1638,7 +1658,7 @@ Yul Control Flow Graph: ], "op": "mload", "out": [ - "v93" + "v95" ] } ], @@ -1647,7 +1667,7 @@ Yul Control Flow Graph: "v46" ], "out": [ - "v93" + "v95" ] }, "type": "BuiltinCall" diff --git a/test/libyul/SSAControlFlowGraphTest.cpp b/test/libyul/SSAControlFlowGraphTest.cpp index d2acee7bcb85..087a79e974af 100644 --- a/test/libyul/SSAControlFlowGraphTest.cpp +++ b/test/libyul/SSAControlFlowGraphTest.cpp @@ -73,7 +73,8 @@ TestCase::TestResult SSAControlFlowGraphTest::run(std::ostream& _stream, std::st std::unique_ptr controlFlow = SSAControlFlowGraphBuilder::build( *yulStack.parserResult()->analysisInfo, yulStack.dialect(), - yulStack.parserResult()->code()->root() + yulStack.parserResult()->code()->root(), + true ); ControlFlowLiveness liveness(*controlFlow); m_obtainedResult = controlFlow->toDot(&liveness); diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 6fb0453c186b..ecb1b7cfeacd 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -63,29 +63,30 @@ // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ // Block 0; (0, max 17)\nLiveIn: v0,v1\l\ -// LiveOut: v0,v1\l\n"]; +// LiveOut: v0,v1,v4\l\nv4 := 42\l\ +// "]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ -// Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ -// Block 0 => 42,\l\ -// Block 21 => v43\l\ +// Block 1; (1, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv6 := φ(\l\ +// Block 0 => v4,\l\ +// Block 21 => v44\l\ // )\l\ -// v6 := lt(v0, v5)\l\ +// v7 := lt(v0, v6)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v6 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_1Exit:0 -> Block1_4 [style="solid"]; // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ -// Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ -// v8 := eq(0, v7)\l\ +// Block 2; (2, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6,v8\l\nv8 := mload(v6)\l\ +// v9 := eq(0, v8)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v8 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit [label="{ If v9 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_2Exit:0 -> Block1_7 [style="solid"]; // Block1_2Exit:1 -> Block1_6 [style="solid"]; // Block1_4 [label="\ @@ -102,11 +103,11 @@ // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ -// Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// Block 7; (5, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv14 := eq(1, v8)\l\ // "]; // Block1_7 -> Block1_7Exit; -// Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit [label="{ If v14 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_7Exit:0 -> Block1_10 [style="solid"]; // Block1_7Exit:1 -> Block1_9 [style="solid"]; // Block1_9 [label="\ @@ -116,11 +117,11 @@ // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// Block 10; (7, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv21 := eq(2, v8)\l\ // "]; // Block1_10 -> Block1_10Exit; -// Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit [label="{ If v21 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_10Exit:0 -> Block1_13 [style="solid"]; // Block1_10Exit:1 -> Block1_12 [style="solid"]; // Block1_12 [label="\ @@ -131,31 +132,31 @@ // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// Block 13; (9, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6\l\nv26 := eq(3, v8)\l\ // "]; // Block1_13 -> Block1_13Exit; -// Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit [label="{ If v26 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_13Exit:0 -> Block1_16 [style="solid"]; // Block1_13Exit:1 -> Block1_15 [style="solid"]; // Block1_15 [label="\ -// Block 15; (10, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ +// Block 15; (10, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ -// Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// Block 16; (15, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv30 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; -// Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit [label="{ If v30 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_16Exit:0 -> Block1_18 [style="solid"]; // Block1_16Exit:1 -> Block1_17 [style="solid"]; // Block1_5 [label="\ -// Block 5; (11, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ +// Block 5; (11, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; @@ -167,30 +168,30 @@ // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18; (17, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ +// Block 18; (17, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ -// Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ -// v44 := calldataload(v43)\l\ +// Block 3; (12, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v44\l\nv44 := add(1, v6)\l\ +// v45 := calldataload(v44)\l\ // "]; // Block1_3 -> Block1_3Exit; -// Block1_3Exit [label="{ If v44 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit [label="{ If v45 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_3Exit:0 -> Block1_21 [style="solid"]; // Block1_3Exit:1 -> Block1_20 [style="solid"]; // Block1_20 [label="\ -// Block 20; (13, max 13)\nLiveIn: v43\l\ -// LiveOut: \l\nsstore(v43, 0)\l\ +// Block 20; (13, max 13)\nLiveIn: v44\l\ +// LiveOut: \l\nsstore(v44, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21; (14, max 14)\nLiveIn: v0,v1,v43\l\ -// LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ +// Block 21; (14, max 14)\nLiveIn: v0,v1,v44\l\ +// LiveOut: v0,v1,v44\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index c3ea8b94f8aa..d4e8b432d608 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -79,36 +79,38 @@ // FunctionEntry_f_0 -> Block1_0; // Block1_0 [label="\ // Block 0; (0, max 17)\nLiveIn: v0,v1\l\ -// LiveOut: v0,v1\l\n"]; +// LiveOut: v0,v1,v4\l\nv4 := 42\l\ +// "]; // Block1_0 -> Block1_0Exit [arrowhead=none]; // Block1_0Exit [label="Jump" shape=oval]; // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ -// Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ -// Block 0 => 42,\l\ -// Block 21 => v43\l\ +// Block 1; (1, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv6 := φ(\l\ +// Block 0 => v4,\l\ +// Block 21 => v44\l\ // )\l\ -// v6 := lt(v0, v5)\l\ +// v7 := lt(v0, v6)\l\ // "]; // Block1_1 -> Block1_1Exit; -// Block1_1Exit [label="{ If v6 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_1Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_1Exit:0 -> Block1_4 [style="solid"]; // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ -// Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ -// v8 := eq(0, v7)\l\ +// Block 2; (2, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6,v8\l\nv8 := mload(v6)\l\ +// v9 := eq(0, v8)\l\ // "]; // Block1_2 -> Block1_2Exit; -// Block1_2Exit [label="{ If v8 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_2Exit [label="{ If v9 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_2Exit:0 -> Block1_7 [style="solid"]; // Block1_2Exit:1 -> Block1_6 [style="solid"]; // Block1_4 [label="\ // Block 4; (4, max 4)\nLiveIn: \l\ -// LiveOut: \l\nsstore(3084, 12)\l\ +// LiveOut: v78\l\nsstore(3084, 12)\l\ +// v78 := 27\l\ // "]; -// Block1_4Exit [label="FunctionReturn[27]"]; +// Block1_4Exit [label="FunctionReturn[v78]"]; // Block1_4 -> Block1_4Exit; // Block1_6 [label="\ // Block 6; (3, max 4)\nLiveIn: \l\ @@ -118,11 +120,11 @@ // Block1_6Exit [label="Jump" shape=oval]; // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ -// Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// Block 7; (5, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv14 := eq(1, v8)\l\ // "]; // Block1_7 -> Block1_7Exit; -// Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_7Exit [label="{ If v14 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_7Exit:0 -> Block1_10 [style="solid"]; // Block1_7Exit:1 -> Block1_9 [style="solid"]; // Block1_9 [label="\ @@ -132,11 +134,11 @@ // Block1_9Exit [label="FunctionReturn[0]"]; // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ -// Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// Block 10; (7, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6,v8\l\nv21 := eq(2, v8)\l\ // "]; // Block1_10 -> Block1_10Exit; -// Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_10Exit [label="{ If v21 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_10Exit:0 -> Block1_13 [style="solid"]; // Block1_10Exit:1 -> Block1_12 [style="solid"]; // Block1_12 [label="\ @@ -147,31 +149,31 @@ // Block1_12Exit [label="Terminated"]; // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ -// Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// Block 13; (9, max 17)\nLiveIn: v0,v1,v6,v8\l\ +// LiveOut: v0,v1,v6\l\nv26 := eq(3, v8)\l\ // "]; // Block1_13 -> Block1_13Exit; -// Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_13Exit [label="{ If v26 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_13Exit:0 -> Block1_16 [style="solid"]; // Block1_13Exit:1 -> Block1_15 [style="solid"]; // Block1_15 [label="\ -// Block 15; (10, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2056, 8)\l\ +// Block 15; (10, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2056, 8)\l\ // "]; // Block1_15 -> Block1_15Exit [arrowhead=none]; // Block1_15Exit [label="Jump" shape=oval]; // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ -// Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// Block 16; (15, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nv30 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; -// Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_16Exit [label="{ If v30 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_16Exit:0 -> Block1_18 [style="solid"]; // Block1_16Exit:1 -> Block1_17 [style="solid"]; // Block1_5 [label="\ -// Block 5; (11, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2827, 11)\l\ +// Block 5; (11, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2827, 11)\l\ // "]; // Block1_5 -> Block1_5Exit [arrowhead=none]; // Block1_5Exit [label="Jump" shape=oval]; @@ -183,30 +185,30 @@ // Block1_17Exit [label="Terminated"]; // Block1_17 -> Block1_17Exit; // Block1_18 [label="\ -// Block 18; (17, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nsstore(2570, 10)\l\ +// Block 18; (17, max 17)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v6\l\nsstore(2570, 10)\l\ // "]; // Block1_18 -> Block1_18Exit [arrowhead=none]; // Block1_18Exit [label="Jump" shape=oval]; // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ -// Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ -// v44 := calldataload(v43)\l\ +// Block 3; (12, max 14)\nLiveIn: v0,v1,v6\l\ +// LiveOut: v0,v1,v44\l\nv44 := add(1, v6)\l\ +// v45 := calldataload(v44)\l\ // "]; // Block1_3 -> Block1_3Exit; -// Block1_3Exit [label="{ If v44 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block1_3Exit [label="{ If v45 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block1_3Exit:0 -> Block1_21 [style="solid"]; // Block1_3Exit:1 -> Block1_20 [style="solid"]; // Block1_20 [label="\ -// Block 20; (13, max 13)\nLiveIn: v43\l\ -// LiveOut: \l\nsstore(v43, 0)\l\ +// Block 20; (13, max 13)\nLiveIn: v44\l\ +// LiveOut: \l\nsstore(v44, 0)\l\ // "]; // Block1_20Exit [label="FunctionReturn[0]"]; // Block1_20 -> Block1_20Exit; // Block1_21 [label="\ -// Block 21; (14, max 14)\nLiveIn: v0,v1,v43\l\ -// LiveOut: v0,v1,v43\l\nsstore(65535, 255)\l\ +// Block 21; (14, max 14)\nLiveIn: v0,v1,v44\l\ +// LiveOut: v0,v1,v44\l\nsstore(65535, 255)\l\ // "]; // Block1_21 -> Block1_21Exit [arrowhead=none]; // Block1_21Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/function.yul b/test/libyul/yulSSAControlFlowGraph/function.yul index acf1a37aa43f..e2d8c1d52328 100644 --- a/test/libyul/yulSSAControlFlowGraph/function.yul +++ b/test/libyul/yulSSAControlFlowGraph/function.yul @@ -67,7 +67,9 @@ // FunctionEntry_i_0 -> Block4_0; // Block4_0 [label="\ // Block 0; (0, max 0)\nLiveIn: \l\ -// LiveOut: \l\n"]; -// Block4_0Exit [label="FunctionReturn[514, 771]"]; +// LiveOut: v2,v4\l\nv2 := 514\l\ +// v4 := 771\l\ +// "]; +// Block4_0Exit [label="FunctionReturn[v2, v4]"]; // Block4_0 -> Block4_0Exit; // } diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index b088e3b55ed8..f57a5ca29a5b 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -27,25 +27,27 @@ // Entry0 -> Block0_0; // Block0_0 [label="\ // Block 0; (0, max 24)\nLiveIn: \l\ -// LiveOut: \l\n"]; +// LiveOut: v1\l\nv1 := 0\l\ +// "]; // Block0_0 -> Block0_0Exit [arrowhead=none]; // Block0_0Exit [label="Jump" shape=oval]; // Block0_0Exit -> Block0_1 [style="solid"]; // Block0_1 [label="\ -// Block 1; (1, max 24)\nLiveIn: v2\l\ -// LiveOut: v2\l\nv2 := φ(\l\ -// Block 0 => 0,\l\ -// Block 3 => v36\l\ +// Block 1; (1, max 24)\nLiveIn: v3\l\ +// LiveOut: v3\l\nv3 := φ(\l\ +// Block 0 => v1,\l\ +// Block 3 => v41\l\ // )\l\ -// v3 := lt(3, v2)\l\ +// v4 := lt(3, v3)\l\ // "]; // Block0_1 -> Block0_1Exit; -// Block0_1Exit [label="{ If v3 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_1Exit [label="{ If v4 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_1Exit:0 -> Block0_4 [style="solid"]; // Block0_1Exit:1 -> Block0_2 [style="solid"]; // Block0_2 [label="\ -// Block 2; (2, max 23)\nLiveIn: v2\l\ -// LiveOut: v2\l\n"]; +// Block 2; (2, max 23)\nLiveIn: v3\l\ +// LiveOut: v3,v5\l\nv5 := 0\l\ +// "]; // Block0_2 -> Block0_2Exit [arrowhead=none]; // Block0_2Exit [label="Jump" shape=oval]; // Block0_2Exit -> Block0_5 [style="solid"]; @@ -55,164 +57,167 @@ // Block0_4Exit [label="MainExit"]; // Block0_4 -> Block0_4Exit; // Block0_5 [label="\ -// Block 5; (3, max 23)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\nv4 := φ(\l\ -// Block 2 => 0,\l\ -// Block 7 => v35\l\ +// Block 5; (3, max 23)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v6\l\nv6 := φ(\l\ +// Block 2 => v5,\l\ +// Block 7 => v40\l\ // )\l\ -// v5 := lt(3, v4)\l\ +// v7 := lt(3, v6)\l\ // "]; // Block0_5 -> Block0_5Exit; -// Block0_5Exit [label="{ If v5 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_5Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_5Exit:0 -> Block0_8 [style="solid"]; // Block0_5Exit:1 -> Block0_6 [style="solid"]; // Block0_6 [label="\ -// Block 6; (4, max 21)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\n"]; +// Block 6; (4, max 21)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v6,v8\l\nv8 := 0\l\ +// "]; // Block0_6 -> Block0_6Exit [arrowhead=none]; // Block0_6Exit [label="Jump" shape=oval]; // Block0_6Exit -> Block0_9 [style="solid"]; // Block0_8 [label="\ -// Block 8; (22, max 23)\nLiveIn: v2\l\ -// LiveOut: v2\l\n"]; +// Block 8; (22, max 23)\nLiveIn: v3\l\ +// LiveOut: v3\l\n"]; // Block0_8 -> Block0_8Exit [arrowhead=none]; // Block0_8Exit [label="Jump" shape=oval]; // Block0_8Exit -> Block0_3 [style="solid"]; // Block0_9 [label="\ -// Block 9; (5, max 21)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\nv6 := φ(\l\ -// Block 6 => 0,\l\ -// Block 11 => v31\l\ +// Block 9; (5, max 21)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\nv9 := φ(\l\ +// Block 6 => v8,\l\ +// Block 11 => v36\l\ // )\l\ -// v7 := lt(3, v6)\l\ +// v10 := lt(3, v9)\l\ // "]; // Block0_9 -> Block0_9Exit; -// Block0_9Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_9Exit [label="{ If v10 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_9Exit:0 -> Block0_12 [style="solid"]; // Block0_9Exit:1 -> Block0_10 [style="solid"]; // Block0_3 [label="\ -// Block 3; (23, max 23)\nLiveIn: v2\l\ -// LiveOut: v36\l\nv36 := add(1, v2)\l\ +// Block 3; (23, max 23)\nLiveIn: v3\l\ +// LiveOut: v41\l\nv41 := add(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit [arrowhead=none]; // Block0_3Exit [label="Jump" shape=oval]; // Block0_3Exit -> Block0_1 [style="dashed"]; // Block0_10 [label="\ -// Block 10; (6, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 10; (6, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_10 -> Block0_10Exit; // Block0_10Exit [label="{ If 0 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_10Exit:0 -> Block0_14 [style="solid"]; // Block0_10Exit:1 -> Block0_13 [style="solid"]; // Block0_12 [label="\ -// Block 12; (20, max 21)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\n"]; +// Block 12; (20, max 21)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v6\l\n"]; // Block0_12 -> Block0_12Exit [arrowhead=none]; // Block0_12Exit [label="Jump" shape=oval]; // Block0_12Exit -> Block0_7 [style="solid"]; // Block0_13 [label="\ -// Block 13; (7, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 13; (7, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9,v11\l\nv11 := 0\l\ +// "]; // Block0_13 -> Block0_13Exit [arrowhead=none]; // Block0_13Exit [label="Jump" shape=oval]; // Block0_13Exit -> Block0_15 [style="solid"]; // Block0_14 [label="\ -// Block 14; (12, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 14; (12, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_14 -> Block0_14Exit; // Block0_14Exit [label="{ If 1 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_14Exit:0 -> Block0_20 [style="solid"]; // Block0_14Exit:1 -> Block0_19 [style="solid"]; // Block0_7 [label="\ -// Block 7; (21, max 21)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v35\l\nv35 := add(1, v4)\l\ +// Block 7; (21, max 21)\nLiveIn: v3,v6\l\ +// LiveOut: v3,v40\l\nv40 := add(1, v6)\l\ // "]; // Block0_7 -> Block0_7Exit [arrowhead=none]; // Block0_7Exit [label="Jump" shape=oval]; // Block0_7Exit -> Block0_5 [style="dashed"]; // Block0_15 [label="\ -// Block 15; (8, max 19)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v8\l\nv8 := φ(\l\ -// Block 13 => 0,\l\ -// Block 17 => v16\l\ +// Block 15; (8, max 19)\nLiveIn: v3,v6,v9,v12\l\ +// LiveOut: v3,v6,v9,v12\l\nv12 := φ(\l\ +// Block 13 => v11,\l\ +// Block 17 => v20\l\ // )\l\ -// v9 := lt(3, v8)\l\ +// v13 := lt(3, v12)\l\ // "]; // Block0_15 -> Block0_15Exit; -// Block0_15Exit [label="{ If v9 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_15Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_15Exit:0 -> Block0_18 [style="solid"]; // Block0_15Exit:1 -> Block0_16 [style="solid"]; // Block0_19 [label="\ -// Block 19; (13, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 19; (13, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9,v23\l\nv23 := 0\l\ +// "]; // Block0_19 -> Block0_19Exit [arrowhead=none]; // Block0_19Exit [label="Jump" shape=oval]; // Block0_19Exit -> Block0_21 [style="solid"]; // Block0_20 [label="\ -// Block 20; (18, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 20; (18, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_20 -> Block0_20Exit [arrowhead=none]; // Block0_20Exit [label="Jump" shape=oval]; // Block0_20Exit -> Block0_11 [style="solid"]; // Block0_16 [label="\ -// Block 16; (9, max 10)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v8\l\nv13 := add(v4, v2)\l\ -// v14 := add(v6, v13)\l\ -// sstore(v14, v8)\l\ +// Block 16; (9, max 10)\nLiveIn: v3,v6,v9,v12\l\ +// LiveOut: v3,v6,v9,v12\l\nv17 := add(v6, v3)\l\ +// v18 := add(v9, v17)\l\ +// sstore(v18, v12)\l\ // "]; // Block0_16 -> Block0_16Exit [arrowhead=none]; // Block0_16Exit [label="Jump" shape=oval]; // Block0_16Exit -> Block0_17 [style="solid"]; // Block0_18 [label="\ -// Block 18; (11, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 18; (11, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_18 -> Block0_18Exit [arrowhead=none]; // Block0_18Exit [label="Jump" shape=oval]; // Block0_18Exit -> Block0_14 [style="solid"]; // Block0_21 [label="\ -// Block 21; (14, max 19)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v19\l\nv19 := φ(\l\ -// Block 19 => 0,\l\ -// Block 23 => v26\l\ +// Block 21; (14, max 19)\nLiveIn: v3,v6,v9,v24\l\ +// LiveOut: v3,v6,v9,v24\l\nv24 := φ(\l\ +// Block 19 => v23,\l\ +// Block 23 => v31\l\ // )\l\ -// v20 := lt(3, v19)\l\ +// v25 := lt(3, v24)\l\ // "]; // Block0_21 -> Block0_21Exit; -// Block0_21Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; +// Block0_21Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; // Block0_21Exit:0 -> Block0_24 [style="solid"]; // Block0_21Exit:1 -> Block0_22 [style="solid"]; // Block0_11 [label="\ -// Block 11; (19, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v31\l\nv31 := add(1, v6)\l\ +// Block 11; (19, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v36\l\nv36 := add(1, v9)\l\ // "]; // Block0_11 -> Block0_11Exit [arrowhead=none]; // Block0_11Exit [label="Jump" shape=oval]; // Block0_11Exit -> Block0_9 [style="dashed"]; // Block0_17 [label="\ -// Block 17; (10, max 10)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v16\l\nv16 := add(1, v8)\l\ +// Block 17; (10, max 10)\nLiveIn: v3,v6,v9,v12\l\ +// LiveOut: v3,v6,v9,v20\l\nv20 := add(1, v12)\l\ // "]; // Block0_17 -> Block0_17Exit [arrowhead=none]; // Block0_17Exit [label="Jump" shape=oval]; // Block0_17Exit -> Block0_15 [style="dashed"]; // Block0_22 [label="\ -// Block 22; (15, max 16)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v19\l\nv24 := add(v4, v2)\l\ -// v25 := add(v6, v24)\l\ -// sstore(v25, v19)\l\ +// Block 22; (15, max 16)\nLiveIn: v3,v6,v9,v24\l\ +// LiveOut: v3,v6,v9,v24\l\nv29 := add(v6, v3)\l\ +// v30 := add(v9, v29)\l\ +// sstore(v30, v24)\l\ // "]; // Block0_22 -> Block0_22Exit [arrowhead=none]; // Block0_22Exit [label="Jump" shape=oval]; // Block0_22Exit -> Block0_23 [style="solid"]; // Block0_24 [label="\ -// Block 24; (17, max 19)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\n"]; +// Block 24; (17, max 19)\nLiveIn: v3,v6,v9\l\ +// LiveOut: v3,v6,v9\l\n"]; // Block0_24 -> Block0_24Exit [arrowhead=none]; // Block0_24Exit [label="Jump" shape=oval]; // Block0_24Exit -> Block0_20 [style="solid"]; // Block0_23 [label="\ -// Block 23; (16, max 16)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v26\l\nv26 := add(1, v19)\l\ +// Block 23; (16, max 16)\nLiveIn: v3,v6,v9,v24\l\ +// LiveOut: v3,v6,v9,v31\l\nv31 := add(1, v24)\l\ // "]; // Block0_23 -> Block0_23Exit [arrowhead=none]; // Block0_23Exit [label="Jump" shape=oval]; diff --git a/test/libyul/yulSSAControlFlowGraph/nested_function.yul b/test/libyul/yulSSAControlFlowGraph/nested_function.yul index acda15ce81a5..037e1f006c45 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_function.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_function.yul @@ -78,8 +78,9 @@ // FunctionEntry_w_0 -> Block4_0; // Block4_0 [label="\ // Block 0; (0, max 0)\nLiveIn: \l\ -// LiveOut: \l\n"]; -// Block4_0Exit [label="FunctionReturn[1]"]; +// LiveOut: v2\l\nv2 := 1\l\ +// "]; +// Block4_0Exit [label="FunctionReturn[v2]"]; // Block4_0 -> Block4_0Exit; // FunctionEntry_v_0 [label="function v: // r := v()"]; @@ -95,8 +96,9 @@ // FunctionEntry_w_0 -> Block6_0; // Block6_0 [label="\ // Block 0; (0, max 0)\nLiveIn: \l\ -// LiveOut: \l\n"]; -// Block6_0Exit [label="FunctionReturn[17]"]; +// LiveOut: v2\l\nv2 := 17\l\ +// "]; +// Block6_0Exit [label="FunctionReturn[v2]"]; // Block6_0 -> Block6_0Exit; // FunctionEntry_cycle1_0 [label="function cycle1: // r := cycle1()"];