Add --yul-optimizations option to the command-line interface

This commit is contained in:
Kamil Śliwak 2020-04-24 14:24:48 +02:00
parent c41a832f65
commit 35cc64e33d
20 changed files with 105 additions and 2 deletions

View File

@ -37,6 +37,7 @@
#include <libsolidity/interface/StorageLayout.h>
#include <libyul/AssemblyStack.h>
#include <libyul/optimiser/Suite.h>
#include <libevmasm/Instruction.h>
#include <libevmasm/GasMeter.h>
@ -145,6 +146,7 @@ static string const g_strOpcodes = "opcodes";
static string const g_strOptimize = "optimize";
static string const g_strOptimizeRuns = "optimize-runs";
static string const g_strOptimizeYul = "optimize-yul";
static string const g_strYulOptimizations = "yul-optimizations";
static string const g_strOutputDir = "output-dir";
static string const g_strOverwrite = "overwrite";
static string const g_strRevertStrings = "revert-strings";
@ -781,7 +783,6 @@ Allowed options)",
"Import ASTs to be compiled, assumes input holds the AST in compact JSON format. "
"Supported Inputs is the output of the --standard-json or the one produced by --combined-json ast,compact-format"
)
(
g_argAssemble.c_str(),
"Switch to assembly mode, ignoring all options except --machine, --yul-dialect and --optimize and assumes input is assembly."
@ -835,7 +836,12 @@ Allowed options)",
"Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage."
)
(g_strOptimizeYul.c_str(), "Legacy option, ignored. Use the general --optimize to enable Yul optimizer.")
(g_strNoOptimizeYul.c_str(), "Disable Yul optimizer in Solidity.");
(g_strNoOptimizeYul.c_str(), "Disable Yul optimizer in Solidity.")
(
g_strYulOptimizations.c_str(),
po::value<string>()->value_name("steps"),
"Forces yul optimizer to use the specified sequence of optimization steps instead of the built-in one."
);
desc.add(optimizerOptions);
po::options_description outputComponents("Output Components");
outputComponents.add_options()
@ -1168,6 +1174,26 @@ bool CommandLineInterface::processInput()
settings.expectedExecutionsPerDeployment = m_args[g_argOptimizeRuns].as<unsigned>();
if (m_args.count(g_strNoOptimizeYul))
settings.runYulOptimiser = false;
if (m_args.count(g_strYulOptimizations))
{
if (!settings.runYulOptimiser)
{
serr() << "--" << g_strYulOptimizations << " is invalid if Yul optimizer is disabled" << endl;
return false;
}
try
{
yul::OptimiserSuite::validateSequence(m_args[g_strYulOptimizations].as<string>());
}
catch (yul::OptimizerException const& _exception)
{
serr() << "Invalid optimizer step sequence in --" << g_strYulOptimizations << ": " << _exception.what() << endl;
return false;
}
settings.yulOptimiserSteps = m_args[g_strYulOptimizations].as<string>();
}
settings.optimizeStackAllocation = settings.runYulOptimiser;
m_compiler->setOptimiserSettings(settings);

View File

@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations dhfoDgvulfnTUtnIf

View File

@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
constructor() public {}
}

View File

@ -0,0 +1,34 @@
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "C_6" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
codecopy(0, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
return(0, datasize("C_6_deployed"))
}
}
object "C_6_deployed" {
code {
{
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
pop(selector)
}
pop(iszero(calldatasize()))
revert(0, 0)
}
function shift_right_224_unsigned(value) -> newValue
{ newValue := shr(224, value) }
}
}
}

View File

@ -0,0 +1 @@
--ir-optimized --yul-optimizations dhfoDgvulfnTUtnIf

View File

@ -0,0 +1 @@
--yul-optimizations is invalid if Yul optimizer is disabled

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}

View File

@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations abcdefg{hijklmno}pqr[st]uvwxyz

View File

@ -0,0 +1 @@
Invalid optimizer step sequence in --yul-optimizations: 'b' is not a valid step abbreviation

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}

View File

@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations a[a][aa[aa]]a

View File

@ -0,0 +1 @@
Invalid optimizer step sequence in --yul-optimizations: Nested brackets are not supported

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}

View File

@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations a[a][

View File

@ -0,0 +1 @@
Invalid optimizer step sequence in --yul-optimizations: Unbalanced brackets

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}