mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
@@ -156,6 +156,8 @@ Opcode constOpcodeFor(ValueType _type)
|
||||
}
|
||||
|
||||
static map<string, uint8_t> const builtins = {
|
||||
{"i32.select", 0x1b},
|
||||
{"i64.select", 0x1b},
|
||||
{"i32.load", 0x28},
|
||||
{"i64.load", 0x29},
|
||||
{"i32.load8_s", 0x2c},
|
||||
|
||||
@@ -120,6 +120,10 @@ WasmDialect::WasmDialect()
|
||||
addFunction("i32.drop", {i32}, {});
|
||||
addFunction("i64.drop", {i64}, {});
|
||||
|
||||
// Select is also overloaded.
|
||||
addFunction("i32.select", {i32, i32, i32}, {i32});
|
||||
addFunction("i64.select", {i64, i64, i32}, {i64});
|
||||
|
||||
addFunction("nop", {}, {});
|
||||
addFunction("unreachable", {}, {}, false);
|
||||
m_functions["unreachable"_yulstring].sideEffects.storage = SideEffects::None;
|
||||
|
||||
@@ -90,9 +90,9 @@ function mul_64x64_128(x, y) -> hi, lo {
|
||||
// value split into four 64 bit values.
|
||||
function mul_128x128_256(x1, x2, y1, y2) -> r1, r2, r3, r4 {
|
||||
let ah, al := mul_64x64_128(x1, y1)
|
||||
let bh, bl := mul_64x64_128(x1, y2)
|
||||
let ch, cl := mul_64x64_128(x2, y1)
|
||||
let dh, dl := mul_64x64_128(x2, y2)
|
||||
let bh, bl := mul_64x64_128(x1, y2)
|
||||
let ch, cl := mul_64x64_128(x2, y1)
|
||||
let dh, dl := mul_64x64_128(x2, y2)
|
||||
r4 := dl
|
||||
let carry1, carry2
|
||||
let t1, t2
|
||||
|
||||
@@ -35,24 +35,23 @@ function iszero512(x1, x2, x3, x4, x5, x6, x7, x8) -> r:i32 {
|
||||
}
|
||||
|
||||
function eq(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4 {
|
||||
if i64.eq(x1, y1) {
|
||||
if i64.eq(x2, y2) {
|
||||
if i64.eq(x3, y3) {
|
||||
if i64.eq(x4, y4) {
|
||||
r4 := 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r4 := i64.extend_i32_u(
|
||||
i32.and(
|
||||
i64.eq(x1, y1),
|
||||
i32.and(
|
||||
i64.eq(x2, y2),
|
||||
i32.and(
|
||||
i64.eq(x3, y3),
|
||||
i64.eq(x4, y4)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// returns 0 if a == b, -1 if a < b and 1 if a > b
|
||||
function cmp(a, b) -> r:i32 {
|
||||
switch i64.lt_u(a, b)
|
||||
case 1:i32 { r := 0xffffffff:i32 }
|
||||
default {
|
||||
r := i64.ne(a, b)
|
||||
}
|
||||
r := i32.select(0xffffffff:i32, i64.ne(a, b), i64.lt_u(a, b))
|
||||
}
|
||||
|
||||
function lt_320x320_64(x1, x2, x3, x4, x5, y1, y2, y3, y4, y5) -> z:i32 {
|
||||
|
||||
@@ -103,9 +103,9 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
|
||||
for (auto const& [variable, value]: m_value)
|
||||
{
|
||||
assertThrow(value.value, OptimizerException, "");
|
||||
assertThrow(inScope(variable), OptimizerException, "");
|
||||
if (SyntacticallyEqual{}(_e, *value.value))
|
||||
{
|
||||
assertThrow(inScope(variable), OptimizerException, "");
|
||||
_e = Identifier{locationOf(_e), variable};
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ void DataFlowAnalyzer::operator()(Assignment& _assignment)
|
||||
assertThrow(_assignment.value, OptimizerException, "");
|
||||
clearKnowledgeIfInvalidated(*_assignment.value);
|
||||
visit(*_assignment.value);
|
||||
handleAssignment(names, _assignment.value.get());
|
||||
handleAssignment(names, _assignment.value.get(), false);
|
||||
}
|
||||
|
||||
void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
|
||||
@@ -98,7 +98,7 @@ void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
|
||||
visit(*_varDecl.value);
|
||||
}
|
||||
|
||||
handleAssignment(names, _varDecl.value.get());
|
||||
handleAssignment(names, _varDecl.value.get(), true);
|
||||
}
|
||||
|
||||
void DataFlowAnalyzer::operator()(If& _if)
|
||||
@@ -161,7 +161,7 @@ void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
|
||||
for (auto const& var: _fun.returnVariables)
|
||||
{
|
||||
m_variableScopes.back().variables.emplace(var.name);
|
||||
handleAssignment({var.name}, nullptr);
|
||||
handleAssignment({var.name}, nullptr, true);
|
||||
}
|
||||
ASTModifier::operator()(_fun);
|
||||
|
||||
@@ -220,9 +220,10 @@ void DataFlowAnalyzer::operator()(Block& _block)
|
||||
assertThrow(numScopes == m_variableScopes.size(), OptimizerException, "");
|
||||
}
|
||||
|
||||
void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expression* _value)
|
||||
void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expression* _value, bool _isDeclaration)
|
||||
{
|
||||
clearValues(_variables);
|
||||
if (!_isDeclaration)
|
||||
clearValues(_variables);
|
||||
|
||||
MovableChecker movableChecker{m_dialect, &m_functionSideEffects};
|
||||
if (_value)
|
||||
@@ -244,14 +245,17 @@ void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expres
|
||||
for (auto const& name: _variables)
|
||||
{
|
||||
m_references.set(name, referencedVariables);
|
||||
// assignment to slot denoted by "name"
|
||||
m_storage.eraseKey(name);
|
||||
// assignment to slot contents denoted by "name"
|
||||
m_storage.eraseValue(name);
|
||||
// assignment to slot denoted by "name"
|
||||
m_memory.eraseKey(name);
|
||||
// assignment to slot contents denoted by "name"
|
||||
m_memory.eraseValue(name);
|
||||
if (!_isDeclaration)
|
||||
{
|
||||
// assignment to slot denoted by "name"
|
||||
m_storage.eraseKey(name);
|
||||
// assignment to slot contents denoted by "name"
|
||||
m_storage.eraseValue(name);
|
||||
// assignment to slot denoted by "name"
|
||||
m_memory.eraseKey(name);
|
||||
// assignment to slot contents denoted by "name"
|
||||
m_memory.eraseValue(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (_value && _variables.size() == 1)
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
|
||||
protected:
|
||||
/// Registers the assignment.
|
||||
void handleAssignment(std::set<YulString> const& _names, Expression* _value);
|
||||
void handleAssignment(std::set<YulString> const& _names, Expression* _value, bool _isDeclaration);
|
||||
|
||||
/// Creates a new inner scope.
|
||||
void pushScope(bool _functionScope);
|
||||
|
||||
@@ -364,6 +364,9 @@ void OptimiserSuite::runSequenceUntilStable(
|
||||
size_t maxRounds
|
||||
)
|
||||
{
|
||||
if (_steps.empty())
|
||||
return;
|
||||
|
||||
size_t codeSize = 0;
|
||||
for (size_t rounds = 0; rounds < maxRounds; ++rounds)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user