<commit_before>/*
 * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file
 * @brief       Processor architecture specification.
 * @author      <NAME>
 */
#ifndef FIRM_BE_BEARCH_H
#define FIRM_BE_BEARCH_H

#include <stdbool.h>

#include "firm_types.h"
#include "obst.h"
#include "raw_bitset.h"

#include "be_types.h"
#include "beinfo.h"
#include "be.h"

/**
 * this constant is returned by the get_sp_bias functions if the stack
 * is reset (usually because the frame pointer is copied to the stack
 * pointer
 */
#define SP_BIAS_RESET      INT_MIN

typedef enum arch_register_class_flags_t {
	arch_register_class_flag_none      = 0,
	/** don't do automatic register allocation for this class */
	arch_register_class_flag_manual_ra = 1U << 0,
	/** the register models an abstract state (example: fpu rounding mode) */
	arch_register_class_flag_state     = 1U << 1
} arch_register_class_flags_t;
ENUM_BITSET(arch_register_class_flags_t)

typedef enum arch_register_type_t {
	arch_register_type_none         = 0,
	/** Do not consider this register when allocating. */
	arch_register_type_ignore       = 1U << 0,
	/** The emitter can choose an arbitrary register. The register fulfills any
	 * register constraints as long as the register class matches */
	arch_register_type_joker        = 1U << 1,
	/** This is just a virtual register. Virtual registers fulfill any register
	 * constraints as long as the register class matches. It is a allowed to
	 * have multiple definitions for the same virtual register at a point */
	arch_register_type_virtual      = 1U << 2,
	/** The register represents a state that should be handled by bestate
	 * code */
	arch_register_type_state        = 1U << 3,
} arch_register_type_t;
ENUM_BITSET(arch_register_type_t)

/**
 * Different types of register allocation requirements.
 */
typedef enum arch_register_req_type_t {
	/** No register requirement. */
	arch_register_req_type_none              = 0,
	/** All registers in the class are allowed. */
	arch_register_req_type_normal            = 1U << 0,
	/** Only a real subset of the class is allowed. */
	arch_register_req_type_limited           = 1U << 1,
	/** The register should be equal to another one at the node. */
	arch_register_req_type_should_be_same    = 1U << 2,
	/** The register must be unequal from some other at the node. */
	arch_register_req_type_must_be_different = 1U << 3,
	/** The registernumber should be aligned (in case of multiregister values)*/
	arch_register_req_type_aligned           = 1U << 4,
	/** ignore while allocating registers */
	arch_register_req_type_ignore            = 1U << 5,
	/** the output produces a new value for the stack pointer
	 * (this is not really a constraint but a marker to guide the stackpointer
	 * rewiring logic) */
	arch_register_req_type_produces_sp       = 1U << 6,
} arch_register_req_type_t;
ENUM_BITSET(arch_register_req_type_t)

extern arch_register_req_t const arch_no_requirement;
#define arch_no_register_req (&arch_no_requirement)

/**
 * Print information about a register requirement in human readable form
 * @param F   output stream/file
 * @param req The requirements structure to format.
 */
void arch_dump_register_req(FILE *F, const arch_register_req_t *req,
                            const ir_node *node);

void arch_dump_register_reqs(FILE *F, const ir_node *node);
void arch_dump_reqs_and_registers(FILE *F, const ir_node *node);

void arch_set_frame_offset(ir_node *irn, int bias);

ir_entity *arch_get_frame_entity(const ir_node *irn);
int        arch_get_sp_bias(ir_node *irn);

int             arch_get_op_estimated_cost(const ir_node *irn);
arch_inverse_t *arch_get_inverse(const ir_node *irn, int i,
                                 arch_inverse_t *inverse,
                                 struct obstack *obstack);
int             arch_possible_memory_operand(const ir_node *irn,
                                             unsigned int i);
void            arch_perform_memory_operand(ir_node *irn, ir_node *spill,
                                            unsigned int i);

/**
 * Get the register allocated for a value.
 */
const arch_register_t *arch_get_irn_register(const ir_node *irn);

/**
 * Assign register to a value
 */
void arch_set_irn_register(ir_node *irn, const arch_register_t *reg);

/**
 * Set the register for a certain output operand.
 */
void arch_set_irn_register_out(ir_node *irn, unsigned pos, const arch_register_t *r);

const arch_register_t *arch_get_irn_register_out(const ir_node *irn, unsigned pos);
const arch_register_t *arch_get_irn_register_in(const ir_node *irn, int pos);

/**
 * Get register constraints for an operand at position @p
 */
static inline const arch_register_req_t *arch_get_irn_register_req_in(
		const ir_node *node, int pos)
{
	const backend_info_t *info = be_get_info(node);
	if (info->in_reqs == NULL)
		return arch_no_register_req;
	return info->in_reqs[pos];
}

/**
 * Get register constraint for a produced result (the @p pos result)
 */
static inline const arch_register_req_t *arch_get_irn_register_req_out(
		const ir_node *node, unsigned pos)
{
	const backend_info_t *info = be_get_info(node);
	if (info->out_infos == NULL)
		return arch_no_register_req;
	return info->out_infos[pos].req;
}

