<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 "FunctionContext.hpp"
#include "Variable.hpp"
#include "Utils.hpp"
#include "VisitorUtils.hpp"
#include "Type.hpp"
#include "Options.hpp"

#include "ast/GetConstantValue.hpp"

using namespace eddic;

FunctionContext::FunctionContext(std::shared_ptr<Context> parent, std::shared_ptr<GlobalContext> global_context, Platform platform, std::shared_ptr<Configuration> configuration) : 
        Context(parent, global_context), platform(platform) {
    currentPosition = -INT->size(platform); 
    
    if(configuration->option_defined("fomit-frame-pointer")){
        currentParameter = INT->size(platform);
    } else {
        currentParameter = 2 * INT->size(platform);
    }
}

int FunctionContext::size() const {
    auto size = -currentPosition;

    if(size == -INT->size(platform)){
        return 0;
    }

    return size;
}

std::shared_ptr<Variable> FunctionContext::newParameter(const std::string& variable, std::shared_ptr<const Type> type){
    Position position(PositionType::PARAMETER, currentParameter);

    currentParameter += type->size(platform);

    return std::make_shared<Variable>(variable, type, position);
}

std::shared_ptr<Variable> FunctionContext::newVariable(const std::string& variable, std::shared_ptr<const Type> type){
    currentPosition -= type->size(platform);

    Position position(PositionType::STACK, currentPosition + INT->size(platform));
    auto var = std::make_shared<Variable>(variable, type, position);

    storage[variable] = var;

    return var;
}

FunctionContext::Variables FunctionContext::stored_variables(){
    return storage;
}

std::shared_ptr<Variable> FunctionContext::addVariable(const std::string& variable, std::shared_ptr<const Type> type){
    return variables[variable] = newVariable(variable, type);
}

std::shared_ptr<Variable> FunctionContext::newVariable(std::shared_ptr<Variable> source){
    std::string name = "g_" + source->name() + "_" + toString(temporary++);
    
    if(source->position().isTemporary()){
        Position position(PositionType::TEMPORARY);

        auto var = std::make_shared<Variable>(name, source->type(), position); 
        storage[name] = var;
        return variables[name] = var;
    } else {
        return addVariable(name, source->type());
    }
}

std::shared_ptr<Variable> FunctionContext::addVariable(const std::string& variable, std::shared_ptr<const Type> type, ast::Value& value){
    assert(type->is_const());

    Position position(PositionType::CONST);

    auto val = visit(ast::GetConstantValue(), value);
    
    auto var = std::make_shared<Variable>(variable, type, position, val);
    return variables[variable] = var;
}

std::shared_ptr<Variable> FunctionContext::generate_variable(const std::string& prefix, std::shared_ptr<const Type> type){
    std::string name = prefix + "_" + toString(generated++); 

    return addVariable(name, type);
}

std::shared_ptr<Variable> FunctionContext::addParameter(const std::string& parameter, std::shared_ptr<const Type> type){
    return variables[parameter] = newParameter(parameter, type);
}

std::shared_ptr<Variable> FunctionContext::new_temporary(std::shared_ptr<const Type> type){
    ASSERT((type->is_standard_type() && type != STRING) || type->is_pointer(), "Invalid temprary");

    Position position(PositionType::TEMPORARY);

    std::string name = "t_" + toString(temporary++);
    auto var = std::make_shared<Variable>(name, type, position); 
    storage[name] = var;
    return variables[name] = var;
}

void FunctionContext::storeTemporary(std::shared_ptr<Variable> temp){
    currentPosition -= temp->type()->size(platform);

    Position position(PositionType::STACK, currentPosition + INT->size(platform));
    
    temp->setPosition(position); 
}

void FunctionContext::reallocate_storage(){
    currentPosition = -INT->size(platform);

    auto it = storage.begin();
    auto end = storage.end();

    while(it != end){
        auto v = it->second;

        if(v->position().isStack()){
            currentPosition -= v->type()->size(platform);
            Position position(PositionType::STACK, currentPosition + INT->size(platform));
            v->setPosition(position);
        }

        ++it;
    }
}

void FunctionContext::allocate_in_register(std::shared_ptr<Variable> variable, unsigned int register_){
    assert(variable->position().isStack()); 

    Position position(PositionType::REGISTER, register_);
    variable->setPosition(position);

    reallocate_storage();
}

