mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Properly assign types in ExpressionSplitter.
This commit is contained in:
parent
915cb65106
commit
b9b36cd89e
@ -23,11 +23,13 @@
|
|||||||
|
|
||||||
#include <libyul/optimiser/ASTWalker.h>
|
#include <libyul/optimiser/ASTWalker.h>
|
||||||
#include <libyul/optimiser/OptimiserStep.h>
|
#include <libyul/optimiser/OptimiserStep.h>
|
||||||
|
#include <libyul/optimiser/TypeInfo.h>
|
||||||
|
|
||||||
#include <libyul/AsmData.h>
|
#include <libyul/AsmData.h>
|
||||||
#include <libyul/Dialect.h>
|
#include <libyul/Dialect.h>
|
||||||
|
|
||||||
#include <libsolutil/CommonData.h>
|
#include <libsolutil/CommonData.h>
|
||||||
|
#include <libsolutil/Visitor.h>
|
||||||
|
|
||||||
#include <boost/range/adaptor/reversed.hpp>
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
|
|
||||||
@ -39,7 +41,8 @@ using namespace solidity::langutil;
|
|||||||
|
|
||||||
void ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast)
|
void ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast)
|
||||||
{
|
{
|
||||||
ExpressionSplitter{_context.dialect, _context.dispenser}(_ast);
|
TypeInfo typeInfo(_context.dialect, _ast);
|
||||||
|
ExpressionSplitter{_context.dialect, _context.dispenser, typeInfo}(_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionSplitter::operator()(FunctionCall& _funCall)
|
void ExpressionSplitter::operator()(FunctionCall& _funCall)
|
||||||
@ -103,10 +106,13 @@ void ExpressionSplitter::outlineExpression(Expression& _expr)
|
|||||||
|
|
||||||
SourceLocation location = locationOf(_expr);
|
SourceLocation location = locationOf(_expr);
|
||||||
YulString var = m_nameDispenser.newName({});
|
YulString var = m_nameDispenser.newName({});
|
||||||
|
YulString type = m_typeInfo.typeOf(_expr);
|
||||||
m_statementsToPrefix.emplace_back(VariableDeclaration{
|
m_statementsToPrefix.emplace_back(VariableDeclaration{
|
||||||
location,
|
location,
|
||||||
{{TypedName{location, var, {}}}},
|
{{TypedName{location, var, type}}},
|
||||||
make_unique<Expression>(std::move(_expr))
|
make_unique<Expression>(std::move(_expr))
|
||||||
});
|
});
|
||||||
_expr = Identifier{location, var};
|
_expr = Identifier{location, var};
|
||||||
|
m_typeInfo.setVariableType(var, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@
|
|||||||
namespace solidity::yul
|
namespace solidity::yul
|
||||||
{
|
{
|
||||||
|
|
||||||
class NameCollector;
|
|
||||||
struct Dialect;
|
struct Dialect;
|
||||||
struct OptimiserStepContext;
|
struct OptimiserStepContext;
|
||||||
|
class TypeInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimiser component that modifies an AST in place, turning complex
|
* Optimiser component that modifies an AST in place, turning complex
|
||||||
@ -68,8 +68,14 @@ public:
|
|||||||
void operator()(Block& _block) override;
|
void operator()(Block& _block) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ExpressionSplitter(Dialect const& _dialect, NameDispenser& _nameDispenser):
|
explicit ExpressionSplitter(
|
||||||
m_dialect(_dialect), m_nameDispenser(_nameDispenser)
|
Dialect const& _dialect,
|
||||||
|
NameDispenser& _nameDispenser,
|
||||||
|
TypeInfo& _typeInfo
|
||||||
|
):
|
||||||
|
m_dialect(_dialect),
|
||||||
|
m_nameDispenser(_nameDispenser),
|
||||||
|
m_typeInfo(_typeInfo)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/// Replaces the expression by a variable if it is a function call or functional
|
/// Replaces the expression by a variable if it is a function call or functional
|
||||||
@ -82,6 +88,7 @@ private:
|
|||||||
std::vector<Statement> m_statementsToPrefix;
|
std::vector<Statement> m_statementsToPrefix;
|
||||||
Dialect const& m_dialect;
|
Dialect const& m_dialect;
|
||||||
NameDispenser& m_nameDispenser;
|
NameDispenser& m_nameDispenser;
|
||||||
|
TypeInfo& m_typeInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
42
test/libyul/yulOptimizerTests/expressionSplitter/typed.yul
Normal file
42
test/libyul/yulOptimizerTests/expressionSplitter/typed.yul
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
function fun(x: i32, y) -> t: i32, z: i32 {
|
||||||
|
z := i32.add(x, i32.add(z, z))
|
||||||
|
|
||||||
|
}
|
||||||
|
i64.store(i32.load(5:i32), i64.load(8:i32))
|
||||||
|
let i := 0
|
||||||
|
for {} i32.eqz(i32.load(9:i32)) { i := i64.add(i, 1) } {
|
||||||
|
let f: i32, g: i32 := fun(i32.load(1:i32), i64.load(i32.load(0: i32)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// dialect: ewasm
|
||||||
|
// step: expressionSplitter
|
||||||
|
// ----
|
||||||
|
// {
|
||||||
|
// function fun(x:i32, y) -> t:i32, z:i32
|
||||||
|
// {
|
||||||
|
// let _1:i32 := i32.add(z, z)
|
||||||
|
// z := i32.add(x, _1)
|
||||||
|
// }
|
||||||
|
// let _2:i32 := 8:i32
|
||||||
|
// let _3 := i64.load(_2)
|
||||||
|
// let _4:i32 := 5:i32
|
||||||
|
// let _5:i32 := i32.load(_4)
|
||||||
|
// i64.store(_5, _3)
|
||||||
|
// let i := 0
|
||||||
|
// for { }
|
||||||
|
// i32.eqz(i32.load(9:i32))
|
||||||
|
// {
|
||||||
|
// let _6 := 1
|
||||||
|
// i := i64.add(i, _6)
|
||||||
|
// }
|
||||||
|
// {
|
||||||
|
// let _7:i32 := 0:i32
|
||||||
|
// let _8:i32 := i32.load(_7)
|
||||||
|
// let _9 := i64.load(_8)
|
||||||
|
// let _10:i32 := 1:i32
|
||||||
|
// let _11:i32 := i32.load(_10)
|
||||||
|
// let f:i32, g:i32 := fun(_11, _9)
|
||||||
|
// }
|
||||||
|
// }
|
Loading…
Reference in New Issue
Block a user