mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-10-31 13:20:59 +00:00 
			
		
		
		
	
		
			
	
	
		
			142 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			142 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> | ||
|  |  * | ||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||
|  |  */ | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include <LibJS/Bytecode/BasicBlock.h>
 | ||
|  | #include <LibJS/Bytecode/Generator.h>
 | ||
|  | #include <sys/time.h>
 | ||
|  | #include <time.h>
 | ||
|  | 
 | ||
|  | namespace JS::Bytecode { | ||
|  | 
 | ||
|  | struct PassPipelineExecutable { | ||
|  |     Executable& executable; | ||
|  |     Optional<HashMap<BasicBlock const*, HashTable<BasicBlock const*>>> cfg {}; | ||
|  |     Optional<HashMap<BasicBlock const*, HashTable<BasicBlock const*>>> inverted_cfg {}; | ||
|  |     Optional<HashTable<BasicBlock const*>> exported_blocks {}; | ||
|  | }; | ||
|  | 
 | ||
|  | class Pass { | ||
|  | public: | ||
|  |     Pass() = default; | ||
|  |     virtual ~Pass() = default; | ||
|  | 
 | ||
|  |     virtual void perform(PassPipelineExecutable&) = 0; | ||
|  |     void started() | ||
|  |     { | ||
|  |         gettimeofday(&m_start_time, nullptr); | ||
|  |     } | ||
|  |     void finished() | ||
|  |     { | ||
|  |         struct timeval end_time { | ||
|  |             0, 0 | ||
|  |         }; | ||
|  |         gettimeofday(&end_time, nullptr); | ||
|  |         time_t interval_s = end_time.tv_sec - m_start_time.tv_sec; | ||
|  |         suseconds_t interval_us = end_time.tv_usec; | ||
|  |         if (interval_us < m_start_time.tv_usec) { | ||
|  |             interval_s -= 1; | ||
|  |             interval_us += 1000000; | ||
|  |         } | ||
|  |         interval_us -= m_start_time.tv_usec; | ||
|  |         m_time_difference = interval_s * 1000000 + interval_us; | ||
|  |     } | ||
|  | 
 | ||
|  |     u64 elapsed() const { return m_time_difference; } | ||
|  | 
 | ||
|  | protected: | ||
|  |     struct timeval m_start_time { | ||
|  |         0, 0 | ||
|  |     }; | ||
|  |     u64 m_time_difference { 0 }; | ||
|  | }; | ||
|  | 
 | ||
|  | class PassManager : public Pass { | ||
|  | public: | ||
|  |     PassManager() = default; | ||
|  |     ~PassManager() override = default; | ||
|  | 
 | ||
|  |     void add(NonnullOwnPtr<Pass> pass) { m_passes.append(move(pass)); } | ||
|  | 
 | ||
|  |     template<typename PassT, typename... Args> | ||
|  |     void add(Args&&... args) { m_passes.append(make<PassT>(forward<Args>(args)...)); } | ||
|  | 
 | ||
|  |     void perform(Executable& executable) | ||
|  |     { | ||
|  |         PassPipelineExecutable pipeline_executable { executable }; | ||
|  |         perform(pipeline_executable); | ||
|  |     } | ||
|  | 
 | ||
|  |     virtual void perform(PassPipelineExecutable& executable) override | ||
|  |     { | ||
|  |         started(); | ||
|  |         for (auto& pass : m_passes) | ||
|  |             pass.perform(executable); | ||
|  |         finished(); | ||
|  |     } | ||
|  | 
 | ||
|  | private: | ||
|  |     NonnullOwnPtrVector<Pass> m_passes; | ||
|  | }; | ||
|  | 
 | ||
|  | namespace Passes { | ||
|  | 
 | ||
|  | class GenerateCFG : public Pass { | ||
|  | public: | ||
|  |     GenerateCFG() = default; | ||
|  |     ~GenerateCFG() override = default; | ||
|  | 
 | ||
|  | private: | ||
|  |     virtual void perform(PassPipelineExecutable&) override; | ||
|  | }; | ||
|  | 
 | ||
|  | class MergeBlocks : public Pass { | ||
|  | public: | ||
|  |     MergeBlocks() = default; | ||
|  |     ~MergeBlocks() override = default; | ||
|  | 
 | ||
|  | private: | ||
|  |     virtual void perform(PassPipelineExecutable&) override; | ||
|  | }; | ||
|  | 
 | ||
|  | class PlaceBlocks : public Pass { | ||
|  | public: | ||
|  |     PlaceBlocks() = default; | ||
|  |     ~PlaceBlocks() override = default; | ||
|  | 
 | ||
|  | private: | ||
|  |     virtual void perform(PassPipelineExecutable&) override; | ||
|  | }; | ||
|  | 
 | ||
|  | class UnifySameBlocks : public Pass { | ||
|  | public: | ||
|  |     UnifySameBlocks() = default; | ||
|  |     ~UnifySameBlocks() override = default; | ||
|  | 
 | ||
|  | private: | ||
|  |     virtual void perform(PassPipelineExecutable&) override; | ||
|  | }; | ||
|  | 
 | ||
|  | class DumpCFG : public Pass { | ||
|  | public: | ||
|  |     DumpCFG(FILE* file) | ||
|  |         : m_file(file) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     ~DumpCFG() override = default; | ||
|  | 
 | ||
|  | private: | ||
|  |     virtual void perform(PassPipelineExecutable&) override; | ||
|  | 
 | ||
|  |     FILE* m_file { nullptr }; | ||
|  | }; | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | } |