GCC Middle and Back End API Reference
ira-costs.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "regset.h"
#include "ira.h"
#include "ira-int.h"
#include "addresses.h"
#include "reload.h"
#include "print-rtl.h"
Include dependency graph for ira-costs.cc:

Data Structures

struct  costs
struct  cost_classes
struct  cost_classes_hasher


#define max_struct_costs_size    (this_target_ira_int->x_max_struct_costs_size)
#define init_cost    (this_target_ira_int->x_init_cost)
#define temp_costs    (this_target_ira_int->x_temp_costs)
#define op_costs    (this_target_ira_int->x_op_costs)
#define this_op_costs    (this_target_ira_int->x_this_op_costs)
#define COSTS(arr, num)    ((struct costs *) ((char *) (arr) + (num) * struct_costs_size))
#define COST_INDEX(regno)


typedef struct cost_classescost_classes_t
typedef const struct cost_classesconst_cost_classes_t


static void complete_cost_classes (cost_classes_t classes_ptr)
static void initiate_regno_cost_classes (void)
static cost_classes_t setup_cost_classes (cost_classes_t from)
static cost_classes_t restrict_cost_classes (cost_classes_t full, machine_mode mode, const_hard_reg_set regs)
static void setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
static void setup_regno_cost_classes_by_mode (int regno, machine_mode mode)
static void finish_regno_cost_classes (void)
static int copy_cost (rtx x, machine_mode mode, reg_class_t rclass, bool to_p, secondary_reload_info *prev_sri)
static void record_reg_classes (int n_alts, int n_ops, rtx *ops, machine_mode *modes, const char **constraints, rtx_insn *insn, enum reg_class *pref)
static bool ok_for_index_p_nonstrict (rtx reg)
static bool ok_for_base_p_nonstrict (rtx reg, machine_mode mode, addr_space_t as, enum rtx_code outer_code, enum rtx_code index_code)
static void record_address_regs (machine_mode mode, addr_space_t as, rtx x, int context, enum rtx_code outer_code, enum rtx_code index_code, int scale)
static void record_operand_costs (rtx_insn *insn, enum reg_class *pref)
static rtx_insnscan_one_insn (rtx_insn *insn)
static void print_allocno_costs (void)
static void print_pseudo_costs (void)
static void process_bb_for_costs (basic_block bb)
static void process_bb_node_for_costs (ira_loop_tree_node_t loop_tree_node)
static bool validate_autoinc_and_mem_addr_p (rtx x)
static bool equiv_can_be_consumed_p (int regno, rtx to, rtx_insn *insn)
static bool get_equiv_regno (rtx x, int &regno, rtx &subreg)
static void calculate_equiv_gains (void)
static void find_costs_and_classes (void)
static void process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node)
static void setup_allocno_class_and_costs (void)
void ira_init_costs_once (void)
void ira_init_costs (void)
static void init_costs (void)
static void finish_costs (void)
void ira_costs (void)
void ira_set_pseudo_classes (bool define_pseudo_classes, FILE *dump_file)
void ira_tune_allocno_costs (void)
void ira_adjust_equiv_reg_cost (unsigned regno, int cost)
void ira_costs_cc_finalize (void)


static bool pseudo_classes_defined_p = false
static bool allocno_p
static int cost_elements_num
static struct costs * costs
static struct coststotal_allocno_costs
static size_t struct_costs_size
static enum reg_class * pref
static enum reg_class * pref_buffer
static enum reg_class * regno_aclass
static int * regno_equiv_gains
static int frequency
static cost_classes_tregno_cost_classes
static hash_table< cost_classes_hasher > * cost_classes_htab
static cost_classes_t cost_classes_aclass_cache [N_REG_CLASSES]
static cost_classes_t cost_classes_mode_cache [MAX_MACHINE_MODE]
static cost_classes all_cost_classes

Macro Definition Documentation


#define COST_INDEX ( regno)
: (int) regno)
ira_allocno_t * ira_curr_regno_allocno_map
Definition ira-build.cc:1755
static bool allocno_p
Definition ira-costs.cc:45
#define ALLOCNO_NUM(A)
Definition ira-int.h:431
Return index in COSTS when processing reg with REGNO.   

Referenced by calculate_equiv_gains(), record_address_regs(), record_reg_classes(), and scan_one_insn().


#define COSTS ( arr,
num )    ((struct costs *) ((char *) (arr) + (num) * struct_costs_size))
Return pointer to structure containing costs of allocno or pseudo
with given NUM in array ARR.   

Referenced by find_costs_and_classes(), print_allocno_costs(), print_pseudo_costs(), record_address_regs(), scan_one_insn(), and setup_allocno_class_and_costs().

