mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	[yul-phaser] Make Program and Population classes accept source code rather than file path
- I need some sample .yul files for testing but I see that existing tests generally have source code hard-coded in them rather than in standalone .yul files. There are lots of .yul files but they seem to be automatically processed by a special test case rather loaded ad-hoc by manually created tests. - Program and Population required a file name until now. I'm making them accept loaded source code to be able to give them data hard-coded in a test.
This commit is contained in:
		
							parent
							
								
									7b7c88ae95
								
							
						
					
					
						commit
						785f65d0f5
					
				| @ -26,6 +26,7 @@ | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::langutil; | ||||
| using namespace solidity::phaser; | ||||
| 
 | ||||
| namespace solidity::phaser | ||||
| @ -48,25 +49,25 @@ ostream& phaser::operator<<(ostream& _stream, Individual const& _individual) | ||||
| 	return _stream; | ||||
| } | ||||
| 
 | ||||
| Population::Population(string const& _sourcePath, vector<Chromosome> const& _chromosomes): | ||||
| 	m_sourcePath{_sourcePath} | ||||
| Population::Population(CharStream _sourceCode, vector<Chromosome> const& _chromosomes): | ||||
| 	m_sourceCode{move(_sourceCode)} | ||||
| { | ||||
| 	for (auto const& chromosome: _chromosomes) | ||||
| 		m_individuals.push_back({chromosome}); | ||||
| } | ||||
| 
 | ||||
| Population Population::makeRandom(string const& _sourcePath, size_t _size) | ||||
| Population Population::makeRandom(CharStream _sourceCode, size_t _size) | ||||
| { | ||||
| 	vector<Individual> individuals; | ||||
| 	for (size_t i = 0; i < _size; ++i) | ||||
| 		individuals.push_back({Chromosome::makeRandom(randomChromosomeLength())}); | ||||
| 
 | ||||
| 	return Population(_sourcePath, individuals); | ||||
| 	return Population(move(_sourceCode), individuals); | ||||
| } | ||||
| 
 | ||||
| size_t Population::measureFitness(Chromosome const& _chromosome, string const& _sourcePath) | ||||
| size_t Population::measureFitness(Chromosome const& _chromosome, CharStream& _sourceCode) | ||||
| { | ||||
| 	auto program = Program::load(_sourcePath); | ||||
| 	auto program = Program::load(_sourceCode); | ||||
| 	program.optimise(_chromosome.optimisationSteps()); | ||||
| 	return program.codeSize(); | ||||
| } | ||||
| @ -87,7 +88,7 @@ void Population::run(optional<size_t> _numRounds, ostream& _outputStream) | ||||
| 
 | ||||
| ostream& phaser::operator<<(ostream& _stream, Population const& _population) | ||||
| { | ||||
| 	_stream << "Source: " << _population.m_sourcePath << endl; | ||||
| 	_stream << "Stream name: " << _population.m_sourceCode.name() << endl; | ||||
| 
 | ||||
| 	auto individual = _population.m_individuals.begin(); | ||||
| 	for (; individual != _population.m_individuals.end(); ++individual) | ||||
| @ -105,7 +106,7 @@ void Population::doEvaluation() | ||||
| { | ||||
| 	for (auto& individual: m_individuals) | ||||
| 		if (!individual.fitness.has_value()) | ||||
| 			individual.fitness = measureFitness(individual.chromosome, m_sourcePath); | ||||
| 			individual.fitness = measureFitness(individual.chromosome, m_sourceCode); | ||||
| } | ||||
| 
 | ||||
| void Population::doSelection() | ||||
|  | ||||
| @ -20,6 +20,8 @@ | ||||
| #include <tools/yulPhaser/Chromosome.h> | ||||
| #include <tools/yulPhaser/Random.h> | ||||
| 
 | ||||
| #include <liblangutil/CharStream.h> | ||||
| 
 | ||||
| #include <optional> | ||||
| #include <ostream> | ||||
| #include <vector> | ||||
| @ -53,21 +55,21 @@ class Population | ||||
| public: | ||||
| 	static constexpr size_t MaxChromosomeLength = 30; | ||||
| 
 | ||||
| 	explicit Population(std::string const& _sourcePath, std::vector<Chromosome> const& _chromosomes = {}); | ||||
| 	static Population makeRandom(std::string const& _sourcePath, size_t _size); | ||||
| 	explicit Population(langutil::CharStream _sourceCode, std::vector<Chromosome> const& _chromosomes = {}); | ||||
| 	static Population makeRandom(langutil::CharStream _sourceCode, size_t _size); | ||||
| 
 | ||||
| 	void run(std::optional<size_t> _numRounds, std::ostream& _outputStream); | ||||
| 
 | ||||
| 	std::vector<Individual> const& individuals() const { return m_individuals; } | ||||
| 
 | ||||
| 	static size_t randomChromosomeLength() { return binomialRandomInt(MaxChromosomeLength, 0.5); } | ||||
| 	static size_t measureFitness(Chromosome const& _chromosome, std::string const& _sourcePath); | ||||
| 	static size_t measureFitness(Chromosome const& _chromosome, langutil::CharStream& _sourceCode); | ||||
| 
 | ||||
| 	friend std::ostream& operator<<(std::ostream& _stream, Population const& _population); | ||||
| 
 | ||||
| private: | ||||
| 	explicit Population(std::string const& _sourcePath, std::vector<Individual> _individuals = {}): | ||||
| 		m_sourcePath{_sourcePath}, | ||||
| 	explicit Population(langutil::CharStream _sourceCode, std::vector<Individual> _individuals = {}): | ||||
| 		m_sourceCode{std::move(_sourceCode)}, | ||||
| 		m_individuals{std::move(_individuals)} {} | ||||
| 
 | ||||
| 	void doMutation(); | ||||
| @ -79,7 +81,7 @@ private: | ||||
| 		size_t _count | ||||
| 	); | ||||
| 
 | ||||
