aboutsummaryrefslogtreecommitdiffstats
path: root/libyul/optimiser/Metrics.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-12-06 06:42:55 +0800
committerchriseth <chris@ethereum.org>2019-01-07 21:03:32 +0800
commit2e9c70add0490a5157f393c78e29bb86f67111d7 (patch)
treeaa182a37aa5cc21be1144041ad3d6df803e9c255 /libyul/optimiser/Metrics.cpp
parentaca9e581454585fab494a87febb7da3278e3aa7b (diff)
downloaddexon-solidity-2e9c70add0490a5157f393c78e29bb86f67111d7.tar
dexon-solidity-2e9c70add0490a5157f393c78e29bb86f67111d7.tar.gz
dexon-solidity-2e9c70add0490a5157f393c78e29bb86f67111d7.tar.bz2
dexon-solidity-2e9c70add0490a5157f393c78e29bb86f67111d7.tar.lz
dexon-solidity-2e9c70add0490a5157f393c78e29bb86f67111d7.tar.xz
dexon-solidity-2e9c70add0490a5157f393c78e29bb86f67111d7.tar.zst
dexon-solidity-2e9c70add0490a5157f393c78e29bb86f67111d7.zip
Use rematerializer if variable is unreferenced or value is "cheap".
Diffstat (limited to 'libyul/optimiser/Metrics.cpp')
-rw-r--r--libyul/optimiser/Metrics.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp
index 8fc9476e..a351f1d1 100644
--- a/libyul/optimiser/Metrics.cpp
+++ b/libyul/optimiser/Metrics.cpp
@@ -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);
+}