<commit_before>//=======================================================================
// Copyright <NAME> 2011.
// 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)
//=======================================================================

#include "assert.hpp"
#include "FunctionContext.hpp"
#include "Utils.hpp"
#include "Type.hpp"

#include "Labels.hpp"
#include "ltac/StatementCompiler.hpp"
#include "ltac/Utils.hpp"

#include "mtac/Utils.hpp" //TODO Perhaps part of this should be moved to ltac ? 

using namespace eddic;

//TODO Avoid as much as possible direct acess to the the registers fields of the manager

ltac::StatementCompiler::StatementCompiler(std::vector<ltac::Register> registers, std::vector<ltac::FloatRegister> float_registers, 
        std::shared_ptr<ltac::Function> function, std::shared_ptr<FloatPool> float_pool) : 
        function(function), manager(registers, float_registers, function, float_pool), float_pool(float_pool) {
    descriptor = getPlatformDescriptor(platform);
}

void ltac::StatementCompiler::set_current(mtac::Statement statement){
    manager.set_current(statement);
}

void ltac::StatementCompiler::reset(){
    manager.reset();

    ended = false;
}

void ltac::StatementCompiler::end_basic_block(){
    manager.spills_all();

    ended = true;
}

void ltac::StatementCompiler::collect_parameters(std::shared_ptr<eddic::Function> definition){
    manager.collect_parameters(definition, descriptor);
}

ltac::Register ltac::StatementCompiler::to_register(std::shared_ptr<Variable> var){
    return ltac::to_register(var, manager);
}

ltac::Argument ltac::StatementCompiler::to_arg(mtac::Argument argument){
    return ltac::to_arg(argument, manager);
}

ltac::Address ltac::StatementCompiler::to_pointer(std::shared_ptr<Variable> var, int offset){
    assert(var->type()->is_pointer());

    auto reg = manager.get_reg(var);
    return ltac::Address(reg, offset);
}

ltac::Address ltac::StatementCompiler::to_address(std::shared_ptr<Variable> var, int offset){
    auto position = var->position();

    assert(!position.isTemporary());

    if(position.isStack()){
        return ltac::Address(ltac::BP, -position.offset() + offset);
    } else if(position.isParameter()){
        //The case of array is special because only the address is passed, not the complete array
        if(var->type()->is_array())
        {
            auto reg = manager.get_free_reg();

            ltac::add_instruction(function, ltac::Operator::MOV, reg, ltac::Address(ltac::BP, position.offset()));

            manager.release(reg);

            return ltac::Address(reg, offset);
        }
        //In the other cases, the value is passed, so we can compute the offset directly
        else {
            return ltac::Address(ltac::BP, position.offset() + offset);
        }
    } else if(position.isGlobal()){
        return ltac::Address("V" + position.name(), offset);
    } 

    ASSERT_PATH_NOT_TAKEN("Should never get there");
}

