Use rematerializer if variable is unreferenced or value is "cheap".

This commit is contained in:
chriseth
2019-01-07 14:03:32 +01:00
parent aca9e58145
commit 2e9c70add0
23 changed files with 261 additions and 127 deletions
+64
View File
@@ -21,6 +21,9 @@
#include <libyul/optimiser/Metrics.h>
#include <libyul/AsmData.h>
#include <libyul/Exceptions.h>
#include <libevmasm/Instruction.h>
using namespace dev;
using namespace yul;
@@ -60,3 +63,64 @@ void CodeSize::visit(Expression const& _expression)
++m_size;
ASTWalker::visit(_expression);
}
size_t CodeCost::codeCost(Expression const& _expr)
{
CodeCost cc;
cc.visit(_expr);
return cc.m_cost;
}
void CodeCost::operator()(FunctionCall const& _funCall)
{
yulAssert(m_cost >= 1, "Should assign cost one in visit(Expression).");
m_cost += 49;
ASTWalker::operator()(_funCall);
}
void CodeCost::operator()(FunctionalInstruction const& _instr)
{
using namespace dev::solidity;
yulAssert(m_cost >= 1, "Should assign cost one in visit(Expression).");
Tier gasPriceTier = instructionInfo(_instr.instruction).gasPriceTier;
if (gasPriceTier < Tier::VeryLow)
m_cost -= 1;
else if (gasPriceTier < Tier::High)
m_cost += 1;
else
m_cost += 49;
ASTWalker::operator()(_instr);
}
void CodeCost::operator()(Literal const& _literal)
{
yulAssert(m_cost >= 1, "Should assign cost one in visit(Expression).");
size_t cost = 0;
switch (_literal.kind)
{
case LiteralKind::Boolean:
break;
case LiteralKind::Number:
for (u256 n = u256(_literal.value.str()); n >= 0x100; n >>= 8)
cost++;
break;
case LiteralKind::String:
cost = _literal.value.str().size();
break;
}
m_cost += cost;
}
void CodeCost::visit(Statement const& _statement)
{
++m_cost;
ASTWalker::visit(_statement);
}
void CodeCost::visit(Expression const& _expression)
{
++m_cost;
ASTWalker::visit(_expression);
}