CommandLineParser: Handle --optimize-runs option in assembly mode

Fixes #11708.
This commit is contained in:
jaa2 2021-07-28 10:53:19 -05:00 committed by hrkrshnn
parent 1794e1c837
commit c627e6af10
12 changed files with 88 additions and 5 deletions

View File

@ -22,6 +22,7 @@ Bugfixes:
* Yul Code Generator: Fix internal compiler error when using a long literal with bitwise negation.
* Yul Code Generator: Fix source location references for calls to builtin functions.
* Yul Parser: Fix source location references for ``if`` statements.
* Commandline Interface: Apply ``--optimizer-runs`` option in assembly / yul mode.
### 0.8.6 (2021-06-22)

View File

@ -49,6 +49,8 @@ differences, for example, functions may be inlined, combined, or rewritten to el
redundancies, etc. (compare the output between the flags ``--ir`` and
``--optimize --ir-optimized``).
.. _optimizer-parameter-runs:
Optimizer Parameter Runs
========================

View File

@ -1177,11 +1177,13 @@ intermediate states. This allows for easy debugging and verification of the opti
Please refer to the general :ref:`optimizer documentation <optimizer>`
for more details about the different optimization stages and how to use the optimizer.
If you want to use Solidity in stand-alone Yul mode, you activate the optimizer using ``--optimize``:
If you want to use Solidity in stand-alone Yul mode, you activate the optimizer using ``--optimize``
and optionally specify the :ref:`expected number of contract executions <optimizer-parameter-runs>` with
``--optimize-runs``:
.. code-block:: sh
solc --strict-assembly --optimize
solc --strict-assembly --optimize --optimize-runs 200
In Solidity mode, the Yul optimizer is activated together with the regular optimizer.

View File

@ -555,6 +555,7 @@ bool CommandLineInterface::processInput()
m_options.assembly.inputLanguage,
m_options.assembly.targetMachine,
m_options.optimizer.enabled,
m_options.optimizer.expectedExecutionsPerDeployment,
m_options.optimizer.yulSteps
);
}
@ -595,7 +596,8 @@ bool CommandLineInterface::compile()
m_compiler->enableEwasmGeneration(m_options.compiler.outputs.ewasm);
OptimiserSettings settings = m_options.optimizer.enabled ? OptimiserSettings::standard() : OptimiserSettings::minimal();
settings.expectedExecutionsPerDeployment = m_options.optimizer.expectedExecutionsPerDeployment;
if (m_options.optimizer.expectedExecutionsPerDeployment.has_value())
settings.expectedExecutionsPerDeployment = m_options.optimizer.expectedExecutionsPerDeployment.value();
if (m_options.optimizer.noOptimizeYul)
settings.runYulOptimiser = false;
@ -941,6 +943,7 @@ bool CommandLineInterface::assemble(
yul::AssemblyStack::Language _language,
yul::AssemblyStack::Machine _targetMachine,
bool _optimize,
optional<unsigned int> _expectedExecutionsPerDeployment,
optional<string> _yulOptimiserSteps
)
{
@ -951,6 +954,8 @@ bool CommandLineInterface::assemble(
for (auto const& src: m_fileReader.sourceCodes())
{
OptimiserSettings settings = _optimize ? OptimiserSettings::full() : OptimiserSettings::minimal();
if (_expectedExecutionsPerDeployment.has_value())
settings.expectedExecutionsPerDeployment = _expectedExecutionsPerDeployment.value();
if (_yulOptimiserSteps.has_value())
settings.yulOptimiserSteps = _yulOptimiserSteps.value();

View File

@ -78,6 +78,7 @@ private:
yul::AssemblyStack::Language _language,
yul::AssemblyStack::Machine _targetMachine,
bool _optimize,
std::optional<unsigned int> _expectedExecutionsPerDeployment = std::nullopt,
std::optional<std::string> _yulOptimiserSteps = std::nullopt
);

View File

@ -967,6 +967,8 @@ General Information)").c_str(),
m_options.optimizer.enabled = (m_args.count(g_strOptimize) > 0);
m_options.optimizer.noOptimizeYul = (m_args.count(g_strNoOptimizeYul) > 0);
m_options.optimizer.expectedExecutionsPerDeployment = m_args.at(g_strOptimizeRuns).as<unsigned>();
if (m_args.count(g_strYulOptimizations))
{
if (!m_options.optimizer.enabled)

View File

@ -159,7 +159,7 @@ struct CommandLineOptions
struct
{
bool enabled = false;
unsigned expectedExecutionsPerDeployment = 0;
std::optional<unsigned> expectedExecutionsPerDeployment;
bool noOptimizeYul = false;
std::optional<std::string> yulSteps;
} optimizer;

View File

@ -0,0 +1 @@
--yul --yul-dialect evm --optimize --ir-optimized --optimize-runs 10000

View File

@ -0,0 +1 @@
Warning: Yul is still experimental. Please use the output with care.

View File

@ -0,0 +1,13 @@
object "RunsTest1" {
code {
// Deploy the contract
datacopy(0, dataoffset("Runtime"), datasize("Runtime"))
return(0, datasize("Runtime"))
}
object "Runtime" {
code {
let funcSel := shl(224, 0xabc12345)
mstore(0, funcSel)
}
}
}

View File

@ -0,0 +1,52 @@
======= yul_optimize_runs/input.yul (EVM) =======
Pretty printed source:
object "RunsTest1" {
code {
{
let _1 := datasize("Runtime")
datacopy(0, dataoffset("Runtime"), _1)
return(0, _1)
}
}
object "Runtime" {
code {
{
mstore(0, 0xabc1234500000000000000000000000000000000000000000000000000000000)
}
}
}
}
Binary representation:
602480600d600039806000f3fe7fabc1234500000000000000000000000000000000000000000000000000000000600052
Text representation:
/* "yul_optimize_runs/input.yul":106:125 */
dataSize(sub_0)
dup1
/* "yul_optimize_runs/input.yul":83:104 */
dataOffset(sub_0)
/* "yul_optimize_runs/input.yul":80:81 */
0x00
/* "yul_optimize_runs/input.yul":71:126 */
codecopy
/* "yul_optimize_runs/input.yul":145:164 */
dup1
/* "yul_optimize_runs/input.yul":80:81 */
0x00
/* "yul_optimize_runs/input.yul":135:165 */
return
stop
sub_0: assembly {
/* "yul_optimize_runs/input.yul":237:257 */
0xabc1234500000000000000000000000000000000000000000000000000000000
/* "yul_optimize_runs/input.yul":277:278 */
0x00
/* "yul_optimize_runs/input.yul":270:288 */
mstore
}

View File

@ -294,7 +294,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
if (expectedLanguage == AssemblyStack::Language::StrictAssembly || expectedLanguage == AssemblyStack::Language::Ewasm)
commandLine += vector<string>{
"--optimize",
"--optimize-runs=1000", // Ignored in assembly mode
"--optimize-runs=1000",
"--yul-optimizations=agf",
};
@ -332,7 +332,10 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
{
expectedOptions.optimizer.enabled = true;
expectedOptions.optimizer.yulSteps = "agf";
expectedOptions.optimizer.expectedExecutionsPerDeployment = 1000;
}
else
expectedOptions.optimizer.expectedExecutionsPerDeployment = OptimiserSettings{}.expectedExecutionsPerDeployment;
stringstream sout, serr;
optional<CommandLineOptions> parsedOptions = parseCommandLine(commandLine, sout, serr);