◆ init_cost

◆ max_struct_costs_size

#define max_struct_costs_size    (this_target_ira_int->x_max_struct_costs_size)

◆ op_costs

◆ temp_costs

#define temp_costs    (this_target_ira_int->x_temp_costs)

◆ this_op_costs

#define this_op_costs    (this_target_ira_int->x_this_op_costs)

Typedef Documentation

◆ const_cost_classes_t

typedef const struct cost_classes* const_cost_classes_t

◆ cost_classes_t

typedef struct cost_classes* cost_classes_t
Types of pointers to the structure above.   

Function Documentation

◆ calculate_equiv_gains()

◆ complete_cost_classes()

static void complete_cost_classes ( cost_classes_t classes_ptr)
Use the array of classes in CLASSES_PTR to fill out the rest of
the structure.   

References cost_classes::classes, cost_classes::hard_regno_index, i, cost_classes::index, ira_class_hard_regs, ira_class_hard_regs_num, and cost_classes::num.

Referenced by initiate_regno_cost_classes(), and setup_cost_classes().

◆ copy_cost()

static int copy_cost ( rtx x,
machine_mode mode,
reg_class_t rclass,
bool to_p,
secondary_reload_info * prev_sri )
Compute the cost of loading X into (if TO_P is TRUE) or from (if
TO_P is FALSE) a register of class RCLASS in mode MODE.  X must not
be a pseudo register.   

References copy_cost(), COSTS_N_INSNS, secondary_reload_info::extra_cost, GET_CODE, ira_init_register_move_cost_if_necessary(), ira_memory_move_cost, ira_register_move_cost, MEM_P, secondary_reload_info::prev_sri, REG_P, REGNO, secondary_reload_info::t_icode, and targetm.

Referenced by copy_cost(), and record_reg_classes().

◆ equiv_can_be_consumed_p()

static bool equiv_can_be_consumed_p ( int regno,
rtx to,
rtx_insn * insn )
Check that reg REGNO can be changed by TO in INSN.  Return true in case the
result insn would be valid one.   

References cancel_changes(), PATTERN(), regno_reg_rtx, validate_autoinc_and_mem_addr_p(), validate_replace_src_group(), and verify_changes().

Referenced by calculate_equiv_gains().

◆ find_costs_and_classes()

static void find_costs_and_classes ( void )
Find costs of register classes and memory for allocnos or pseudos
and their best costs.  Set up preferred, alternative and allocno
classes for pseudos.   

References a, add_cost(), ALLOCNO_CLASS_COST, ALLOCNO_LOOP_TREE_NODE, ALLOCNO_MODE, ALLOCNO_NEXT_REGNO_ALLOCNO, ALLOCNO_NUM, allocno_p, ALLOCNO_REGNO, bitmap_bit_p, calculate_equiv_gains(), cfun, cost_classes::classes, cost_elements_num, COSTS, first_moveable_pseudo, FOR_EACH_ALLOCNO, FOR_EACH_BB_FN, hard_reg_set_subset_p(), HOST_BITS_PER_INT, i, basic_block_def::index, cost_classes::index, init_recog(), INT_MAX, internal_flag_ira_verbose, ira_add_allocno_pref(), ira_allocate(), ira_allocno_class_translate, ira_allocnos_num, ira_assert, ira_class_hard_regs, ira_class_hard_regs_num, ira_class_subset_p, ira_dump_file, ira_free(), ira_important_classes_num, ira_init_register_move_cost_if_necessary(), ira_loop_tree_root, ira_reg_allocno_class_p, ira_reg_class_intersect, ira_reg_class_max_nregs, ira_reg_class_subunion, ira_reg_class_superunion, IRA_REGION_ALL, IRA_REGION_MIXED, ira_register_move_cost, ira_regno_allocno_map, ira_traverse_loop_tree(), ira_use_lra_p, last_moveable_pseudo, MAX, max_reg_num(), max_struct_costs_size, costs::mem_cost, non_spilled_static_chain_regno_p(), NULL, NULL_RTX, cost_classes::num, pic_offset_table_rtx, pref, pref_buffer, print_allocno_costs(), print_pseudo_costs(), process_bb_for_costs(), process_bb_node_for_costs(), pseudo_classes_defined_p, PSEUDO_REGNO_MODE, reg_class_contents, reg_class_names, reg_class_size, reg_class_subunion, reg_preferred_class(), REGNO, regno_aclass, ira_loop_tree_node::regno_allocno_map, regno_cost_classes, regno_equiv_gains, regno_reg_rtx, resize_reg_info(), setup_reg_classes(), setup_regno_cost_classes_by_aclass(), setup_regno_cost_classes_by_mode(), struct_costs_size, targetm, temp_costs, and total_allocno_costs.