ltac::Address ltac::StatementCompiler::to_address(std::shared_ptr<Variable> var, mtac::Argument offset){
    if(auto* ptr = boost::get<int>(&offset)){
        return to_address(var, *ptr);
    }

    assert(ltac::is_variable(offset));

    auto position = var->position();
    assert(!position.isTemporary());

    auto offsetReg = manager.get_reg(ltac::get_variable(offset));

    if(position.isStack()){
        return ltac::Address(ltac::BP, offsetReg, 1, -1 * position.offset());
    } else if(position.isParameter()){
        auto reg = manager.get_free_reg();

        ltac::add_instruction(function, ltac::Operator::MOV, reg, ltac::Address(ltac::BP, position.offset()));

        manager.release(reg);

        return ltac::Address(reg, offsetReg);
    } else if(position.isGlobal()){
        return ltac::Address("V" + position.name(), offsetReg);
    } 
<commit_msg>Implement Compilation of Deferencing a temporary<commit_after>//=======================================================================
// Copyright <NAME> 2011.
// 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)
//=======================================================================

#include "assert.hpp"
#include "FunctionContext.hpp"
#include "Utils.hpp"
#include "Type.hpp"

#include "Labels.hpp"
#include "ltac/StatementCompiler.hpp"
#include "ltac/Utils.hpp"

#include "mtac/Utils.hpp" //TODO Perhaps part of this should be moved to ltac ? 

using namespace eddic;

//TODO Avoid as much as possible direct acess to the the registers fields of the manager

ltac::StatementCompiler::StatementCompiler(std::vector<ltac::Register> registers, std::vector<ltac::FloatRegister> float_registers, 
        std::shared_ptr<ltac::Function> function, std::shared_ptr<FloatPool> float_pool) : 
        function(function), manager(registers, float_registers, function, float_pool), float_pool(float_pool) {
    descriptor = getPlatformDescriptor(platform);
}

void ltac::StatementCompiler::set_current(mtac::Statement statement){
    manager.set_current(statement);
}

void ltac::StatementCompiler::reset(){
    manager.reset();

    ended = false;
}

void ltac::StatementCompiler::end_basic_block(){
    manager.spills_all();

    ended = true;
}

void ltac::StatementCompiler::collect_parameters(std::shared_ptr<eddic::Function> definition){
    manager.collect_parameters(definition, descriptor);
}

ltac::Register ltac::StatementCompiler::to_register(std::shared_ptr<Variable> var){
    return ltac::to_register(var, manager);
}

ltac::Argument ltac::StatementCompiler::to_arg(mtac::Argument argument){
    return ltac::to_arg(argument, manager);
}

ltac::Address ltac::StatementCompiler::to_pointer(std::shared_ptr<Variable> var, int offset){
    assert(var->type()->is_pointer());

    auto reg = manager.get_reg(var);
    return ltac::Address(reg, offset);
}

ltac::Address ltac::StatementCompiler::to_address(std::shared_ptr<Variable> var, int offset){
    auto position = var->position();

    if(position.isStack()){
        return ltac::Address(ltac::BP, -position.offset() + offset);
    } else if(position.isParameter()){
        //The case of array is special because only the address is passed, not the complete array
        if(var->type()->is_array())
        {
            auto reg = manager.get_free_reg();

            ltac::add_instruction(function, ltac::Operator::MOV, reg, ltac::Address(ltac::BP, position.offset()));

            manager.release(reg);

            return ltac::Address(reg, offset);
        }
        //In the other cases, the value is passed, so we can compute the offset directly
        else {
            return ltac::Address(ltac::BP, position.offset() + offset);
        }
    } else if(position.isGlobal()){
        return ltac::Address("V" + position.name(), offset);
    } else if(position.isTemporary()){
        auto reg = manager.get_reg(var);
        return ltac::Address(reg);
    }

    ASSERT_PATH_NOT_TAKEN("Should never get there");
}

ltac::Address ltac::StatementCompiler::to_address(std::shared_ptr<Variable> var, mtac::Argument offset){
    if(auto* ptr = boost::get<int>(&offset)){
        return to_address(var, *ptr);
    }

    assert(ltac::is_variable(offset));

    auto position = var->position();
    assert(!position.isTemporary());

    auto offsetReg = manager.get_reg(ltac::get_variable(offset));

    if(position.isStack()){
        return ltac::Address(ltac::BP, offsetReg, 1, -1 * position.offset());
    } else if(position.isParameter()){
        auto reg = manager.get_free_reg();

        ltac::add_instruction(function, ltac::Operator::MOV, reg, ltac::Address(ltac::BP, position.offset()));

        manager.release(reg);

        return ltac::Address(reg, offsetReg);
    } else if(position.isGlobal()){
        return ltac::Address("V" + position.name(), offsetReg);
    } 

{'fraction_non_alphanumeric': 0.17500936212707527, 'fraction_numerical': 0.0029958806640868803, 'mean_word_length': 4.461486025903204, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 37, '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': '7034378', 'n_tokens_mistral': 2444, 'n_tokens_neox': 2311, 'n_words': 501}