mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Run yul optimizer on user code without refs
This commit is contained in:
parent
3a4cb016ff
commit
1a3998648c
@ -20,6 +20,8 @@
|
|||||||
* Solidity compiler.
|
* Solidity compiler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <libsolidity/ast/AST.h>
|
#include <libsolidity/ast/AST.h>
|
||||||
#include <libsolidity/ast/ASTUtils.h>
|
#include <libsolidity/ast/ASTUtils.h>
|
||||||
#include <libsolidity/ast/TypeProvider.h>
|
#include <libsolidity/ast/TypeProvider.h>
|
||||||
@ -27,7 +29,16 @@
|
|||||||
#include <libsolidity/codegen/ContractCompiler.h>
|
#include <libsolidity/codegen/ContractCompiler.h>
|
||||||
#include <libsolidity/codegen/ExpressionCompiler.h>
|
#include <libsolidity/codegen/ExpressionCompiler.h>
|
||||||
|
|
||||||
|
#include <libyul/AsmAnalysisInfo.h>
|
||||||
|
#include <libyul/AsmData.h>
|
||||||
|
#include <libyul/AsmDataForward.h>
|
||||||
#include <libyul/backends/evm/AsmCodeGen.h>
|
#include <libyul/backends/evm/AsmCodeGen.h>
|
||||||
|
#include <libyul/backends/evm/EVMMetrics.h>
|
||||||
|
#include <libyul/backends/evm/EVMDialect.h>
|
||||||
|
#include <libyul/optimiser/Suite.h>
|
||||||
|
#include <libyul/Object.h>
|
||||||
|
#include <libyul/optimiser/ASTCopier.h>
|
||||||
|
#include <libyul/YulString.h>
|
||||||
|
|
||||||
#include <libevmasm/Instruction.h>
|
#include <libevmasm/Instruction.h>
|
||||||
#include <libevmasm/Assembly.h>
|
#include <libevmasm/Assembly.h>
|
||||||
@ -40,6 +51,13 @@
|
|||||||
#include <boost/range/adaptor/reversed.hpp>
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
// Change to "define" to output all intermediate code
|
||||||
|
#undef SOL_OUTPUT_ASM
|
||||||
|
#ifdef SOL_OUTPUT_ASM
|
||||||
|
#include <libyul/AsmPrinter.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::evmasm;
|
using namespace solidity::evmasm;
|
||||||
@ -788,10 +806,65 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
|||||||
_assembly.appendInstruction(Instruction::POP);
|
_assembly.appendInstruction(Instruction::POP);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
solAssert(_inlineAssembly.annotation().analysisInfo, "");
|
|
||||||
|
yul::Block const* code = &_inlineAssembly.operations();
|
||||||
|
yul::AsmAnalysisInfo* analysisInfo = _inlineAssembly.annotation().analysisInfo.get();
|
||||||
|
|
||||||
|
// Only used in the scope below, but required to live outside to keep the
|
||||||
|
// shared_ptr's alive
|
||||||
|
yul::Object object;
|
||||||
|
|
||||||
|
// The optimiser cannot handle external references
|
||||||
|
if (
|
||||||
|
m_optimiserSettings.runYulOptimiser &&
|
||||||
|
_inlineAssembly.annotation().externalReferences.empty()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Create a modifiable copy of the code and analysis
|
||||||
|
object.code = make_shared<yul::Block>(yul::ASTCopier().translate(*code));
|
||||||
|
object.analysisInfo = make_shared<yul::AsmAnalysisInfo>();
|
||||||
|
|
||||||
|
{
|
||||||
|
ErrorList errList;
|
||||||
|
ErrorReporter errorReporter{errList};
|
||||||
|
|
||||||
|
yul::AsmAnalyzer analyzer(
|
||||||
|
*object.analysisInfo,
|
||||||
|
errorReporter,
|
||||||
|
_inlineAssembly.dialect()
|
||||||
|
);
|
||||||
|
solAssert(analyzer.analyze(*object.code), "Inline analysis failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&_inlineAssembly.dialect());
|
||||||
|
solAssert(dialect, "");
|
||||||
|
|
||||||
|
#ifdef SOL_OUTPUT_ASM
|
||||||
|
cout << yul::AsmPrinter(*dialect)(*object.code) << endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool const isCreation = m_context.runtimeContext() != nullptr;
|
||||||
|
yul::GasMeter meter(*dialect, isCreation, m_optimiserSettings.expectedExecutionsPerDeployment);
|
||||||
|
yul::OptimiserSuite::run(
|
||||||
|
*dialect,
|
||||||
|
&meter,
|
||||||
|
object,
|
||||||
|
m_optimiserSettings.optimizeStackAllocation,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef SOL_OUTPUT_ASM
|
||||||
|
cout << "After optimizer:" << endl;
|
||||||
|
cout << yul::AsmPrinter(*dialect)(*object.code) << endl;
|
||||||
|
#endif
|
||||||
|
code = object.code.get();
|
||||||
|
analysisInfo = object.analysisInfo.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
solAssert(analysisInfo, "");
|
||||||
yul::CodeGenerator::assemble(
|
yul::CodeGenerator::assemble(
|
||||||
_inlineAssembly.operations(),
|
*code,
|
||||||
*_inlineAssembly.annotation().analysisInfo,
|
*analysisInfo,
|
||||||
*m_context.assemblyPtr(),
|
*m_context.assemblyPtr(),
|
||||||
m_context.evmVersion(),
|
m_context.evmVersion(),
|
||||||
identifierAccess,
|
identifierAccess,
|
||||||
|
@ -84,6 +84,7 @@ public:
|
|||||||
virtual Expression translate(Expression const& _expression);
|
virtual Expression translate(Expression const& _expression);
|
||||||
virtual Statement translate(Statement const& _statement);
|
virtual Statement translate(Statement const& _statement);
|
||||||
|
|
||||||
|
Block translate(Block const& _block);
|
||||||
protected:
|
protected:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<T> translateVector(std::vector<T> const& _values);
|
std::vector<T> translateVector(std::vector<T> const& _values);
|
||||||
@ -94,7 +95,6 @@ protected:
|
|||||||
return _v ? std::make_unique<T>(translate(*_v)) : nullptr;
|
return _v ? std::make_unique<T>(translate(*_v)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block translate(Block const& _block);
|
|
||||||
Case translate(Case const& _case);
|
Case translate(Case const& _case);
|
||||||
virtual Identifier translate(Identifier const& _identifier);
|
virtual Identifier translate(Identifier const& _identifier);
|
||||||
Literal translate(Literal const& _literal);
|
Literal translate(Literal const& _literal);
|
||||||
|
1
test/cmdlineTests/optimizer_user_yul/args
Normal file
1
test/cmdlineTests/optimizer_user_yul/args
Normal file
@ -0,0 +1 @@
|
|||||||
|
--optimize --asm --metadata-hash none
|
37
test/cmdlineTests/optimizer_user_yul/input.sol
Normal file
37
test/cmdlineTests/optimizer_user_yul/input.sol
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
pragma solidity >=0.0;
|
||||||
|
|
||||||
|
contract C
|
||||||
|
{
|
||||||
|
constructor() public payable
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
|
||||||
|
// Can't be optimized due to external reference "a"
|
||||||
|
assembly
|
||||||
|
{
|
||||||
|
let x,y,z
|
||||||
|
|
||||||
|
sstore(0, 1)
|
||||||
|
|
||||||
|
for { } sload(4) { } {
|
||||||
|
z := exp(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
a := 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can be optimized due to no external references
|
||||||
|
assembly
|
||||||
|
{
|
||||||
|
let x,y,z
|
||||||
|
|
||||||
|
sstore(2, 3)
|
||||||
|
|
||||||
|
for { } sload(5) { } {
|
||||||
|
// Expected to be optimized out for yulOptimizer, but not for
|
||||||
|
// old optimizer
|
||||||
|
z := exp(x, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
test/cmdlineTests/optimizer_user_yul/output
Normal file
87
test/cmdlineTests/optimizer_user_yul/output
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
======= optimizer_user_yul/input.sol:C =======
|
||||||
|
EVM assembly:
|
||||||
|
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||||
|
mstore(0x40, 0x80)
|
||||||
|
/* "optimizer_user_yul/input.sol":72:77 int a */
|
||||||
|
0x00
|
||||||
|
/* "optimizer_user_yul/input.sol":38:487 constructor() public payable... */
|
||||||
|
dup1
|
||||||
|
0x00
|
||||||
|
dup1
|
||||||
|
/* "optimizer_user_yul/input.sol":176:177 1 */
|
||||||
|
0x01
|
||||||
|
/* "optimizer_user_yul/input.sol":173:174 0 */
|
||||||
|
0x00
|
||||||
|
/* "optimizer_user_yul/input.sol":166:178 sstore(0, 1) */
|
||||||
|
sstore
|
||||||
|
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||||
|
tag_3:
|
||||||
|
/* "optimizer_user_yul/input.sol":197:198 4 */
|
||||||
|
0x04
|
||||||
|
/* "optimizer_user_yul/input.sol":191:199 sload(4) */
|
||||||
|
sload
|
||||||
|
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||||
|
iszero
|
||||||
|
tag_5
|
||||||
|
jumpi
|
||||||
|
pop
|
||||||
|
/* "optimizer_user_yul/input.sol":215:224 exp(x, y) */
|
||||||
|
dup1
|
||||||
|
dup3
|
||||||
|
exp
|
||||||
|
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||||
|
jump(tag_3)
|
||||||
|
tag_5:
|
||||||
|
/* "optimizer_user_yul/input.sol":187:190 { } */
|
||||||
|
pop
|
||||||
|
pop
|
||||||
|
pop
|
||||||
|
/* "optimizer_user_yul/input.sol":239:240 2 */
|
||||||
|
0x02
|
||||||
|
/* "optimizer_user_yul/input.sol":234:240 a := 2 */
|
||||||
|
swap1
|
||||||
|
pop
|
||||||
|
/* "optimizer_user_yul/input.sol":340:341 3 */
|
||||||
|
0x03
|
||||||
|
/* "optimizer_user_yul/input.sol":337:338 2 */
|
||||||
|
0x02
|
||||||
|
/* "optimizer_user_yul/input.sol":330:342 sstore(2, 3) */
|
||||||
|
sstore
|
||||||
|
/* "optimizer_user_yul/input.sol":347:480 for { } sload(5) { } {... */
|
||||||
|
tag_6:
|
||||||
|
/* "optimizer_user_yul/input.sol":361:362 5 */
|
||||||
|
0x05
|
||||||
|
/* "optimizer_user_yul/input.sol":355:363 sload(5) */
|
||||||
|
sload
|
||||||
|
tag_9
|
||||||
|
jumpi
|
||||||
|
jump(tag_8)
|
||||||
|
tag_9:
|
||||||
|
/* "optimizer_user_yul/input.sol":347:480 for { } sload(5) { } {... */
|
||||||
|
jump(tag_6)
|
||||||
|
tag_8:
|
||||||
|
/* "optimizer_user_yul/input.sol":311:484 {... */
|
||||||
|
pop
|
||||||
|
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||||
|
dataSize(sub_0)
|
||||||
|
dup1
|
||||||
|
dataOffset(sub_0)
|
||||||
|
0x00
|
||||||
|
codecopy
|
||||||
|
0x00
|
||||||
|
return
|
||||||
|
stop
|
||||||
|
|
||||||
|
sub_0: assembly {
|
||||||
|
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||||
|
mstore(0x40, 0x80)
|
||||||
|
/* "--CODEGEN--":12:13 */
|
||||||
|
0x00
|
||||||
|
/* "--CODEGEN--":9:10 */
|
||||||
|
dup1
|
||||||
|
/* "--CODEGEN--":2:14 */
|
||||||
|
revert
|
||||||
|
|
||||||
|
auxdata: 0xa164736f6c63782a302e362e332d646576656c6f702e323032302e322e362b636f6d6d69742e31353237396436392e6d6f640032
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user