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.
|
||||
*/
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolidity/ast/ASTUtils.h>
|
||||
#include <libsolidity/ast/TypeProvider.h>
|
||||
@ -27,7 +29,16 @@
|
||||
#include <libsolidity/codegen/ContractCompiler.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/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/Assembly.h>
|
||||
@ -40,6 +51,13 @@
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#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 solidity;
|
||||
using namespace solidity::evmasm;
|
||||
@ -788,10 +806,65 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
||||
_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(
|
||||
_inlineAssembly.operations(),
|
||||
*_inlineAssembly.annotation().analysisInfo,
|
||||
*code,
|
||||
*analysisInfo,
|
||||
*m_context.assemblyPtr(),
|
||||
m_context.evmVersion(),
|
||||
identifierAccess,
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
virtual Expression translate(Expression const& _expression);
|
||||
virtual Statement translate(Statement const& _statement);
|
||||
|
||||
Block translate(Block const& _block);
|
||||
protected:
|
||||
template <typename T>
|
||||
std::vector<T> translateVector(std::vector<T> const& _values);
|
||||
@ -94,7 +95,6 @@ protected:
|
||||
return _v ? std::make_unique<T>(translate(*_v)) : nullptr;
|
||||
}
|
||||
|
||||
Block translate(Block const& _block);
|
||||
Case translate(Case const& _case);
|
||||
virtual Identifier translate(Identifier const& _identifier);
|
||||
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