From 49d914a3919b0e861e333c7bb577b8c016d161c6 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 11 Mar 2019 17:30:46 +0100 Subject: [PATCH] Fix and test yul stack optimization flag for commandline interface. --- libyul/AssemblyStack.h | 2 +- solc/CommandLineInterface.cpp | 2 +- test/cmdlineTests.sh | 2 + test/cmdlineTests/object_compiler/output | 1 - test/cmdlineTests/yul_stack_opt/args | 1 + test/cmdlineTests/yul_stack_opt/input.sol | 24 +++ test/cmdlineTests/yul_stack_opt/output | 202 ++++++++++++++++++ test/cmdlineTests/yul_stack_opt_disabled/args | 1 + test/cmdlineTests/yul_stack_opt_disabled/err | 5 + test/cmdlineTests/yul_stack_opt_disabled/exit | 1 + .../yul_stack_opt_disabled/input.sol | 24 +++ .../yul_stack_opt_disabled/output | 31 +++ test/libsolidity/InlineAssembly.cpp | 3 +- test/libyul/ObjectCompilerTest.cpp | 2 +- 14 files changed, 296 insertions(+), 5 deletions(-) create mode 100644 test/cmdlineTests/yul_stack_opt/args create mode 100644 test/cmdlineTests/yul_stack_opt/input.sol create mode 100644 test/cmdlineTests/yul_stack_opt/output create mode 100644 test/cmdlineTests/yul_stack_opt_disabled/args create mode 100644 test/cmdlineTests/yul_stack_opt_disabled/err create mode 100644 test/cmdlineTests/yul_stack_opt_disabled/exit create mode 100644 test/cmdlineTests/yul_stack_opt_disabled/input.sol create mode 100644 test/cmdlineTests/yul_stack_opt_disabled/output diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 4484c546c..8a30ebfcb 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -74,7 +74,7 @@ public: /// Run the assembly step (should only be called after parseAndAnalyze). /// @param _optimize does not run the optimizer but performs optimized code generation. - MachineAssemblyObject assemble(Machine _machine, bool _optimize = false) const; + MachineAssemblyObject assemble(Machine _machine, bool _optimize) const; /// @returns the errors generated during parsing, analysis (and potentially assembly). langutil::ErrorList const& errors() const { return m_errors; } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 2b762e646..ac512d4e4 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1295,7 +1295,7 @@ bool CommandLineInterface::assemble( yul::MachineAssemblyObject object; try { - object = stack.assemble(_targetMachine); + object = stack.assemble(_targetMachine, _optimize); } catch (Exception const& _exception) { diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 9a3e53111..389aed579 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -125,6 +125,8 @@ function test_solc_behaviour() sed -i -e '/^Warning: This is a pre-release compiler version, please do not use it in production./d' "$stderr_path" sed -i -e 's/ Consider adding "pragma .*$//' "$stderr_path" fi + # Remove path to cpp file + sed -i -e 's/^\(Exception while assembling:\).*/\1/' "$stderr_path" if [[ $exitCode -ne "$exit_code_expected" ]] then diff --git a/test/cmdlineTests/object_compiler/output b/test/cmdlineTests/object_compiler/output index 496ac4193..51830a0c0 100644 --- a/test/cmdlineTests/object_compiler/output +++ b/test/cmdlineTests/object_compiler/output @@ -42,7 +42,6 @@ Text representation: 0x00 /* "object_compiler/input.sol":265:295 */ return - /* "object_compiler/input.sol":29:299 */ pop stop diff --git a/test/cmdlineTests/yul_stack_opt/args b/test/cmdlineTests/yul_stack_opt/args new file mode 100644 index 000000000..20fe41eb5 --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt/args @@ -0,0 +1 @@ +--strict-assembly --optimize diff --git a/test/cmdlineTests/yul_stack_opt/input.sol b/test/cmdlineTests/yul_stack_opt/input.sol new file mode 100644 index 000000000..772a6d4df --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt/input.sol @@ -0,0 +1,24 @@ +{ + function fun() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, n3, o3, p3 + { + let a := 1 + let b := 1 + let z3 := 1 + sstore(a, b) + sstore(add(a, 1), b) + sstore(add(a, 2), b) + sstore(add(a, 3), b) + sstore(add(a, 4), b) + sstore(add(a, 5), b) + sstore(add(a, 6), b) + sstore(add(a, 7), b) + sstore(add(a, 8), b) + sstore(add(a, 9), b) + sstore(add(a, 10), b) + sstore(add(a, 11), b) + sstore(add(a, 12), b) + } + let a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1 := fun() + let a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2 := fun() + sstore(a1, a2) +} diff --git a/test/cmdlineTests/yul_stack_opt/output b/test/cmdlineTests/yul_stack_opt/output new file mode 100644 index 000000000..c8e10fe86 --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt/output @@ -0,0 +1,202 @@ + +======= yul_stack_opt/input.sol (EVM) ======= + +Pretty printed source: +object "object" { + code { + let a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1 := fun() + let a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2 := fun() + sstore(a1, a2) + function fun() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, n3, o3, p3 + { + let a := 1 + sstore(a, a) + sstore(2, a) + sstore(3, a) + sstore(4, a) + sstore(5, a) + sstore(6, a) + sstore(7, a) + sstore(8, a) + sstore(9, a) + sstore(10, a) + sstore(11, a) + sstore(12, a) + sstore(13, a) + } + } +} + + +Binary representation: +60056032565b505050505050505050505050505050601a6032565b5050505050505050505050505050508082555050609a565b60006000600060006000600060006000600060006000600060006000600060006001808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d5550909192939495969798999a9b9c9d9e9f565b + +Text representation: + /* "yul_stack_opt/input.sol":495:500 */ + tag_1 + jump(tag_2) +tag_1: + /* "yul_stack_opt/input.sol":425:500 */ + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + /* "yul_stack_opt/input.sol":572:577 */ + tag_3 + jump(tag_2) +tag_3: + /* "yul_stack_opt/input.sol":502:577 */ + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + pop + /* "yul_stack_opt/input.sol":590:592 */ + dup1 + /* "yul_stack_opt/input.sol":586:588 */ + dup3 + /* "yul_stack_opt/input.sol":579:593 */ + sstore + pop + pop + /* "yul_stack_opt/input.sol":3:423 */ + jump(tag_4) +tag_2: + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + 0x00 + /* "yul_stack_opt/input.sol":98:99 */ + 0x01 + /* "yul_stack_opt/input.sol":139:140 */ + dup1 + /* "yul_stack_opt/input.sol":136:137 */ + dup2 + /* "yul_stack_opt/input.sol":129:141 */ + sstore + /* "yul_stack_opt/input.sol":162:163 */ + dup1 + /* "yul_stack_opt/input.sol":151:160 */ + 0x02 + /* "yul_stack_opt/input.sol":144:164 */ + sstore + /* "yul_stack_opt/input.sol":185:186 */ + dup1 + /* "yul_stack_opt/input.sol":174:183 */ + 0x03 + /* "yul_stack_opt/input.sol":167:187 */ + sstore + /* "yul_stack_opt/input.sol":208:209 */ + dup1 + /* "yul_stack_opt/input.sol":197:206 */ + 0x04 + /* "yul_stack_opt/input.sol":190:210 */ + sstore + /* "yul_stack_opt/input.sol":231:232 */ + dup1 + /* "yul_stack_opt/input.sol":220:229 */ + 0x05 + /* "yul_stack_opt/input.sol":213:233 */ + sstore + /* "yul_stack_opt/input.sol":254:255 */ + dup1 + /* "yul_stack_opt/input.sol":243:252 */ + 0x06 + /* "yul_stack_opt/input.sol":236:256 */ + sstore + /* "yul_stack_opt/input.sol":277:278 */ + dup1 + /* "yul_stack_opt/input.sol":266:275 */ + 0x07 + /* "yul_stack_opt/input.sol":259:279 */ + sstore + /* "yul_stack_opt/input.sol":300:301 */ + dup1 + /* "yul_stack_opt/input.sol":289:298 */ + 0x08 + /* "yul_stack_opt/input.sol":282:302 */ + sstore + /* "yul_stack_opt/input.sol":323:324 */ + dup1 + /* "yul_stack_opt/input.sol":312:321 */ + 0x09 + /* "yul_stack_opt/input.sol":305:325 */ + sstore + /* "yul_stack_opt/input.sol":346:347 */ + dup1 + /* "yul_stack_opt/input.sol":335:344 */ + 0x0a + /* "yul_stack_opt/input.sol":328:348 */ + sstore + /* "yul_stack_opt/input.sol":370:371 */ + dup1 + /* "yul_stack_opt/input.sol":358:368 */ + 0x0b + /* "yul_stack_opt/input.sol":351:372 */ + sstore + /* "yul_stack_opt/input.sol":394:395 */ + dup1 + /* "yul_stack_opt/input.sol":382:392 */ + 0x0c + /* "yul_stack_opt/input.sol":375:396 */ + sstore + /* "yul_stack_opt/input.sol":418:419 */ + dup1 + /* "yul_stack_opt/input.sol":406:416 */ + 0x0d + /* "yul_stack_opt/input.sol":399:420 */ + sstore + pop + /* "yul_stack_opt/input.sol":85:423 */ + swap1 + swap2 + swap3 + swap4 + swap5 + swap6 + swap7 + swap8 + swap9 + swap10 + swap11 + swap12 + swap13 + swap14 + swap15 + swap16 + jump +tag_4: + diff --git a/test/cmdlineTests/yul_stack_opt_disabled/args b/test/cmdlineTests/yul_stack_opt_disabled/args new file mode 100644 index 000000000..2c89c24e0 --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt_disabled/args @@ -0,0 +1 @@ +--strict-assembly diff --git a/test/cmdlineTests/yul_stack_opt_disabled/err b/test/cmdlineTests/yul_stack_opt_disabled/err new file mode 100644 index 000000000..6959bbf41 --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt_disabled/err @@ -0,0 +1,5 @@ +Exception while assembling: +Dynamic exception type: boost::exception_detail::clone_impl +std::exception::what: Variable a1 is 17 slot(s) too deep inside the stack. +[dev::tag_comment*] = Variable a1 is 17 slot(s) too deep inside the stack. + diff --git a/test/cmdlineTests/yul_stack_opt_disabled/exit b/test/cmdlineTests/yul_stack_opt_disabled/exit new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt_disabled/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/yul_stack_opt_disabled/input.sol b/test/cmdlineTests/yul_stack_opt_disabled/input.sol new file mode 100644 index 000000000..772a6d4df --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt_disabled/input.sol @@ -0,0 +1,24 @@ +{ + function fun() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, n3, o3, p3 + { + let a := 1 + let b := 1 + let z3 := 1 + sstore(a, b) + sstore(add(a, 1), b) + sstore(add(a, 2), b) + sstore(add(a, 3), b) + sstore(add(a, 4), b) + sstore(add(a, 5), b) + sstore(add(a, 6), b) + sstore(add(a, 7), b) + sstore(add(a, 8), b) + sstore(add(a, 9), b) + sstore(add(a, 10), b) + sstore(add(a, 11), b) + sstore(add(a, 12), b) + } + let a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1 := fun() + let a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2 := fun() + sstore(a1, a2) +} diff --git a/test/cmdlineTests/yul_stack_opt_disabled/output b/test/cmdlineTests/yul_stack_opt_disabled/output new file mode 100644 index 000000000..c9e3d5078 --- /dev/null +++ b/test/cmdlineTests/yul_stack_opt_disabled/output @@ -0,0 +1,31 @@ + +======= yul_stack_opt_disabled/input.sol (EVM) ======= + +Pretty printed source: +object "object" { + code { + function fun() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, n3, o3, p3 + { + let a := 1 + let b := 1 + let z3 := 1 + sstore(a, b) + sstore(add(a, 1), b) + sstore(add(a, 2), b) + sstore(add(a, 3), b) + sstore(add(a, 4), b) + sstore(add(a, 5), b) + sstore(add(a, 6), b) + sstore(add(a, 7), b) + sstore(add(a, 8), b) + sstore(add(a, 9), b) + sstore(add(a, 10), b) + sstore(add(a, 11), b) + sstore(add(a, 12), b) + } + let a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1 := fun() + let a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2 := fun() + sstore(a1, a2) + } +} + diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 7e5c47cf2..149f7679c 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -66,8 +66,9 @@ boost::optional parseAndReturnFirstError( try { success = stack.parseAndAnalyze("", _source); + bool const optimize = false; if (success && _assemble) - stack.assemble(_machine); + stack.assemble(_machine, optimize); } catch (FatalError const&) { diff --git a/test/libyul/ObjectCompilerTest.cpp b/test/libyul/ObjectCompilerTest.cpp index c710cfd4b..4c4315733 100644 --- a/test/libyul/ObjectCompilerTest.cpp +++ b/test/libyul/ObjectCompilerTest.cpp @@ -74,7 +74,7 @@ bool ObjectCompilerTest::run(ostream& _stream, string const& _linePrefix, bool c if (m_optimize) stack.optimize(); - MachineAssemblyObject obj = stack.assemble(AssemblyStack::Machine::EVM); + MachineAssemblyObject obj = stack.assemble(AssemblyStack::Machine::EVM, m_optimize); solAssert(obj.bytecode, ""); m_obtainedResult = "Assembly:\n" + obj.assembly;