static inline void arch_set_irn_register_req_out(ir_node *node, unsigned pos,
		const arch_register_req_t *req)
{<commit_msg>bearch: Remove special handling that a node has no backend info, when getting a register requirement of the node.<commit_after>/*
 * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file
 * @brief       Processor architecture specification.
 * @author      <NAME>
 */
#ifndef FIRM_BE_BEARCH_H
#define FIRM_BE_BEARCH_H

#include <stdbool.h>

#include "firm_types.h"
#include "obst.h"
#include "raw_bitset.h"

#include "be_types.h"
#include "beinfo.h"
#include "be.h"

/**
 * this constant is returned by the get_sp_bias functions if the stack
 * is reset (usually because the frame pointer is copied to the stack
 * pointer
 */
#define SP_BIAS_RESET      INT_MIN

typedef enum arch_register_class_flags_t {
	arch_register_class_flag_none      = 0,
	/** don't do automatic register allocation for this class */
	arch_register_class_flag_manual_ra = 1U << 0,
	/** the register models an abstract state (example: fpu rounding mode) */
	arch_register_class_flag_state     = 1U << 1
} arch_register_class_flags_t;
ENUM_BITSET(arch_register_class_flags_t)

typedef enum arch_register_type_t {
	arch_register_type_none         = 0,
	/** Do not consider this register when allocating. */
	arch_register_type_ignore       = 1U << 0,
	/** The emitter can choose an arbitrary register. The register fulfills any
	 * register constraints as long as the register class matches */
	arch_register_type_joker        = 1U << 1,
	/** This is just a virtual register. Virtual registers fulfill any register
	 * constraints as long as the register class matches. It is a allowed to
	 * have multiple definitions for the same virtual register at a point */
	arch_register_type_virtual      = 1U << 2,
	/** The register represents a state that should be handled by bestate
	 * code */
	arch_register_type_state        = 1U << 3,
} arch_register_type_t;
ENUM_BITSET(arch_register_type_t)

/**
 * Different types of register allocation requirements.
 */
typedef enum arch_register_req_type_t {
	/** No register requirement. */
	arch_register_req_type_none              = 0,
	/** All registers in the class are allowed. */
	arch_register_req_type_normal            = 1U << 0,
	/** Only a real subset of the class is allowed. */
	arch_register_req_type_limited           = 1U << 1,
	/** The register should be equal to another one at the node. */
	arch_register_req_type_should_be_same    = 1U << 2,
	/** The register must be unequal from some other at the node. */
	arch_register_req_type_must_be_different = 1U << 3,
	/** The registernumber should be aligned (in case of multiregister values)*/
	arch_register_req_type_aligned           = 1U << 4,
	/** ignore while allocating registers */
	arch_register_req_type_ignore            = 1U << 5,
	/** the output produces a new value for the stack pointer
	 * (this is not really a constraint but a marker to guide the stackpointer
	 * rewiring logic) */
	arch_register_req_type_produces_sp       = 1U << 6,
} arch_register_req_type_t;
ENUM_BITSET(arch_register_req_type_t)

extern arch_register_req_t const arch_no_requirement;
#define arch_no_register_req (&arch_no_requirement)

/**
 * Print information about a register requirement in human readable form
 * @param F   output stream/file
 * @param req The requirements structure to format.
 */
void arch_dump_register_req(FILE *F, const arch_register_req_t *req,
                            const ir_node *node);

void arch_dump_register_reqs(FILE *F, const ir_node *node);
void arch_dump_reqs_and_registers(FILE *F, const ir_node *node);

void arch_set_frame_offset(ir_node *irn, int bias);

ir_entity *arch_get_frame_entity(const ir_node *irn);
int        arch_get_sp_bias(ir_node *irn);

int             arch_get_op_estimated_cost(const ir_node *irn);
arch_inverse_t *arch_get_inverse(const ir_node *irn, int i,
                                 arch_inverse_t *inverse,
                                 struct obstack *obstack);
int             arch_possible_memory_operand(const ir_node *irn,
                                             unsigned int i);
void            arch_perform_memory_operand(ir_node *irn, ir_node *spill,
                                            unsigned int i);

/**
 * Get the register allocated for a value.
 */
const arch_register_t *arch_get_irn_register(const ir_node *irn);

/**
 * Assign register to a value
 */
void arch_set_irn_register(ir_node *irn, const arch_register_t *reg);

/**
 * Set the register for a certain output operand.
 */
void arch_set_irn_register_out(ir_node *irn, unsigned pos, const arch_register_t *r);

const arch_register_t *arch_get_irn_register_out(const ir_node *irn, unsigned pos);
const arch_register_t *arch_get_irn_register_in(const ir_node *irn, int pos);

/**
 * Get register constraints for an operand at position @p
 */
static inline const arch_register_req_t *arch_get_irn_register_req_in(
		const ir_node *node, int pos)
{
	const backend_info_t *info = be_get_info(node);
	return info->in_reqs[pos];
}

/**
 * Get register constraint for a produced result (the @p pos result)
 */
static inline const arch_register_req_t *arch_get_irn_register_req_out(
		const ir_node *node, unsigned pos)
{
	const backend_info_t *info = be_get_info(node);
	return info->out_infos[pos].req;
}

static inline void arch_set_irn_register_req_out(ir_node *node, unsigned pos,
		const arch_register_req_t *req)
{
{'fraction_non_alphanumeric': 0.07601998334721066, 'fraction_numerical': 0.006328059950041632, 'mean_word_length': 3.6626552795031055, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3460554', 'n_tokens_mistral': 3786, 'n_tokens_neox': 3651, 'n_words': 1222}