Referenced by ira_costs(), and ira_set_pseudo_classes().

◆ finish_costs()

static void finish_costs ( void )
Common finalization function for ira_costs and

References finish_subregs_of_mode(), ira_free(), pref_buffer, regno_aclass, and regno_equiv_gains.

Referenced by ira_costs(), and ira_set_pseudo_classes().

◆ finish_regno_cost_classes()

static void finish_regno_cost_classes ( void )
Finalize info about the cost classes for each pseudo.   

References cost_classes_htab, ira_free(), NULL, and regno_cost_classes.

Referenced by ira_costs(), and ira_set_pseudo_classes().

◆ get_equiv_regno()

static bool get_equiv_regno ( rtx x,
int & regno,
rtx & subreg )
Return true if X contains a pseudo with equivalence.  In this case also
return the pseudo through parameter REG.  If the pseudo is a part of subreg,
return the subreg through parameter SUBREG.   


Referenced by calculate_equiv_gains(), and get_equiv_regno().

◆ init_costs()

static void init_costs ( void )
Common initialization function for ira_costs and

References cost_elements_num, init_subregs_of_mode(), ira_allocate(), max_reg_num(), max_struct_costs_size, pref_buffer, regno_aclass, and regno_equiv_gains.

Referenced by ira_costs(), and ira_set_pseudo_classes().

◆ initiate_regno_cost_classes()

◆ ira_adjust_equiv_reg_cost()

void ira_adjust_equiv_reg_cost ( unsigned regno,
int cost )
A hook from the reload pass.  Add COST to the estimated gain for eliminating
REGNO with its equivalence.  If COST is zero, record that no such
elimination is possible.   

References costs::cost, ira_assert, ira_use_lra_p, and regno_equiv_gains.

Referenced by calculate_elim_costs_all_insns(), and note_reg_elim_costly().

◆ ira_costs()

◆ ira_costs_cc_finalize()

void ira_costs_cc_finalize ( void )

References this_target_ira_int.

Referenced by toplev::finalize().

◆ ira_init_costs()

void ira_init_costs ( void )
This is called each time register related information is

References i, init_cost, ira_important_classes_num, max_struct_costs_size, costs::mem_cost, op_costs, temp_costs, this_op_costs, and this_target_ira_int.

Referenced by ira_init().

◆ ira_init_costs_once()

void ira_init_costs_once ( void )
Function called once during compiler work.   

References i, init_cost, NULL, op_costs, temp_costs, and this_op_costs.

Referenced by ira_init_once().

◆ ira_set_pseudo_classes()

void ira_set_pseudo_classes ( bool define_pseudo_classes,
FILE * dump_file )
Entry function which defines classes for pseudos.
Set pseudo_classes_defined_p only if DEFINE_PSEUDO_CLASSES is true.   

References allocno_p, cost_elements_num, dump_file, find_costs_and_classes(), finish_costs(), finish_regno_cost_classes(), init_costs(), initiate_regno_cost_classes(), internal_flag_ira_verbose, ira_dump_file, max_reg_num(), and pseudo_classes_defined_p.

Referenced by ira(), move_loop_invariants(), and one_code_hoisting_pass().

◆ ira_tune_allocno_costs()

◆ ok_for_base_p_nonstrict()

static bool ok_for_base_p_nonstrict ( rtx reg,
machine_mode mode,
addr_space_t as,
enum rtx_code outer_code,
enum rtx_code index_code )
A version of regno_ok_for_base_p for use here, when all
pseudo-registers should count as OK.  Arguments as for

References ok_for_base_p_1(), and REGNO.

Referenced by record_address_regs().

◆ ok_for_index_p_nonstrict()

static bool ok_for_index_p_nonstrict ( rtx reg)
Wrapper around REGNO_OK_FOR_INDEX_P, to allow pseudo registers.   

References REGNO.

Referenced by record_address_regs().

◆ print_allocno_costs()

◆ print_pseudo_costs()

static void print_pseudo_costs ( void )

◆ process_bb_for_costs()

static void process_bb_for_costs ( basic_block bb)
Traverse the BB represented by LOOP_TREE_NODE to update the allocno

References FOR_BB_INSNS, frequency, REG_FREQ_FROM_BB, and scan_one_insn().

Referenced by find_costs_and_classes(), and process_bb_node_for_costs().

◆ process_bb_node_for_costs()

static void process_bb_node_for_costs ( ira_loop_tree_node_t loop_tree_node)
Traverse the BB represented by LOOP_TREE_NODE to update the allocno