void FunctionContext::allocate_in_param_register(std::shared_ptr<Variable> variable, unsigned int register_){
    assert(variable->position().isParameter()); 

    Position position(PositionType::PARAM_REGISTER, register_);
    variable->setPosition(position);<commit_msg>Add logging facilities to the FunctionContext<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 "FunctionContext.hpp"
#include "Variable.hpp"
#include "Utils.hpp"
#include "VisitorUtils.hpp"
#include "Type.hpp"
#include "Options.hpp"
#include "logging.hpp"

#include "ast/GetConstantValue.hpp"

using namespace eddic;

FunctionContext::FunctionContext(std::shared_ptr<Context> parent, std::shared_ptr<GlobalContext> global_context, Platform platform, std::shared_ptr<Configuration> configuration) : 
        Context(parent, global_context), platform(platform) {
    currentPosition = -INT->size(platform); 
    
    if(configuration->option_defined("fomit-frame-pointer")){
        currentParameter = INT->size(platform);
    } else {
        currentParameter = 2 * INT->size(platform);
    }
}

int FunctionContext::size() const {
    auto size = -currentPosition;

    if(size == -INT->size(platform)){
        return 0;
    }

    return size;
}

std::shared_ptr<Variable> FunctionContext::newParameter(const std::string& variable, std::shared_ptr<const Type> type){
    Position position(PositionType::PARAMETER, currentParameter);

    currentParameter += type->size(platform);

    return std::make_shared<Variable>(variable, type, position);
}

std::shared_ptr<Variable> FunctionContext::newVariable(const std::string& variable, std::shared_ptr<const Type> type){
    currentPosition -= type->size(platform);

    Position position(PositionType::STACK, currentPosition + INT->size(platform));
    auto var = std::make_shared<Variable>(variable, type, position);

    log::emit<Info>("Variables") << "Allocate " << variable << " at " << position.offset() << log::endl;

    storage[variable] = var;

    return var;
}

FunctionContext::Variables FunctionContext::stored_variables(){
    return storage;
}

std::shared_ptr<Variable> FunctionContext::addVariable(const std::string& variable, std::shared_ptr<const Type> type){
    return variables[variable] = newVariable(variable, type);
}

std::shared_ptr<Variable> FunctionContext::newVariable(std::shared_ptr<Variable> source){
    std::string name = "g_" + source->name() + "_" + toString(temporary++);
    
    if(source->position().isTemporary()){
        Position position(PositionType::TEMPORARY);

        auto var = std::make_shared<Variable>(name, source->type(), position); 
        storage[name] = var;
        return variables[name] = var;
    } else {
        return addVariable(name, source->type());
    }
}

std::shared_ptr<Variable> FunctionContext::addVariable(const std::string& variable, std::shared_ptr<const Type> type, ast::Value& value){
    assert(type->is_const());

    Position position(PositionType::CONST);

    auto val = visit(ast::GetConstantValue(), value);
    
    auto var = std::make_shared<Variable>(variable, type, position, val);
    return variables[variable] = var;
}

std::shared_ptr<Variable> FunctionContext::generate_variable(const std::string& prefix, std::shared_ptr<const Type> type){
    std::string name = prefix + "_" + toString(generated++); 

    return addVariable(name, type);
}

std::shared_ptr<Variable> FunctionContext::addParameter(const std::string& parameter, std::shared_ptr<const Type> type){
    return variables[parameter] = newParameter(parameter, type);
}

std::shared_ptr<Variable> FunctionContext::new_temporary(std::shared_ptr<const Type> type){
    ASSERT((type->is_standard_type() && type != STRING) || type->is_pointer(), "Invalid temprary");

    Position position(PositionType::TEMPORARY);

    std::string name = "t_" + toString(temporary++);
    auto var = std::make_shared<Variable>(name, type, position); 
    storage[name] = var;
    return variables[name] = var;
}

void FunctionContext::storeTemporary(std::shared_ptr<Variable> temp){
    currentPosition -= temp->type()->size(platform);

    Position position(PositionType::STACK, currentPosition + INT->size(platform));
    
    log::emit<Info>("Variables") << "Store temporary " << temp->name() << " at " << position.offset() << log::endl;
    
    temp->setPosition(position); 
}

void FunctionContext::reallocate_storage(){
    currentPosition = -INT->size(platform);

    auto it = storage.begin();
    auto end = storage.end();

    while(it != end){
        auto v = it->second;

        if(v->position().isStack()){
            currentPosition -= v->type()->size(platform);
            Position position(PositionType::STACK, currentPosition + INT->size(platform));
            v->setPosition(position);
    
            log::emit<Info>("Variables") << "Reallocate " << v->name() << " at " << position.offset() << log::endl;
        }

        ++it;
    }
}

void FunctionContext::allocate_in_register(std::shared_ptr<Variable> variable, unsigned int register_){
    assert(variable->position().isStack()); 

    Position position(PositionType::REGISTER, register_);
    variable->setPosition(position);

    reallocate_storage();
}

void FunctionContext::allocate_in_param_register(std::shared_ptr<Variable> variable, unsigned int register_){
    assert(variable->position().isParameter()); 

    Position position(PositionType::PARAM_REGISTER, register_);
    variable->setPosition(position);
{'fraction_non_alphanumeric': 0.17089982060239825, 'fraction_numerical': 0.002266074969313568, 'mean_word_length': 4.977426636568849, 'pattern_counts': {'":': 0, '<': 92, '<?xml version=': 0, '>': 124, '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': '4404839', 'n_tokens_mistral': 2994, 'n_tokens_neox': 2900, 'n_words': 585}