CommandLineInterface: Make --yul-optimizations work in strict assembly mode

This commit is contained in:
Kamil Śliwak 2020-05-08 18:20:14 +02:00
parent 5d4b9022f0
commit 6a58227830
10 changed files with 217 additions and 13 deletions

View File

@ -5,6 +5,7 @@ Language Features:
Compiler Features:
* Commandline Interface: Don't ignore `--yul-optimizations` in assembly mode.

View File

@ -1041,8 +1041,7 @@ Optimization step sequence
--------------------------
By default the Yul optimizer applies its predefined sequence of optimization steps to the generated assembly.
You can override this sequence and supply your own using the `--yul-optimizations` option when compiling
in Solidity mode:
You can override this sequence and supply your own using the `--yul-optimizations` option:
.. code-block:: sh

View File

@ -787,19 +787,19 @@ Allowed options)").c_str(),
(
g_argAssemble.c_str(),
("Switch to assembly mode, ignoring all options except "
"--" + g_argMachine + ", --" + g_strYulDialect + " and --" + g_argOptimize + " "
"--" + g_argMachine + ", --" + g_strYulDialect + ", --" + g_argOptimize + " and --" + g_strYulOptimizations + " "
"and assumes input is assembly.").c_str()
)
(
g_argYul.c_str(),
("Switch to Yul mode, ignoring all options except "
"--" + g_argMachine + ", --" + g_strYulDialect + " and --" + g_argOptimize + " "
"--" + g_argMachine + ", --" + g_strYulDialect + ", --" + g_argOptimize + " and --" + g_strYulOptimizations + " "
"and assumes input is Yul.").c_str()
)
(
g_argStrictAssembly.c_str(),
("Switch to strict assembly mode, ignoring all options except "
"--" + g_argMachine + ", --" + g_strYulDialect + " and --" + g_argOptimize + " "
"--" + g_argMachine + ", --" + g_strYulDialect + ", --" + g_argOptimize + " and --" + g_strYulOptimizations + " "
"and assumes input is strict assembly.").c_str()
)
(
@ -1079,6 +1079,29 @@ bool CommandLineInterface::processInput()
serr() << "--" << g_strNoOptimizeYul << " is invalid in assembly mode. Optimization is disabled by default and can be enabled with --" << g_argOptimize << "." << endl;
return false;
}
optional<string> yulOptimiserSteps;
if (m_args.count(g_strYulOptimizations))
{
if (!optimize)
{
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;
}
yulOptimiserSteps = m_args[g_strYulOptimizations].as<string>();
}
if (m_args.count(g_argMachine))
{
string machine = m_args[g_argMachine].as<string>();
@ -1130,7 +1153,7 @@ bool CommandLineInterface::processInput()
"Warning: Yul is still experimental. Please use the output with care." <<
endl;
return assemble(inputLanguage, targetMachine, optimize);
return assemble(inputLanguage, targetMachine, optimize, yulOptimiserSteps);
}
if (m_args.count(g_argLink))
{
@ -1542,18 +1565,21 @@ string CommandLineInterface::objectWithLinkRefsHex(evmasm::LinkerObject const& _
bool CommandLineInterface::assemble(
yul::AssemblyStack::Language _language,
yul::AssemblyStack::Machine _targetMachine,
bool _optimize
bool _optimize,
optional<string> _yulOptimiserSteps
)
{
solAssert(_optimize || !_yulOptimiserSteps.has_value(), "");
bool successful = true;
map<string, yul::AssemblyStack> assemblyStacks;
for (auto const& src: m_sourceCodes)
{
auto& stack = assemblyStacks[src.first] = yul::AssemblyStack(
m_evmVersion,
_language,
_optimize ? OptimiserSettings::full() : OptimiserSettings::minimal()
);
OptimiserSettings settings = _optimize ? OptimiserSettings::full() : OptimiserSettings::minimal();
if (_yulOptimiserSteps.has_value())
settings.yulOptimiserSteps = _yulOptimiserSteps.value();
auto& stack = assemblyStacks[src.first] = yul::AssemblyStack(m_evmVersion, _language, settings);
try
{
if (!stack.parseAndAnalyze(src.first, src.second))

View File

@ -56,7 +56,12 @@ private:
/// @returns the full object with library placeholder hints in hex.
static std::string objectWithLinkRefsHex(evmasm::LinkerObject const& _obj);
bool assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine, bool _optimize);
bool assemble(
yul::AssemblyStack::Language _language,
yul::AssemblyStack::Machine _targetMachine,
bool _optimize,
std::optional<std::string> _yulOptimiserSteps = std::nullopt
);
void outputCompilationResults();

View File

@ -0,0 +1,26 @@
{
"language": "Yul",
"sources":
{
"A":
{
"content": "{ let x := mload(0) sstore(add(x, 0), 0) }"
}
},
"settings":
{
"optimizer": {
"enabled": true,
"details": {
"yul": true,
"yulDetails": {
"optimizerSteps": "dhfoDgvulfnTUtnIf"
}
}
},
"outputSelection":
{
"*": { "*": ["*"], "": [ "*" ] }
}
}
}

View File

@ -0,0 +1,30 @@
{"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":17:18 */
0x00
/* \"A\":11:19 */
mload
/* \"A\":38:39 */
0x00
/* \"A\":34:35 */
0x00
/* \"A\":31:32 */
dup3
/* \"A\":27:36 */
add
/* \"A\":20:40 */
sstore
pop
","bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}},"ir":"object \"object\" {
code {
let x := mload(0)
sstore(add(x, 0), 0)
}
}
","irOptimized":"object \"object\" {
code {
{
let x := mload(0)
sstore(add(x, 0), 0)
}
}
}
"}}},"errors":[{"component":"general","formattedMessage":"Yul is still experimental. Please use the output with care.","message":"Yul is still experimental. Please use the output with care.","severity":"warning","type":"Warning"}]}

View File

@ -0,0 +1 @@
--strict-assembly --optimize --yul-optimizations dhfoDgvulfnTUtnIf

View File

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

View File

@ -0,0 +1,27 @@
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,88 @@
======= strict_asm_optimizer_steps/input.yul (EVM) =======
Pretty printed source:
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)
pop(iszero(lt(calldatasize(), 4)))
revert(0, 0)
}
}
}
}
Binary representation:
60806040523415600f5760006000fd5b6010601d60003960106000f3fe608060405260043610155060006000fd
Text representation:
/* "strict_asm_optimizer_steps/input.yul":45:48 */
0x80
/* "strict_asm_optimizer_steps/input.yul":41:43 */
0x40
/* "strict_asm_optimizer_steps/input.yul":34:49 */
mstore
/* "strict_asm_optimizer_steps/input.yul":61:72 */
callvalue
/* "strict_asm_optimizer_steps/input.yul":58:60 */
iszero
tag_1
jumpi
/* "strict_asm_optimizer_steps/input.yul":85:86 */
0x00
/* "strict_asm_optimizer_steps/input.yul":82:83 */
0x00
/* "strict_asm_optimizer_steps/input.yul":75:87 */
revert
/* "strict_asm_optimizer_steps/input.yul":58:60 */
tag_1:
/* "strict_asm_optimizer_steps/input.yul":98:163 */
dataSize(sub_0)
dataOffset(sub_0)
/* "strict_asm_optimizer_steps/input.yul":107:108 */
0x00
/* "strict_asm_optimizer_steps/input.yul":98:163 */
codecopy
/* "strict_asm_optimizer_steps/input.yul":172:207 */
dataSize(sub_0)
/* "strict_asm_optimizer_steps/input.yul":179:180 */
0x00
/* "strict_asm_optimizer_steps/input.yul":172:207 */
return
stop
sub_0: assembly {
/* "strict_asm_optimizer_steps/input.yul":298:301 */
0x80
/* "strict_asm_optimizer_steps/input.yul":294:296 */
0x40
/* "strict_asm_optimizer_steps/input.yul":287:302 */
mstore
/* "strict_asm_optimizer_steps/input.yul":348:349 */
0x04
/* "strict_asm_optimizer_steps/input.yul":332:346 */
calldatasize
/* "strict_asm_optimizer_steps/input.yul":329:350 */
lt
/* "strict_asm_optimizer_steps/input.yul":322:351 */
iszero
/* "strict_asm_optimizer_steps/input.yul":319:321 */
pop
/* "strict_asm_optimizer_steps/input.yul":570:571 */
0x00
/* "strict_asm_optimizer_steps/input.yul":567:568 */
0x00
/* "strict_asm_optimizer_steps/input.yul":560:572 */
revert
}