Block deepener

This commit is contained in:
Daniel Kirchner 2019-05-13 17:22:43 +02:00
parent d01bc4039d
commit 894df0fba9
9 changed files with 212 additions and 0 deletions

View File

@ -52,6 +52,8 @@ add_library(yul
optimiser/ASTCopier.h
optimiser/ASTWalker.cpp
optimiser/ASTWalker.h
optimiser/BlockDeepener.cpp
optimiser/BlockDeepener.h
optimiser/BlockFlattener.cpp
optimiser/BlockFlattener.h
optimiser/BlockClassFinder.cpp

View File

@ -0,0 +1,47 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libyul/optimiser/BlockDeepener.h>
#include <libyul/AsmData.h>
#include <libdevcore/Visitor.h>
#include <libdevcore/CommonData.h>
#include <functional>
using namespace std;
using namespace dev;
using namespace yul;
void BlockDeepener::operator()(Block& _block)
{
ASTModifier::operator()(_block);
if (_block.statements.size() <= 1)
return ;
std::vector<Statement> result;
std::vector<Statement> *current = &result;
for (std::size_t i = 0; i < _block.statements.size() - 1; ++i)
{
current->emplace_back(std::move(_block.statements[i]));
current->emplace_back(Block{
_block.location,
{}
});
current = &boost::get<Block>(current->back()).statements;
}
current->emplace_back(std::move(_block.statements.back()));
_block.statements = std::move(result);
}

View File

@ -0,0 +1,31 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <libyul/optimiser/ASTWalker.h>
namespace yul
{
class BlockDeepener: public ASTModifier
{
public:
using ASTModifier::operator();
void operator()(Block& _block) override;
};
}

View File

@ -19,6 +19,7 @@
#include <test/Options.h>
#include <libyul/optimiser/BlockDeepener.h>
#include <libyul/optimiser/BlockFlattener.h>
#include <libyul/optimiser/BlockOutliner.h>
#include <libyul/optimiser/VarDeclInitializer.h>
@ -112,6 +113,11 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line
if (m_optimizerStep == "disambiguator")
disambiguate();
else if (m_optimizerStep == "blockDeepener")
{
disambiguate();
BlockDeepener{}(*m_ast);
}
else if (m_optimizerStep == "blockFlattener")
{
disambiguate();

View File

@ -0,0 +1,27 @@
{
let _1 := mload(0)
let f_a := mload(1)
let f_r
f_a := mload(f_a)
f_r := add(f_a, calldatasize())
let z := mload(2)
}
// ====
// step: blockDeepener
// ----
// {
// let _1 := mload(0)
// {
// let f_a := mload(1)
// {
// let f_r
// {
// f_a := mload(f_a)
// {
// f_r := add(f_a, calldatasize())
// { let z := mload(2) }
// }
// }
// }
// }
// }

View File

@ -0,0 +1,14 @@
{
for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) }
{ a := add(a, 1) a := add(a,1) }
}
// ====
// step: blockDeepener
// ----
// {
// for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) }
// {
// a := add(a, 1)
// { a := add(a, 1) }
// }
// }

View File

@ -0,0 +1,19 @@
{
if add(mload(7), sload(mload(3)))
{
let y := add(mload(3), 3)
y := add(y, 7)
}
let t := add(3, 9)
}
// ====
// step: blockDeepener
// ----
// {
// if add(mload(7), sload(mload(3)))
// {
// let y := add(mload(3), 3)
// { y := add(y, 7) }
// }
// { let t := add(3, 9) }
// }

View File

@ -0,0 +1,35 @@
{
let a := 3
let b := 4
a := add(b, 3)
let c := 5
b := add(b, 4)
c := add(a, 5)
b := add(a, b)
a := add(a, c)
}
// ====
// step: blockDeepener
// ----
// {
// let a := 3
// {
// let b := 4
// {
// a := add(b, 3)
// {
// let c := 5
// {
// b := add(b, 4)
// {
// c := add(a, 5)
// {
// b := add(a, b)
// { a := add(a, c) }
// }
// }
// }
// }
// }
// }
// }

View File

@ -0,0 +1,31 @@
{
let a := 1
switch calldataload(0)
case 0 {
mstore(0, 1)
a := 8
}
default {
a := 3
a := 4
}
a := 5
}
// ====
// step: blockDeepener
// ----
// {
// let a := 1
// {
// switch calldataload(0)
// case 0 {
// mstore(0, 1)
// { a := 8 }
// }
// default {
// a := 3
// { a := 4 }
// }
// { a := 5 }
// }
// }