diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2019-01-17 21:57:55 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2019-01-18 03:37:43 +0800 |
commit | fd1658572463a246f602ae0fe161430429daa9e0 (patch) | |
tree | 40f3c0e5adf7a424e35b1218376a9ae9f7129811 /libyul | |
parent | 6de2d92f20d48d38797a628ee35e7615170cd63f (diff) | |
download | dexon-solidity-fd1658572463a246f602ae0fe161430429daa9e0.tar.gz dexon-solidity-fd1658572463a246f602ae0fe161430429daa9e0.tar.zst dexon-solidity-fd1658572463a246f602ae0fe161430429daa9e0.zip |
Undo second SSA transformation and add more tests.
Diffstat (limited to 'libyul')
-rw-r--r-- | libyul/optimiser/SSAReverser.cpp | 88 | ||||
-rw-r--r-- | libyul/optimiser/SSAReverser.h | 15 |
2 files changed, 74 insertions, 29 deletions
diff --git a/libyul/optimiser/SSAReverser.cpp b/libyul/optimiser/SSAReverser.cpp index 313a677a..2cfa3d58 100644 --- a/libyul/optimiser/SSAReverser.cpp +++ b/libyul/optimiser/SSAReverser.cpp @@ -29,42 +29,74 @@ void SSAReverser::operator()(Block& _block) _block.statements, [&](Statement& _stmt1, Statement& _stmt2) -> boost::optional<vector<Statement>> { + auto* varDecl = boost::get<VariableDeclaration>(&_stmt1); + + if (!varDecl || varDecl->variables.size() != 1 || !varDecl->value) + return {}; + // Replaces // let a_1 := E // a := a_1 // with // a := E // let a_1 := a - - auto* varDecl = boost::get<VariableDeclaration>(&_stmt1); - auto* assignment = boost::get<Assignment>(&_stmt2); - - if (!varDecl || !assignment) - return {}; - - auto* identifier = boost::get<Identifier>(assignment->value.get()); - - if ( - varDecl->variables.size() == 1 && - varDecl->value && - assignment->variableNames.size() == 1 && - identifier && - identifier->name == varDecl->variables.front().name - ) + if (auto* assignment = boost::get<Assignment>(&_stmt2)) + { + auto* identifier = boost::get<Identifier>(assignment->value.get()); + if ( + assignment->variableNames.size() == 1 && + identifier && + identifier->name == varDecl->variables.front().name + ) + { + vector<Statement> result; + result.emplace_back(Assignment{ + std::move(assignment->location), + assignment->variableNames, + std::move(varDecl->value) + }); + result.emplace_back(VariableDeclaration{ + std::move(varDecl->location), + std::move(varDecl->variables), + std::make_unique<Expression>(std::move(assignment->variableNames.front())) + }); + return { std::move(result) }; + } + } + // Replaces + // let a_1 := E + // let a := a_1 + // with + // let a := E + // let a_1 := a + else if (auto* varDecl2 = boost::get<VariableDeclaration>(&_stmt2)) { - vector<Statement> result; - result.emplace_back(Assignment{ - std::move(assignment->location), - assignment->variableNames, - std::move(varDecl->value) - }); - result.emplace_back(VariableDeclaration{ - std::move(varDecl->location), - std::move(varDecl->variables), - std::make_unique<Expression>(std::move(assignment->variableNames.front())) - }); - return { std::move(result) }; + auto* identifier = boost::get<Identifier>(varDecl2->value.get()); + if ( + varDecl2->variables.size() == 1 && + identifier && + identifier->name == varDecl->variables.front().name + ) + { + vector<Statement> result; + auto varIdentifier2 = std::make_unique<Expression>(Identifier{ + varDecl2->variables.front().location, + varDecl2->variables.front().name + }); + result.emplace_back(VariableDeclaration{ + std::move(varDecl2->location), + std::move(varDecl2->variables), + std::move(varDecl->value) + }); + result.emplace_back(VariableDeclaration{ + std::move(varDecl->location), + std::move(varDecl->variables), + std::move(varIdentifier2) + }); + return { std::move(result) }; + } } + return {}; } ); diff --git a/libyul/optimiser/SSAReverser.h b/libyul/optimiser/SSAReverser.h index a4a11074..34b61647 100644 --- a/libyul/optimiser/SSAReverser.h +++ b/libyul/optimiser/SSAReverser.h @@ -33,11 +33,24 @@ namespace yul * let a_1 := E * a := a_1 * - * To undo this transformation, the SSAReverser changes this back to + * To undo this kind of transformation, the SSAReverser changes this back to * * a := E * let a_1 := a * + * Secondly, the SSA transform will rewrite + * + * let a := E + * to + * + * let a_1 := E + * let a := a_1 + * + * To undo this kind of transformation, the SSAReverser changes this back to + * + * let a := E + * let a_1 := a + * * After that the CSE can replace references of a_1 by references to a, * after which the unused pruner can remove the declaration of a_1. * |