mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Keep one instance of KnowledgeBase for UnusedStoreEliminator.
This commit is contained in:
parent
47aa1c65ae
commit
96e2a6d3fe
@ -92,6 +92,21 @@ void UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast)
|
|||||||
remover(_ast);
|
remover(_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnusedStoreEliminator::UnusedStoreEliminator(
|
||||||
|
Dialect const& _dialect,
|
||||||
|
map<YulString, SideEffects> const& _functionSideEffects,
|
||||||
|
map<YulString, ControlFlowSideEffects> _controlFlowSideEffects,
|
||||||
|
map<YulString, AssignedValue> const& _ssaValues,
|
||||||
|
bool _ignoreMemory
|
||||||
|
):
|
||||||
|
UnusedStoreBase(_dialect),
|
||||||
|
m_ignoreMemory(_ignoreMemory),
|
||||||
|
m_functionSideEffects(_functionSideEffects),
|
||||||
|
m_controlFlowSideEffects(_controlFlowSideEffects),
|
||||||
|
m_ssaValues(_ssaValues),
|
||||||
|
m_knowledgeBase([this](YulString _var) { return util::valueOrNullptr(m_ssaValues, _var); })
|
||||||
|
{}
|
||||||
|
|
||||||
void UnusedStoreEliminator::operator()(FunctionCall const& _functionCall)
|
void UnusedStoreEliminator::operator()(FunctionCall const& _functionCall)
|
||||||
{
|
{
|
||||||
UnusedStoreBase::operator()(_functionCall);
|
UnusedStoreBase::operator()(_functionCall);
|
||||||
@ -174,12 +189,11 @@ void UnusedStoreEliminator::visit(Statement const& _statement)
|
|||||||
initialState = State::Used;
|
initialState = State::Used;
|
||||||
auto startOffset = identifierNameIfSSA(funCall->arguments.at(1));
|
auto startOffset = identifierNameIfSSA(funCall->arguments.at(1));
|
||||||
auto length = identifierNameIfSSA(funCall->arguments.at(2));
|
auto length = identifierNameIfSSA(funCall->arguments.at(2));
|
||||||
KnowledgeBase knowledge([this](YulString _var) { return util::valueOrNullptr(m_ssaValues, _var); });
|
|
||||||
if (length && startOffset)
|
if (length && startOffset)
|
||||||
{
|
{
|
||||||
FunctionCall const* lengthCall = get_if<FunctionCall>(m_ssaValues.at(*length).value);
|
FunctionCall const* lengthCall = get_if<FunctionCall>(m_ssaValues.at(*length).value);
|
||||||
if (
|
if (
|
||||||
knowledge.knownToBeZero(*startOffset) &&
|
m_knowledgeBase.knownToBeZero(*startOffset) &&
|
||||||
lengthCall &&
|
lengthCall &&
|
||||||
toEVMInstruction(m_dialect, lengthCall->functionName.name) == Instruction::RETURNDATASIZE
|
toEVMInstruction(m_dialect, lengthCall->functionName.name) == Instruction::RETURNDATASIZE
|
||||||
)
|
)
|
||||||
@ -267,8 +281,6 @@ bool UnusedStoreEliminator::knownUnrelated(
|
|||||||
UnusedStoreEliminator::Operation const& _op2
|
UnusedStoreEliminator::Operation const& _op2
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
KnowledgeBase knowledge([this](YulString _var) { return util::valueOrNullptr(m_ssaValues, _var); });
|
|
||||||
|
|
||||||
if (_op1.location != _op2.location)
|
if (_op1.location != _op2.location)
|
||||||
return true;
|
return true;
|
||||||
if (_op1.location == Location::Storage)
|
if (_op1.location == Location::Storage)
|
||||||
@ -278,26 +290,26 @@ bool UnusedStoreEliminator::knownUnrelated(
|
|||||||
yulAssert(
|
yulAssert(
|
||||||
_op1.length &&
|
_op1.length &&
|
||||||
_op2.length &&
|
_op2.length &&
|
||||||
knowledge.valueIfKnownConstant(*_op1.length) == 1 &&
|
m_knowledgeBase.valueIfKnownConstant(*_op1.length) == 1 &&
|
||||||
knowledge.valueIfKnownConstant(*_op2.length) == 1
|
m_knowledgeBase.valueIfKnownConstant(*_op2.length) == 1
|
||||||
);
|
);
|
||||||
return knowledge.knownToBeDifferent(*_op1.start, *_op2.start);
|
return m_knowledgeBase.knownToBeDifferent(*_op1.start, *_op2.start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yulAssert(_op1.location == Location::Memory, "");
|
yulAssert(_op1.location == Location::Memory, "");
|
||||||
if (
|
if (
|
||||||
(_op1.length && knowledge.knownToBeZero(*_op1.length)) ||
|
(_op1.length && m_knowledgeBase.knownToBeZero(*_op1.length)) ||
|
||||||
(_op2.length && knowledge.knownToBeZero(*_op2.length))
|
(_op2.length && m_knowledgeBase.knownToBeZero(*_op2.length))
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (_op1.start && _op1.length && _op2.start)
|
if (_op1.start && _op1.length && _op2.start)
|
||||||
{
|
{
|
||||||
optional<u256> length1 = knowledge.valueIfKnownConstant(*_op1.length);
|
optional<u256> length1 = m_knowledgeBase.valueIfKnownConstant(*_op1.length);
|
||||||
optional<u256> start1 = knowledge.valueIfKnownConstant(*_op1.start);
|
optional<u256> start1 = m_knowledgeBase.valueIfKnownConstant(*_op1.start);
|
||||||
optional<u256> start2 = knowledge.valueIfKnownConstant(*_op2.start);
|
optional<u256> start2 = m_knowledgeBase.valueIfKnownConstant(*_op2.start);
|
||||||
if (
|
if (
|
||||||
(length1 && start1 && start2) &&
|
(length1 && start1 && start2) &&
|
||||||
*start1 + *length1 >= *start1 && // no overflow
|
*start1 + *length1 >= *start1 && // no overflow
|
||||||
@ -307,9 +319,9 @@ bool UnusedStoreEliminator::knownUnrelated(
|
|||||||
}
|
}
|
||||||
if (_op2.start && _op2.length && _op1.start)
|
if (_op2.start && _op2.length && _op1.start)
|
||||||
{
|
{
|
||||||
optional<u256> length2 = knowledge.valueIfKnownConstant(*_op2.length);
|
optional<u256> length2 = m_knowledgeBase.valueIfKnownConstant(*_op2.length);
|
||||||
optional<u256> start2 = knowledge.valueIfKnownConstant(*_op2.start);
|
optional<u256> start2 = m_knowledgeBase.valueIfKnownConstant(*_op2.start);
|
||||||
optional<u256> start1 = knowledge.valueIfKnownConstant(*_op1.start);
|
optional<u256> start1 = m_knowledgeBase.valueIfKnownConstant(*_op1.start);
|
||||||
if (
|
if (
|
||||||
(length2 && start2 && start1) &&
|
(length2 && start2 && start1) &&
|
||||||
*start2 + *length2 >= *start2 && // no overflow
|
*start2 + *length2 >= *start2 && // no overflow
|
||||||
@ -320,12 +332,12 @@ bool UnusedStoreEliminator::knownUnrelated(
|
|||||||
|
|
||||||
if (_op1.start && _op1.length && _op2.start && _op2.length)
|
if (_op1.start && _op1.length && _op2.start && _op2.length)
|
||||||
{
|
{
|
||||||
optional<u256> length1 = knowledge.valueIfKnownConstant(*_op1.length);
|
optional<u256> length1 = m_knowledgeBase.valueIfKnownConstant(*_op1.length);
|
||||||
optional<u256> length2 = knowledge.valueIfKnownConstant(*_op2.length);
|
optional<u256> length2 = m_knowledgeBase.valueIfKnownConstant(*_op2.length);
|
||||||
if (
|
if (
|
||||||
(length1 && *length1 <= 32) &&
|
(length1 && *length1 <= 32) &&
|
||||||
(length2 && *length2 <= 32) &&
|
(length2 && *length2 <= 32) &&
|
||||||
knowledge.knownToBeDifferentByAtLeast32(*_op1.start, *_op2.start)
|
m_knowledgeBase.knownToBeDifferentByAtLeast32(*_op1.start, *_op2.start)
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -348,22 +360,20 @@ bool UnusedStoreEliminator::knownCovered(
|
|||||||
return true;
|
return true;
|
||||||
if (_covered.location == Location::Memory)
|
if (_covered.location == Location::Memory)
|
||||||
{
|
{
|
||||||
KnowledgeBase knowledge([this](YulString _var) { return util::valueOrNullptr(m_ssaValues, _var); });
|
if (_covered.length && m_knowledgeBase.knownToBeZero(*_covered.length))
|
||||||
|
|
||||||
if (_covered.length && knowledge.knownToBeZero(*_covered.length))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Condition (i = cover_i_ng, e = cover_e_d):
|
// Condition (i = cover_i_ng, e = cover_e_d):
|
||||||
// i.start <= e.start && e.start + e.length <= i.start + i.length
|
// i.start <= e.start && e.start + e.length <= i.start + i.length
|
||||||
if (!_covered.start || !_covering.start || !_covered.length || !_covering.length)
|
if (!_covered.start || !_covering.start || !_covered.length || !_covering.length)
|
||||||
return false;
|
return false;
|
||||||
optional<u256> coveredLength = knowledge.valueIfKnownConstant(*_covered.length);
|
optional<u256> coveredLength = m_knowledgeBase.valueIfKnownConstant(*_covered.length);
|
||||||
optional<u256> coveringLength = knowledge.valueIfKnownConstant(*_covering.length);
|
optional<u256> coveringLength = m_knowledgeBase.valueIfKnownConstant(*_covering.length);
|
||||||
if (*_covered.start == *_covering.start)
|
if (*_covered.start == *_covering.start)
|
||||||
if (coveredLength && coveringLength && *coveredLength <= *coveringLength)
|
if (coveredLength && coveringLength && *coveredLength <= *coveringLength)
|
||||||
return true;
|
return true;
|
||||||
optional<u256> coveredStart = knowledge.valueIfKnownConstant(*_covered.start);
|
optional<u256> coveredStart = m_knowledgeBase.valueIfKnownConstant(*_covered.start);
|
||||||
optional<u256> coveringStart = knowledge.valueIfKnownConstant(*_covering.start);
|
optional<u256> coveringStart = m_knowledgeBase.valueIfKnownConstant(*_covering.start);
|
||||||
if (coveredStart && coveringStart && coveredLength && coveringLength)
|
if (coveredStart && coveringStart && coveredLength && coveringLength)
|
||||||
if (
|
if (
|
||||||
*coveringStart <= *coveredStart &&
|
*coveringStart <= *coveredStart &&
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <libyul/optimiser/OptimiserStep.h>
|
#include <libyul/optimiser/OptimiserStep.h>
|
||||||
#include <libyul/optimiser/Semantics.h>
|
#include <libyul/optimiser/Semantics.h>
|
||||||
#include <libyul/optimiser/UnusedStoreBase.h>
|
#include <libyul/optimiser/UnusedStoreBase.h>
|
||||||
|
#include <libyul/optimiser/KnowledgeBase.h>
|
||||||
|
|
||||||
#include <libevmasm/SemanticInformation.h>
|
#include <libevmasm/SemanticInformation.h>
|
||||||
|
|
||||||
@ -68,13 +69,7 @@ public:
|
|||||||
std::map<YulString, ControlFlowSideEffects> _controlFlowSideEffects,
|
std::map<YulString, ControlFlowSideEffects> _controlFlowSideEffects,
|
||||||
std::map<YulString, AssignedValue> const& _ssaValues,
|
std::map<YulString, AssignedValue> const& _ssaValues,
|
||||||
bool _ignoreMemory
|
bool _ignoreMemory
|
||||||
):
|
);
|
||||||
UnusedStoreBase(_dialect),
|
|
||||||
m_ignoreMemory(_ignoreMemory),
|
|
||||||
m_functionSideEffects(_functionSideEffects),
|
|
||||||
m_controlFlowSideEffects(_controlFlowSideEffects),
|
|
||||||
m_ssaValues(_ssaValues)
|
|
||||||
{}
|
|
||||||
|
|
||||||
using UnusedStoreBase::operator();
|
using UnusedStoreBase::operator();
|
||||||
void operator()(FunctionCall const& _functionCall) override;
|
void operator()(FunctionCall const& _functionCall) override;
|
||||||
@ -121,6 +116,8 @@ private:
|
|||||||
std::map<YulString, AssignedValue> const& m_ssaValues;
|
std::map<YulString, AssignedValue> const& m_ssaValues;
|
||||||
|
|
||||||
std::map<Statement const*, Operation> m_storeOperations;
|
std::map<Statement const*, Operation> m_storeOperations;
|
||||||
|
|
||||||
|
KnowledgeBase mutable m_knowledgeBase;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user