References ira_loop_tree_node::bb, NULL, and process_bb_for_costs().

Referenced by find_costs_and_classes().

◆ process_bb_node_for_hard_reg_moves()

static void process_bb_node_for_hard_reg_moves ( ira_loop_tree_node_t loop_tree_node)

◆ record_address_regs()

static void record_address_regs ( machine_mode mode,
addr_space_t as,
rtx x,
int context,
enum rtx_code outer_code,
enum rtx_code index_code,
int scale )
Record the pseudo registers we must reload into hard registers in a
subexpression of a memory address, X.

If CONTEXT is 0, we are looking at the base part of an address,
otherwise we are looking at the index part.

MODE and AS are the mode and address space of the memory reference;
OUTER_CODE and INDEX_CODE give the context that the rtx appears in.
These four arguments are passed down to base_reg_class.

SCALE is twice the amount to multiply the cost by (it is twice so
we can represent half-cost adjustments).   

References add_cost(), ALLOCNO_BAD_SPILL_P, allocno_p, base_reg_class(), cost_classes::classes, CONST_SCALAR_INT_P, CONSTANT_P, costs::cost, COST_INDEX, COSTS, GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, INT_MAX, ira_curr_regno_allocno_map, ira_init_register_move_cost_if_necessary(), ira_may_move_in_cost, ira_memory_move_cost, costs::mem_cost, cost_classes::num, ok_for_base_p_nonstrict(), ok_for_index_p_nonstrict(), record_address_regs(), REG_P, REG_POINTER, REGNO, regno_cost_classes, SUBREG_REG, and XEXP.

Referenced by record_address_regs(), record_operand_costs(), and scan_one_insn().

◆ record_operand_costs()

◆ record_reg_classes()

static void record_reg_classes ( int n_alts,
int n_ops,
rtx * ops,
machine_mode * modes,
const char ** constraints,
rtx_insn * insn,
enum reg_class * pref )
Record the cost of using memory or hard registers of various
classes for the operands in INSN.

N_ALTS is the number of alternatives.
N_OPS is the number of operands.
OPS is an array of the operands.
MODES are the modes of the operands, in case any are VOIDmode.
CONSTRAINTS are the constraints to use for the operands.  This array
is modified by this procedure.

This procedure works alternative by alternative.  For each
alternative we assume that we will be able to allocate all allocnos
to their ideal register class and calculate the cost of using that
alternative.  Then we compute, for each operand that is a
pseudo-register, the cost of having the allocno allocated to each
register class and using it in that alternative.  To this cost is
added the cost of the alternative.

The cost of each class for this insn is its lowest cost among all
the alternatives.   

References a, ADDR_SPACE_GENERIC, address_operand(), ALLOCNO_BAD_SPILL_P, allocno_p, base_reg_class(), BLOCK_FOR_INSN(), cost_classes::classes, CONST_INT_P, CONSTANT_P, constraints, copy_cost(), costs::cost, COST_INDEX, dump_insn_slim(), extract_mem_from_operand(), find_reg_note(), fputc(), frequency, get_insn_name(), GET_MODE, get_preferred_alternatives(), i, INSN_CODE, INSN_UID(), internal_flag_ira_verbose, INTVAL, ira_assert, ira_curr_regno_allocno_map, ira_dump_file, ira_init_register_move_cost_if_necessary(), ira_may_move_in_cost, ira_may_move_out_cost, ira_memory_move_cost, ira_reg_class_intersect, ira_reg_class_subunion, ira_register_move_cost, LEGITIMATE_PIC_OPERAND_P, costs::mem_cost, MEM_P, MIN, modes, recog_data_d::n_operands, NULL, cost_classes::num, op_costs, OP_IN, OP_INOUT, OP_OUT, recog_data_d::operand_type, pref, recog_data, reg_class_names, reg_fits_class_p(), REG_FREQ_FROM_BB, REG_P, REGNO, regno_cost_classes, rtx_equal_p(), skip_alternative(), struct_costs_size, TEST_BIT, and this_op_costs.

Referenced by record_operand_costs().

◆ restrict_cost_classes()

static cost_classes_t restrict_cost_classes ( cost_classes_t full,
machine_mode mode,
const_hard_reg_set regs )

◆ scan_one_insn()

◆ setup_allocno_class_and_costs()

static void setup_allocno_class_and_costs ( void )

◆ setup_cost_classes()

static cost_classes_t setup_cost_classes ( cost_classes_t from)
Create new cost classes from cost classes FROM and set up members
index and hard_regno_index.  Return the new classes.  The function
implements some common code of two functions
setup_regno_cost_classes_by_aclass and