| 	std::string m_sourcePath; | ||||
| 	langutil::CharStream m_sourceCode; | ||||
| 
 | ||||
| 	std::vector<Individual> m_individuals; | ||||
| }; | ||||
|  | ||||
| @ -38,11 +38,8 @@ | ||||
| #include <libyul/optimiser/OptimiserStep.h> | ||||
| #include <libyul/optimiser/Suite.h> | ||||
| 
 | ||||
| #include <libsolutil/CommonIO.h> | ||||
| #include <libsolutil/JSON.h> | ||||
| 
 | ||||
| #include <boost/filesystem.hpp> | ||||
| 
 | ||||
| #include <cassert> | ||||
| #include <memory> | ||||
| 
 | ||||
| @ -60,10 +57,11 @@ ostream& operator<<(ostream& _stream, Program const& _program); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| Program Program::load(string const& _sourcePath) | ||||
| Program Program::load(CharStream& _sourceCode) | ||||
| { | ||||
| 	// ASSUMPTION: parseSource() rewinds the stream on its own
 | ||||
| 	Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}); | ||||
| 	unique_ptr<Block> ast = parseSource(dialect, loadSource(_sourcePath)); | ||||
| 	unique_ptr<Block> ast = parseSource(dialect, _sourceCode); | ||||
| 	unique_ptr<AsmAnalysisInfo> analysisInfo = analyzeAST(dialect, *ast); | ||||
| 
 | ||||
| 	Program program( | ||||
| @ -95,14 +93,6 @@ string Program::toJson() const | ||||
| 	return jsonPrettyPrint(serializedAst); | ||||
| } | ||||
| 
 | ||||
| CharStream Program::loadSource(string const& _sourcePath) | ||||
| { | ||||
| 	assertThrow(boost::filesystem::exists(_sourcePath), InvalidProgram, "Source file does not exist"); | ||||
| 
 | ||||
| 	string sourceCode = readFileAsString(_sourcePath); | ||||
| 	return CharStream(sourceCode, _sourcePath); | ||||
| } | ||||
| 
 | ||||
| unique_ptr<Block> Program::parseSource(Dialect const& _dialect, CharStream _source) | ||||
| { | ||||
| 	ErrorList errors; | ||||
|  | ||||
| @ -65,7 +65,7 @@ public: | ||||
| 	{} | ||||
| 	Program operator=(Program&& program) = delete; | ||||
| 
 | ||||
| 	static Program load(std::string const& _sourcePath); | ||||
| 	static Program load(langutil::CharStream& _sourceCode); | ||||
| 	void optimise(std::vector<std::string> const& _optimisationSteps); | ||||
| 
 | ||||
| 	size_t codeSize() const { return computeCodeSize(*m_ast); } | ||||
| @ -84,7 +84,6 @@ private: | ||||
| 		m_nameDispenser(_dialect, *m_ast, {}) | ||||
| 	{} | ||||
| 
 | ||||
| 	static langutil::CharStream loadSource(std::string const& _sourcePath); | ||||
| 	static std::unique_ptr<yul::Block> parseSource( | ||||
| 		yul::Dialect const& _dialect, | ||||
| 		langutil::CharStream _source | ||||
|  | ||||
| @ -18,13 +18,20 @@ | ||||
| #include <tools/yulPhaser/Exceptions.h> | ||||
| #include <tools/yulPhaser/Population.h> | ||||
| 
 | ||||
| #include <libsolutil/Assertions.h> | ||||
| #include <libsolutil/CommonIO.h> | ||||
| #include <liblangutil/CharStream.h> | ||||
| 
 | ||||
| #include <boost/filesystem.hpp> | ||||
| #include <boost/program_options.hpp> | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <string> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity::langutil; | ||||
| using namespace solidity::phaser; | ||||
| using namespace solidity::util; | ||||
| 
 | ||||
| namespace po = boost::program_options; | ||||
| 
 | ||||
| @ -37,9 +44,17 @@ struct CommandLineParsingResult | ||||
| 	po::variables_map arguments; | ||||
| }; | ||||
| 
 | ||||
| CharStream loadSource(string const& _sourcePath) | ||||
| { | ||||
| 	assertThrow(boost::filesystem::exists(_sourcePath), InvalidProgram, "Source file does not exist"); | ||||
| 
 | ||||
| 	string sourceCode = readFileAsString(_sourcePath); | ||||
| 	return CharStream(sourceCode, _sourcePath); | ||||
| } | ||||
| 
 | ||||
| void runAlgorithm(string const& _sourcePath) | ||||
| { | ||||
| 	auto population = Population::makeRandom(_sourcePath, 10); | ||||
| 	auto population = Population::makeRandom(loadSource(_sourcePath), 10); | ||||
| 	population.run(nullopt, cout); | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user