[yul-phaser] Extract ProgramBasedMetric base class from ProgramSize

This commit is contained in:
Kamil Śliwak 2020-02-26 20:47:11 +01:00
parent bdc4d1ccd1
commit 0913fd1aac
3 changed files with 57 additions and 11 deletions

View File

@ -22,16 +22,26 @@
#include <liblangutil/CharStream.h> #include <liblangutil/CharStream.h>
#include <libsolutil/CommonIO.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
using namespace std; using namespace std;
using namespace solidity::langutil; using namespace solidity::langutil;
using namespace solidity::util;
using namespace solidity::yul; using namespace solidity::yul;
namespace solidity::phaser::test namespace solidity::phaser::test
{ {
class FitnessMetricFixture class DummyProgramBasedMetric: public ProgramBasedMetric
{
public:
using ProgramBasedMetric::ProgramBasedMetric;
size_t evaluate(Chromosome const&) const override { return 0; }
};
class ProgramBasedMetricFixture
{ {
protected: protected:
static constexpr char SampleSourceCode[] = static constexpr char SampleSourceCode[] =
@ -68,9 +78,20 @@ protected:
BOOST_AUTO_TEST_SUITE(Phaser) BOOST_AUTO_TEST_SUITE(Phaser)
BOOST_AUTO_TEST_SUITE(FitnessMetricsTest) BOOST_AUTO_TEST_SUITE(FitnessMetricsTest)
BOOST_AUTO_TEST_SUITE(ProgramBasedMetricTest)
BOOST_FIXTURE_TEST_CASE(optimisedProgram_should_return_optimised_program, ProgramBasedMetricFixture)
{
string code = toString(DummyProgramBasedMetric(m_program).optimisedProgram(m_chromosome));
BOOST_TEST(code != toString(m_program));
BOOST_TEST(code == toString(m_optimisedProgram));
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(ProgramSizeTest) BOOST_AUTO_TEST_SUITE(ProgramSizeTest)
BOOST_FIXTURE_TEST_CASE(evaluate_should_compute_size_of_the_optimised_program, FitnessMetricFixture) BOOST_FIXTURE_TEST_CASE(evaluate_should_compute_size_of_the_optimised_program, ProgramBasedMetricFixture)
{ {
size_t fitness = ProgramSize(m_program).evaluate(m_chromosome); size_t fitness = ProgramSize(m_program).evaluate(m_chromosome);
@ -78,7 +99,7 @@ BOOST_FIXTURE_TEST_CASE(evaluate_should_compute_size_of_the_optimised_program, F
BOOST_TEST(fitness == m_optimisedProgram.codeSize()); BOOST_TEST(fitness == m_optimisedProgram.codeSize());
} }
BOOST_FIXTURE_TEST_CASE(evaluate_should_repeat_the_optimisation_specified_number_of_times, FitnessMetricFixture) BOOST_FIXTURE_TEST_CASE(evaluate_should_repeat_the_optimisation_specified_number_of_times, ProgramBasedMetricFixture)
{ {
Program const& programOptimisedOnce = m_optimisedProgram; Program const& programOptimisedOnce = m_optimisedProgram;
Program programOptimisedTwice = optimisedProgram(programOptimisedOnce); Program programOptimisedTwice = optimisedProgram(programOptimisedOnce);
@ -91,7 +112,7 @@ BOOST_FIXTURE_TEST_CASE(evaluate_should_repeat_the_optimisation_specified_number
BOOST_TEST(fitness == programOptimisedTwice.codeSize()); BOOST_TEST(fitness == programOptimisedTwice.codeSize());
} }
BOOST_FIXTURE_TEST_CASE(evaluate_should_not_optimise_if_number_of_repetitions_is_zero, FitnessMetricFixture) BOOST_FIXTURE_TEST_CASE(evaluate_should_not_optimise_if_number_of_repetitions_is_zero, ProgramBasedMetricFixture)
{ {
ProgramSize metric(m_program, 0); ProgramSize metric(m_program, 0);
size_t fitness = metric.evaluate(m_chromosome); size_t fitness = metric.evaluate(m_chromosome);

View File

@ -20,11 +20,16 @@
using namespace std; using namespace std;
using namespace solidity::phaser; using namespace solidity::phaser;
size_t ProgramSize::evaluate(Chromosome const& _chromosome) const Program ProgramBasedMetric::optimisedProgram(Chromosome const& _chromosome) const
{ {
Program programCopy = m_program; Program programCopy = m_program;
for (size_t i = 0; i < m_repetitionCount; ++i) for (size_t i = 0; i < m_repetitionCount; ++i)
programCopy.optimise(_chromosome.optimisationSteps()); programCopy.optimise(_chromosome.optimisationSteps());
return programCopy.codeSize(); return programCopy;
}
size_t ProgramSize::evaluate(Chromosome const& _chromosome) const
{
return optimisedProgram(_chromosome).codeSize();
} }

View File

@ -47,24 +47,44 @@ public:
}; };
/** /**
* Fitness metric based on the size of a specific program after applying the optimisations from the * Abstract base class for fitness metrics that return values based on program size.
* chromosome to it. *
* The class provides utilities for optimising programs according to the information stored in
* chromosomes.
*
* It can also store weights for the @a CodeSize metric. It does not do anything with
* them because it does not actually compute the code size but they are readily available for use
* by derived classes.
*/ */
class ProgramSize: public FitnessMetric class ProgramBasedMetric: public FitnessMetric
{ {
public: public:
explicit ProgramSize(Program _program, size_t _repetitionCount = 1): explicit ProgramBasedMetric(
Program _program,
size_t _repetitionCount = 1
):
m_program(std::move(_program)), m_program(std::move(_program)),
m_repetitionCount(_repetitionCount) {} m_repetitionCount(_repetitionCount) {}
Program const& program() const { return m_program; } Program const& program() const { return m_program; }
size_t repetitionCount() const { return m_repetitionCount; } size_t repetitionCount() const { return m_repetitionCount; }
size_t evaluate(Chromosome const& _chromosome) const override; Program optimisedProgram(Chromosome const& _chromosome) const;
private: private:
Program m_program; Program m_program;
size_t m_repetitionCount; size_t m_repetitionCount;
}; };
/**
* Fitness metric based on the size of a specific program after applying the optimisations from the
* chromosome to it.
*/
class ProgramSize: public ProgramBasedMetric
{
public:
using ProgramBasedMetric::ProgramBasedMetric;
size_t evaluate(Chromosome const& _chromosome) const override;
};
} }