<commit_before>//=======================================================================
// Copyright <NAME> 2011-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef MTAC_FUNCTION_H
#define MTAC_FUNCTION_H

#include <memory>
#include <vector>
#include <utility>
#include <set>

#include "iterators.hpp"

#include "mtac/forward.hpp"
#include "mtac/basic_block.hpp"
#include "mtac/basic_block_iterator.hpp"
#include "mtac/Loop.hpp"

#include "ltac/Register.hpp"
#include "ltac/FloatRegister.hpp"

namespace eddic {

class Function;
class FunctionContext;

namespace mtac {

class Function : public std::enable_shared_from_this<Function> {
    public:
        Function(std::shared_ptr<FunctionContext> context, const std::string& name, eddic::Function& definition);

        //Function cannot be copied
        Function(const Function& rhs) = delete;
        Function& operator=(const Function& rhs) = delete;

        //Function can be moved
        Function(Function&& rhs);
        Function& operator=(Function&& rhs);

        std::string get_name() const;

        void add(std::shared_ptr<mtac::Quadruple> statement);
        std::vector<std::shared_ptr<mtac::Quadruple>>& get_statements();
        void release_statements();

        void create_entry_bb();
        void create_exit_bb();

        basic_block_p current_bb();
        basic_block_p append_bb();
        basic_block_p new_bb();
        
        basic_block_p entry_bb();
        basic_block_p exit_bb();

        basic_block_iterator begin();
        basic_block_iterator end();
        
        basic_block_const_iterator begin() const ;
        basic_block_const_iterator end() const ;
        
        basic_block_iterator at(basic_block_p bb);

        basic_block_iterator insert_before(basic_block_iterator it, basic_block_p block);
        basic_block_iterator insert_after(basic_block_iterator it, basic_block_p block);
        basic_block_iterator merge_basic_blocks(basic_block_iterator it, basic_block_p block);
        basic_block_iterator remove(basic_block_iterator it);
        basic_block_iterator remove(basic_block_p bb);

        std::pair<basic_block_iterator, basic_block_iterator> blocks();

        std::vector<mtac::Loop>& loops();

        std::size_t bb_count() const;
        std::size_t size() const;
        
        std::size_t pseudo_registers();
        void set_pseudo_registers(std::size_t pseudo_registers);
        
        std::size_t pseudo_float_registers();
        void set_pseudo_float_registers(std::size_t pseudo_registers);
        
        const std::set<ltac::Register>& use_registers() const;
        const std::set<ltac::FloatRegister>& use_float_registers() const;
        
        const std::set<ltac::Register>& variable_registers() const;
        const std::set<ltac::FloatRegister>& variable_float_registers() const;
        
        void use(ltac::Register reg);
        void use(ltac::FloatRegister reg);
        
        void variable_use(ltac::Register reg);
        void variable_use(ltac::FloatRegister reg);

        bool is_main() const;

        bool& pure();

        eddic::Function& definition();

        std::shared_ptr<FunctionContext> context;

    private:
        eddic::Function* _definition;

        //Before being partitioned, the function has only statement
        std::vector<std::shared_ptr<mtac::Quadruple>> statements;

        bool _pure = false;
        
        //There is no basic blocks at the beginning<commit_msg>Store Quadruple directly in mtac::Function<commit_after>//=======================================================================
// Copyright <NAME> 2011-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef MTAC_FUNCTION_H
#define MTAC_FUNCTION_H

#include <memory>
#include <vector>
#include <utility>
#include <set>

#include "iterators.hpp"

#include "mtac/forward.hpp"
#include "mtac/basic_block.hpp"
#include "mtac/basic_block_iterator.hpp"
#include "mtac/Loop.hpp"

#include "ltac/Register.hpp"
#include "ltac/FloatRegister.hpp"

namespace eddic {

class Function;
class FunctionContext;

namespace mtac {

class Function : public std::enable_shared_from_this<Function> {
    public:
        Function(std::shared_ptr<FunctionContext> context, const std::string& name, eddic::Function& definition);

        //Function cannot be copied
        Function(const Function& rhs) = delete;
        Function& operator=(const Function& rhs) = delete;

        //Function can be moved
        Function(Function&& rhs);
        Function& operator=(Function&& rhs);

        std::string get_name() const;

        void add(mtac::Quadruple statement);
        
        template< class... Args >
        void emplace_back( Args&&... args ){
            statements.emplace_back(std::forward<Args>(args)...);
        }

        std::vector<mtac::Quadruple>& get_statements();
        void release_statements();

        void create_entry_bb();
        void create_exit_bb();

        basic_block_p current_bb();
        basic_block_p append_bb();
        basic_block_p new_bb();
        
        basic_block_p entry_bb();
        basic_block_p exit_bb();

        basic_block_iterator begin();
        basic_block_iterator end();
        
        basic_block_const_iterator begin() const ;
        basic_block_const_iterator end() const ;
        
        basic_block_iterator at(basic_block_p bb);

        basic_block_iterator insert_before(basic_block_iterator it, basic_block_p block);
        basic_block_iterator insert_after(basic_block_iterator it, basic_block_p block);
        basic_block_iterator merge_basic_blocks(basic_block_iterator it, basic_block_p block);
        basic_block_iterator remove(basic_block_iterator it);
        basic_block_iterator remove(basic_block_p bb);

        std::pair<basic_block_iterator, basic_block_iterator> blocks();

        std::vector<mtac::Loop>& loops();

        std::size_t bb_count() const;
        std::size_t size() const;
        
        std::size_t pseudo_registers();
        void set_pseudo_registers(std::size_t pseudo_registers);
        
        std::size_t pseudo_float_registers();
        void set_pseudo_float_registers(std::size_t pseudo_registers);
        
        const std::set<ltac::Register>& use_registers() const;
        const std::set<ltac::FloatRegister>& use_float_registers() const;
        
        const std::set<ltac::Register>& variable_registers() const;
        const std::set<ltac::FloatRegister>& variable_float_registers() const;
        
        void use(ltac::Register reg);
        void use(ltac::FloatRegister reg);
        
        void variable_use(ltac::Register reg);
        void variable_use(ltac::FloatRegister reg);

        bool is_main() const;

        bool& pure();

        eddic::Function& definition();

        std::shared_ptr<FunctionContext> context;

    private:
        eddic::Function* _definition;

        //Before being partitioned, the function has only statement
        std::vector<mtac::Quadruple> statements;

        bool _pure = false;
        
        //There is no basic blocks at the beginning
{'fraction_non_alphanumeric': 0.13876622507694367, 'fraction_numerical': 0.0037468218921450553, 'mean_word_length': 3.290470723306544, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '484012', 'n_tokens_mistral': 2181, 'n_tokens_neox': 2089, 'n_words': 469}