aboutsummaryrefslogtreecommitdiffstats
path: root/libyul/optimiser/Metrics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libyul/optimiser/Metrics.cpp')
-rw-r--r--libyul/optimiser/Metrics.cpp90
1 files changed, 88 insertions, 2 deletions
diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp
index 8fc9476e..e13940aa 100644
--- a/libyul/optimiser/Metrics.cpp
+++ b/libyul/optimiser/Metrics.cpp
@@ -21,7 +21,13 @@
#include <libyul/optimiser/Metrics.h>
#include <libyul/AsmData.h>
+#include <libyul/Exceptions.h>
+#include <libevmasm/Instruction.h>
+
+#include <libdevcore/Visitor.h>
+
+using namespace std;
using namespace dev;
using namespace yul;
@@ -50,13 +56,93 @@ void CodeSize::visit(Statement const& _statement)
{
if (_statement.type() == typeid(FunctionDefinition))
return;
+ else if (!(
+ _statement.type() == typeid(Block) ||
+ _statement.type() == typeid(ExpressionStatement) ||
+ _statement.type() == typeid(Assignment) ||
+ _statement.type() == typeid(VariableDeclaration)
+ ))
+ ++m_size;
- ++m_size;
ASTWalker::visit(_statement);
}
void CodeSize::visit(Expression const& _expression)
{
- ++m_size;
+ if (_expression.type() != typeid(Identifier))
+ ++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);
}
+
+void AssignmentCounter::operator()(Assignment const& _assignment)
+{
+ for (auto const& variable: _assignment.variableNames)
+ ++m_assignmentCounters[variable.name];
+}
+
+size_t AssignmentCounter::assignmentCount(YulString _name) const
+{
+ auto it = m_assignmentCounters.find(_name);
+ return (it == m_assignmentCounters.end()) ? 0 : it->second;
+}