mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Remove ContainsMSize from side-effect-collector.
This commit is contained in:
parent
98e3caa28a
commit
57125de9ef
@ -262,10 +262,7 @@ bool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly)
|
|||||||
if (!m_useYulOptimizer)
|
if (!m_useYulOptimizer)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (yul::SideEffectsCollector(
|
if (yul::MSizeFinder::containsMSize(_inlineAssembly.dialect(), _inlineAssembly.operations()))
|
||||||
_inlineAssembly.dialect(),
|
|
||||||
_inlineAssembly.operations()
|
|
||||||
).containsMSize())
|
|
||||||
m_errorReporter.syntaxError(
|
m_errorReporter.syntaxError(
|
||||||
_inlineAssembly.location(),
|
_inlineAssembly.location(),
|
||||||
"The msize instruction cannot be used when the Yul optimizer is activated because "
|
"The msize instruction cannot be used when the Yul optimizer is activated because "
|
||||||
|
@ -31,7 +31,7 @@ using namespace yul;
|
|||||||
|
|
||||||
void LoadResolver::run(Dialect const& _dialect, Block& _ast)
|
void LoadResolver::run(Dialect const& _dialect, Block& _ast)
|
||||||
{
|
{
|
||||||
bool containsMSize = SideEffectsCollector(_dialect, _ast).containsMSize();
|
bool containsMSize = MSizeFinder::containsMSize(_dialect, _ast);
|
||||||
LoadResolver{_dialect, !containsMSize}(_ast);
|
LoadResolver{_dialect, !containsMSize}(_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +61,6 @@ void SideEffectsCollector::operator()(FunctionalInstruction const& _instr)
|
|||||||
m_sideEffectFree = false;
|
m_sideEffectFree = false;
|
||||||
if (!eth::SemanticInformation::sideEffectFreeIfNoMSize(_instr.instruction))
|
if (!eth::SemanticInformation::sideEffectFreeIfNoMSize(_instr.instruction))
|
||||||
m_sideEffectFreeIfNoMSize = false;
|
m_sideEffectFreeIfNoMSize = false;
|
||||||
if (_instr.instruction == eth::Instruction::MSIZE)
|
|
||||||
m_containsMSize = true;
|
|
||||||
if (eth::SemanticInformation::invalidatesStorage(_instr.instruction))
|
if (eth::SemanticInformation::invalidatesStorage(_instr.instruction))
|
||||||
m_invalidatesStorage = true;
|
m_invalidatesStorage = true;
|
||||||
if (eth::SemanticInformation::invalidatesMemory(_instr.instruction))
|
if (eth::SemanticInformation::invalidatesMemory(_instr.instruction))
|
||||||
@ -81,8 +79,6 @@ void SideEffectsCollector::operator()(FunctionCall const& _functionCall)
|
|||||||
m_sideEffectFree = false;
|
m_sideEffectFree = false;
|
||||||
if (!f->sideEffectFreeIfNoMSize)
|
if (!f->sideEffectFreeIfNoMSize)
|
||||||
m_sideEffectFreeIfNoMSize = false;
|
m_sideEffectFreeIfNoMSize = false;
|
||||||
if (f->isMSize)
|
|
||||||
m_containsMSize = true;
|
|
||||||
if (f->invalidatesStorage)
|
if (f->invalidatesStorage)
|
||||||
m_invalidatesStorage = true;
|
m_invalidatesStorage = true;
|
||||||
if (f->invalidatesMemory)
|
if (f->invalidatesMemory)
|
||||||
@ -98,6 +94,30 @@ void SideEffectsCollector::operator()(FunctionCall const& _functionCall)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MSizeFinder::containsMSize(Dialect const& _dialect, Block const& _ast)
|
||||||
|
{
|
||||||
|
MSizeFinder finder(_dialect);
|
||||||
|
finder(_ast);
|
||||||
|
return finder.m_msizeFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MSizeFinder::operator()(FunctionalInstruction const& _instr)
|
||||||
|
{
|
||||||
|
ASTWalker::operator()(_instr);
|
||||||
|
|
||||||
|
if (_instr.instruction == eth::Instruction::MSIZE)
|
||||||
|
m_msizeFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MSizeFinder::operator()(FunctionCall const& _functionCall)
|
||||||
|
{
|
||||||
|
ASTWalker::operator()(_functionCall);
|
||||||
|
|
||||||
|
if (BuiltinFunction const* f = m_dialect.builtin(_functionCall.functionName.name))
|
||||||
|
if (f->isMSize)
|
||||||
|
m_msizeFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
MovableChecker::MovableChecker(Dialect const& _dialect, Expression const& _expression):
|
MovableChecker::MovableChecker(Dialect const& _dialect, Expression const& _expression):
|
||||||
MovableChecker(_dialect)
|
MovableChecker(_dialect)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,6 @@ public:
|
|||||||
return m_sideEffectFree;
|
return m_sideEffectFree;
|
||||||
}
|
}
|
||||||
bool sideEffectFreeIfNoMSize() const { return m_sideEffectFreeIfNoMSize; }
|
bool sideEffectFreeIfNoMSize() const { return m_sideEffectFreeIfNoMSize; }
|
||||||
bool containsMSize() const { return m_containsMSize; }
|
|
||||||
bool invalidatesStorage() const { return m_invalidatesStorage; }
|
bool invalidatesStorage() const { return m_invalidatesStorage; }
|
||||||
bool invalidatesMemory() const { return m_invalidatesMemory; }
|
bool invalidatesMemory() const { return m_invalidatesMemory; }
|
||||||
|
|
||||||
@ -67,16 +66,35 @@ private:
|
|||||||
/// Is the current expression side-effect free up to msize, i.e. can be removed
|
/// Is the current expression side-effect free up to msize, i.e. can be removed
|
||||||
/// without changing the semantics except for the value returned by the msize instruction.
|
/// without changing the semantics except for the value returned by the msize instruction.
|
||||||
bool m_sideEffectFreeIfNoMSize = true;
|
bool m_sideEffectFreeIfNoMSize = true;
|
||||||
/// Does the current code contain the MSize operation?
|
|
||||||
/// Note that this is a purely syntactic property meaning that even if this is false,
|
|
||||||
/// the code can still contain calls to functions that contain the msize instruction.
|
|
||||||
bool m_containsMSize = false;
|
|
||||||
/// If false, storage is guaranteed to be unchanged by the code under all
|
/// If false, storage is guaranteed to be unchanged by the code under all
|
||||||
/// circumstances.
|
/// circumstances.
|
||||||
bool m_invalidatesStorage = false;
|
bool m_invalidatesStorage = false;
|
||||||
bool m_invalidatesMemory = false;
|
bool m_invalidatesMemory = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that can be used to find out if certain code contains the MSize instruction.
|
||||||
|
*
|
||||||
|
* Note that this is a purely syntactic property meaning that even if this is false,
|
||||||
|
* the code can still contain calls to functions that contain the msize instruction.
|
||||||
|
*
|
||||||
|
* The only safe way to determine this is by passing the full AST.
|
||||||
|
*/
|
||||||
|
class MSizeFinder: public ASTWalker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool containsMSize(Dialect const& _dialect, Block const& _ast);
|
||||||
|
|
||||||
|
using ASTWalker::operator();
|
||||||
|
void operator()(FunctionalInstruction const& _instr);
|
||||||
|
void operator()(FunctionCall const& _funCall);
|
||||||
|
|
||||||
|
private:
|
||||||
|
MSizeFinder(Dialect const& _dialect): m_dialect(_dialect) {}
|
||||||
|
Dialect const& m_dialect;
|
||||||
|
bool m_msizeFound = false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specific AST walker that determines whether an expression is movable
|
* Specific AST walker that determines whether an expression is movable
|
||||||
* and collects the referenced variables.
|
* and collects the referenced variables.
|
||||||
|
@ -165,7 +165,7 @@ bool StackCompressor::run(
|
|||||||
_object.code->statements.size() > 0 && _object.code->statements.at(0).type() == typeid(Block),
|
_object.code->statements.size() > 0 && _object.code->statements.at(0).type() == typeid(Block),
|
||||||
"Need to run the function grouper before the stack compressor."
|
"Need to run the function grouper before the stack compressor."
|
||||||
);
|
);
|
||||||
bool allowMSizeOptimzation = !SideEffectsCollector(_dialect, *_object.code).containsMSize();
|
bool allowMSizeOptimzation = !MSizeFinder::containsMSize(_dialect, *_object.code);
|
||||||
for (size_t iterations = 0; iterations < _maxIterations; iterations++)
|
for (size_t iterations = 0; iterations < _maxIterations; iterations++)
|
||||||
{
|
{
|
||||||
map<YulString, int> stackSurplus = CompilabilityChecker::run(_dialect, _object, _optimizeStackAllocation);
|
map<YulString, int> stackSurplus = CompilabilityChecker::run(_dialect, _object, _optimizeStackAllocation);
|
||||||
|
@ -138,7 +138,7 @@ void UnusedPruner::runUntilStabilised(
|
|||||||
set<YulString> const& _externallyUsedFunctions
|
set<YulString> const& _externallyUsedFunctions
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool allowMSizeOptimization = !SideEffectsCollector(_dialect, _ast).containsMSize();
|
bool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _ast);
|
||||||
runUntilStabilised(_dialect, _ast, allowMSizeOptimization, _externallyUsedFunctions);
|
runUntilStabilised(_dialect, _ast, allowMSizeOptimization, _externallyUsedFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user