mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-11-03 23:00:58 +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 };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 |