References cost_classes::classes, complete_cost_classes(), i, ira_allocate(), and cost_classes::num.

Referenced by restrict_cost_classes(), and setup_regno_cost_classes_by_aclass().

◆ setup_regno_cost_classes_by_aclass()

static void setup_regno_cost_classes_by_aclass ( int regno,
enum reg_class aclass )
Setup cost classes for pseudo REGNO whose allocno class is ACLASS.
This function is used when we know an initial approximation of
allocno class of the pseudo already, e.g. on the second iteration
of class cost calculation or after class cost calculation in
register-pressure sensitive insn scheduling or register-pressure
sensitive loop-invariant motion.   

References cost_classes::classes, cost_classes_aclass_cache, cost_classes_htab, hard_reg_set_subset_p(), i, ira_important_classes, ira_important_classes_num, ira_uniform_class_p, NULL, NULL_RTX, PSEUDO_REGNO_MODE, reg_class_contents, regno_cost_classes, regno_reg_rtx, restrict_cost_classes(), setup_cost_classes(), and valid_mode_changes_for_regno().

Referenced by find_costs_and_classes().

◆ setup_regno_cost_classes_by_mode()

static void setup_regno_cost_classes_by_mode ( int regno,
machine_mode mode )
Setup cost classes for pseudo REGNO with MODE.  Usage of MODE can
decrease number of cost classes for the pseudo, if hard registers
of some important classes cannot hold a value of MODE.  So the
pseudo cannot get hard register of some important classes and cost
calculation for such important classes is only wasting CPU

References all_cost_classes, cost_classes_mode_cache, NULL, reg_class_contents, regno_cost_classes, restrict_cost_classes(), and valid_mode_changes_for_regno().

Referenced by find_costs_and_classes().

◆ validate_autoinc_and_mem_addr_p()

static bool validate_autoinc_and_mem_addr_p ( rtx x)

Variable Documentation

◆ all_cost_classes

cost_classes all_cost_classes
Cost classes that include all classes in ira_important_classes.   

Referenced by initiate_regno_cost_classes(), and setup_regno_cost_classes_by_mode().

◆ allocno_p

◆ cost_classes_aclass_cache

cost_classes_t cost_classes_aclass_cache[N_REG_CLASSES]
Map allocno class -> cost classes for pseudo of given allocno

Referenced by initiate_regno_cost_classes(), and setup_regno_cost_classes_by_aclass().

◆ cost_classes_htab

◆ cost_classes_mode_cache

cost_classes_t cost_classes_mode_cache[MAX_MACHINE_MODE]
Map mode -> cost classes for pseudo of give mode.   

Referenced by initiate_regno_cost_classes(), and setup_regno_cost_classes_by_mode().

◆ cost_elements_num

int cost_elements_num
Number of elements in array `costs'.   

Referenced by find_costs_and_classes(), init_costs(), ira_costs(), and ira_set_pseudo_classes().

◆ costs

struct costs* costs
Costs of each class for each allocno or pseudo.   

Referenced by fast_allocation(), and setup_profitable_hard_regs().

◆ frequency

int frequency

◆ pref

◆ pref_buffer

enum reg_class* pref_buffer
Allocated buffers for pref.   

Referenced by find_costs_and_classes(), finish_costs(), and init_costs().

◆ pseudo_classes_defined_p

bool pseudo_classes_defined_p = false
IRA hard register and memory cost calculation for allocnos or pseudos.
   Copyright (C) 2006-2024 Free Software Foundation, Inc.
   Contributed by Vladimir Makarov <vmakarov@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
The flags is set up every time when we calculate pseudo register
classes through function ira_set_pseudo_classes.   

Referenced by find_costs_and_classes(), and ira_set_pseudo_classes().

◆ regno_aclass

enum reg_class* regno_aclass
Record allocno class of each allocno with the same regno.   

Referenced by find_costs_and_classes(), finish_costs(), init_costs(), and setup_allocno_class_and_costs().

◆ regno_cost_classes

◆ regno_equiv_gains

int* regno_equiv_gains
Record cost gains for not allocating a register with an invariant

Referenced by calculate_equiv_gains(), find_costs_and_classes(), finish_costs(), init_costs(), and ira_adjust_equiv_reg_cost().

◆ struct_costs_size

size_t struct_costs_size
It is the current size of struct costs.   

Referenced by find_costs_and_classes(), record_operand_costs(), and record_reg_classes().

◆ total_allocno_costs

struct costs* total_allocno_costs
Accumulated costs of each class for each allocno.   

Referenced by find_costs_and_classes(), ira_costs(), and print_allocno_costs().