* regs.h (struct reg_info_def): Add freq field.
(REG_N_REFS): Update comment.
(REG_FREQ): New.
* regclass.c (scan_one_insn): Update REG_FREQ.
* flow.c (mark_set_1): Update REG_FREQ, make REG_N_SETS unweighted.
(attempt_auto_inc): Likewise.
(mark_used_reg): Likewise.
(try_pre_increment_1): Likewise.
* local-alloc.c (struct qty): Add freq field.
(alloc_qty): Set freq.
(update_equiv_regs): Set REG_FREQ.
(QTY_CMP_PRI): Use freq.
(combine_regs): Update qty->freq.
* global.c (struct allocno): Update comment for n_refs;
add freq field.
(local_reg_freq): New array.
(global_alloc): Update freq field;
allocate and initialize local_reg_freq.
(allocno_compare): Use freq field.
(find_reg): Likewise.
* reload1.c (count_pseudo): Use freq isntead of n_refs.
(count_spilled_pseudo): Likewise.
* tm.texi (GCOV_TYPE_SIZE): Document.
* basic-block.h (gcov_type): Define.
(struct edge_def): Use gcov_type for count field.
(struct basic_block_def): Likewise.
* defaults.h (GCOV_TYPE_SIZE): Define.
* final.c (end_final): Use GCOV_TYPE_SIZE.
* flow.c (dump_edge_info, dump_flow_info, dump_bb): Print count fields
using HOST_WIDEST_INT_PRINT_DEC.
* gcov-io.h (__fetch_gcov_type, __store_gcov_type, __read_gcov_type,
__write_gcov_type): New.
(store_long): Remove.
* gcov.c (gcov_type): Set default.
(struct adj_list): Use gcov_type for arc_count.
(bb_info): Use gcov_type for succ_count, pred_count and exec_count.
(create_program_flow_graph): Read arc_count properly.
(solve_program_flow_graph): 'total' is gcov_type.
(output_data): Line_counts is gcov_type, print it properly.
* libgcc2.c (struct bb): Counts is gcov_type.
(__bb_exit_func): Use __read_gcov_type and __write_gcov_type.
* profile.c (LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE): Set default.
(GCOV_TYPE_SIZE): Define.
(struct bb_info): succ_count and pred_count is gcov_type.
(compute_branch_probabilities): Use __read_gcov_type,
print read edges to the dump file.
(total): Is gcov_type.
(gen_edge_profiler): Use GCOV_TYPE_SIZE.
From-SVN: r43505
+Fri Jun 22 19:11:28 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * regs.h (struct reg_info_def): Add freq field.
+ (REG_N_REFS): Update comment.
+ (REG_FREQ): New.
+ * regclass.c (scan_one_insn): Update REG_FREQ.
+ * flow.c (mark_set_1): Update REG_FREQ, make REG_N_SETS unweighted.
+ (attempt_auto_inc): Likewise.
+ (mark_used_reg): Likewise.
+ (try_pre_increment_1): Likewise.
+ * local-alloc.c (struct qty): Add freq field.
+ (alloc_qty): Set freq.
+ (update_equiv_regs): Set REG_FREQ.
+ (QTY_CMP_PRI): Use freq.
+ (combine_regs): Update qty->freq.
+ * global.c (struct allocno): Update comment for n_refs;
+ add freq field.
+ (local_reg_freq): New array.
+ (global_alloc): Update freq field;
+ allocate and initialize local_reg_freq.
+ (allocno_compare): Use freq field.
+ (find_reg): Likewise.
+ * reload1.c (count_pseudo): Use freq isntead of n_refs.
+ (count_spilled_pseudo): Likewise.
+
+ * tm.texi (GCOV_TYPE_SIZE): Document.
+ * basic-block.h (gcov_type): Define.
+ (struct edge_def): Use gcov_type for count field.
+ (struct basic_block_def): Likewise.
+ * defaults.h (GCOV_TYPE_SIZE): Define.
+ * final.c (end_final): Use GCOV_TYPE_SIZE.
+ * flow.c (dump_edge_info, dump_flow_info, dump_bb): Print count fields
+ using HOST_WIDEST_INT_PRINT_DEC.
+ * gcov-io.h (__fetch_gcov_type, __store_gcov_type, __read_gcov_type,
+ __write_gcov_type): New.
+ (store_long): Remove.
+ * gcov.c (gcov_type): Set default.
+ (struct adj_list): Use gcov_type for arc_count.
+ (bb_info): Use gcov_type for succ_count, pred_count and exec_count.
+ (create_program_flow_graph): Read arc_count properly.
+ (solve_program_flow_graph): 'total' is gcov_type.
+ (output_data): Line_counts is gcov_type, print it properly.
+ * libgcc2.c (struct bb): Counts is gcov_type.
+ (__bb_exit_func): Use __read_gcov_type and __write_gcov_type.
+ * profile.c (LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE): Set default.
+ (GCOV_TYPE_SIZE): Define.
+ (struct bb_info): succ_count and pred_count is gcov_type.
+ (compute_branch_probabilities): Use __read_gcov_type,
+ print read edges to the dump file.
+ (total): Is gcov_type.
+ (gen_edge_profiler): Use GCOV_TYPE_SIZE.
+
2001-06-14 Andrew Haley <aph@cambridge.redhat.com>
* optabs.c (emit_libcall_block): When using non-call exceptions,
be done, other than zero the statistics on the first allocation. */
#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
+/* Type we use to hold basic block counters. Should be at least 64bit. */
+typedef HOST_WIDEST_INT gcov_type;
+
/* Control flow edge information. */
typedef struct edge_def {
/* Links through the predecessor and successor lists. */
int flags; /* see EDGE_* below */
int probability; /* biased by REG_BR_PROB_BASE */
- int count; /* Expected number of executions calculated
+ gcov_type count; /* Expected number of executions calculated
in profile.c */
} *edge;
int loop_depth;
/* Expected number of executions: calculated in profile.c. */
- int count;
+ gcov_type count;
/* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */
int frequency;
#define PIC_OFFSET_TABLE_REGNUM INVALID_REGNUM
#endif
+/* Type used by GCOV counters. Use 64bit data type if target supports
+ it. */
+#if LONG_TYPE_SIZE >= 64
+#define GCOV_TYPE_SIZE LONG_TYPE_SIZE
+#else
+#define GCOV_TYPE_SIZE LONG_LONG_TYPE_SIZE
+#endif
+
+
/* By default, the preprocessor should be invoked the same way in C++
as in C. */
#ifndef CPLUSPLUS_CPP_SPEC
largest value that @code{WCHAR_TYPE_SIZE} can have at run-time. This is
used in @code{cpp}.
+@findex GCOV_TYPE_SIZE
+@item GCOV_TYPE_SIZE
+A C expression for the size in bits of the type used for gcov counters on the
+target machine. If you don't define this, the default is one
+@code{LONG_TYPE_SIZE} in case it is greater or equal to 64-bit and
+@code{LONG_LONG_TYPE_SIZE} otherwise. You may want to re-define the type to
+ensure atomicity for counters in multithreaded programs.
+
@findex WINT_TYPE
@item WINT_TYPE
A C expression for a string describing the name of the data type to
struct bb_list *ptr;
struct bb_str *sptr;
int long_bytes = LONG_TYPE_SIZE / BITS_PER_UNIT;
+ int gcov_type_bytes = GCOV_TYPE_SIZE / BITS_PER_UNIT;
int pointer_bytes = POINTER_SIZE / BITS_PER_UNIT;
if (profile_block_flag)
size = long_bytes * count_basic_blocks;
else
- size = long_bytes * count_instrumented_edges;
+ size = gcov_type_bytes * count_instrumented_edges;
rounded = size;
rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
/* Count (weighted) references, stores, etc. This counts a
register twice if it is modified, but that is correct. */
REG_N_SETS (i) += 1;
- REG_N_REFS (i) += (optimize_size ? 1
- : pbi->bb->loop_depth + 1);
+ REG_N_REFS (i) += 1;
+ REG_FREQ (i) += (optimize_size ? 1 : pbi->bb->loop_depth + 1);
/* The insns where a reg is live are normally counted
elsewhere, but we want the count to include the insn
/* Count an extra reference to the reg. When a reg is
incremented, spilling it is worse, so we want to make
that less likely. */
- REG_N_REFS (regno) += (optimize_size ? 1 : pbi->bb->loop_depth + 1);
+ REG_FREQ (regno) += (optimize_size ? 1 : pbi->bb->loop_depth + 1);
/* Count the increment as a setting of the register,
even though it isn't a SET in rtl. */
REG_BASIC_BLOCK (regno_first) = REG_BLOCK_GLOBAL;
/* Count (weighted) number of uses of each reg. */
- REG_N_REFS (regno_first)
+ REG_FREQ (regno_first)
+= (optimize_size ? 1 : pbi->bb->loop_depth + 1);
+ REG_N_REFS (regno_first)++;
}
}
so we want to make that less likely. */
if (regno >= FIRST_PSEUDO_REGISTER)
{
- REG_N_REFS (regno) += (optimize_size ? 1
- : pbi->bb->loop_depth + 1);
+ REG_FREQ (regno) += (optimize_size ? 1 : pbi->bb->loop_depth + 1);
REG_N_SETS (regno)++;
}
register basic_block bb = BASIC_BLOCK (i);
register edge e;
- fprintf (file, "\nBasic block %d: first insn %d, last %d, loop_depth %d, count %d, freq %d.\n",
- i, INSN_UID (bb->head), INSN_UID (bb->end), bb->loop_depth,
- bb->count, bb->frequency);
+ fprintf (file, "\nBasic block %d: first insn %d, last %d, loop_depth %d, count ",
+ i, INSN_UID (bb->head), INSN_UID (bb->end), bb->loop_depth);
+ fprintf (file, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
+ fprintf (file, ", freq %i.\n", bb->frequency);
fprintf (file, "Predecessors: ");
for (e = bb->pred; e; e = e->pred_next)
fprintf (file, " %d", side->index);
if (e->count)
- fprintf (file, " count:%d", e->count);
+ {
+ fprintf (file, " count:");
+ fprintf (file, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) e->count);
+ }
if (e->flags)
{
rtx last;
edge e;
- fprintf (outf, ";; Basic block %d, loop depth %d, count %d",
+ fprintf (outf, ";; Basic block %d, loop depth %d, count ",
bb->index, bb->loop_depth, bb->count);
+ fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
putc ('\n', outf);
fputs (";; Predecessors: ", outf);
#include "intl.h"
#undef abort
+typedef HOST_WIDEST_INT gcov_type;
#include "gcov-io.h"
/* The .bb file format consists of several lists of 4-byte integers
struct adj_list {
int source;
int target;
- int arc_count;
+ gcov_type arc_count;
unsigned int count_valid : 1;
unsigned int on_tree : 1;
unsigned int fake : 1;
struct bb_info {
struct adj_list *succ;
struct adj_list *pred;
- int succ_count;
- int pred_count;
- int exec_count;
+ gcov_type succ_count;
+ gcov_type pred_count;
+ gcov_type exec_count;
unsigned int count_valid : 1;
unsigned int on_tree : 1;
#if 0
for (arcptr = bb_graph[i].succ; arcptr; arcptr = arcptr->succ_next)
if (! arcptr->on_tree)
{
- long tmp_count = 0;
- if (da_file && __read_long (&tmp_count, da_file, 8))
+ gcov_type tmp_count = 0;
+ if (da_file && __read_gcov_type (&tmp_count, da_file, 8))
abort();
arcptr->arc_count = tmp_count;
solve_program_flow_graph (bptr)
struct bb_info_list *bptr;
{
- int passes, changes, total;
+ int passes, changes;
+ gcov_type total;
int i;
struct adj_list *arcptr;
struct bb_info *bb_graph;
int this_file;
/* An array indexed by line number which indicates how many times that line
was executed. */
- long *line_counts;
+ gcov_type *line_counts;
/* An array indexed by line number which indicates whether the line was
present in the bb file (i.e. whether it had code associate with it).
Lines never executed are those which both exist, and have zero execution
else
source_file_name = s_ptr->name;
- line_counts = (long *) xcalloc (sizeof (long), s_ptr->maxlineno);
+ line_counts = (gcov_type *) xcalloc (sizeof (gcov_type), s_ptr->maxlineno);
line_exists = xcalloc (1, s_ptr->maxlineno);
if (output_branch_probs)
branch_probs = (struct arcdata **)
if (line_exists[count])
{
if (line_counts[count])
- fprintf (gcov_file, "%12ld %s", line_counts[count],
- string);
+ {
+ char c[20];
+ sprintf (c, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)line_counts[count]);
+ fprintf (gcov_file, "%12s %s", c,
+ string);
+ }
else
fprintf (gcov_file, " ###### %s", string);
}
/* Number of calls crossed by each allocno. */
int calls_crossed;
- /* Number of refs (weighted) to each allocno. */
+ /* Number of refs to each allocno. */
int n_refs;
+ /* Frequency of uses of each allocno. */
+ int freq;
+
/* Guess at live length of each allocno.
This is actually the max of the live lengths of the regs. */
int live_length;
static HARD_REG_SET regs_used_so_far;
-/* Number of refs (weighted) to each hard reg, as used by local alloc.
+/* Number of refs to each hard reg, as used by local alloc.
It is zero for a reg that contains global pseudos or is explicitly used. */
static int local_reg_n_refs[FIRST_PSEUDO_REGISTER];
+/* Frequency of uses of given hard reg. */
+static int local_reg_freq[FIRST_PSEUDO_REGISTER];
+
/* Guess at live length of each hard reg, as used by local alloc.
This is actually the sum of the live lengths of the specific regs. */
allocno[num].size = PSEUDO_REGNO_SIZE (i);
allocno[num].calls_crossed += REG_N_CALLS_CROSSED (i);
allocno[num].n_refs += REG_N_REFS (i);
+ allocno[num].freq += REG_FREQ (i);
if (allocno[num].live_length < REG_LIVE_LENGTH (i))
allocno[num].live_length = REG_LIVE_LENGTH (i);
}
override it. */
memset ((char *) local_reg_live_length, 0, sizeof local_reg_live_length);
memset ((char *) local_reg_n_refs, 0, sizeof local_reg_n_refs);
+ memset ((char *) local_reg_freq, 0, sizeof local_reg_freq);
for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
if (reg_renumber[i] >= 0)
{
for (j = regno; j < endregno; j++)
{
local_reg_n_refs[j] += REG_N_REFS (i);
+ local_reg_freq[j] += REG_FREQ (i);
local_reg_live_length[j] += REG_LIVE_LENGTH (i);
}
}
/* We can't override local-alloc for a reg used not just by local-alloc. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (regs_ever_live[i])
- local_reg_n_refs[i] = 0;
+ local_reg_n_refs[i] = 0, local_reg_freq[i] = 0;
allocno_row_words = (max_allocno + INT_BITS - 1) / INT_BITS;
times a register can occur in one insn (surely less than 100).
Multiplying this by 10000 can't overflow. */
register int pri1
- = (((double) (floor_log2 (allocno[v1].n_refs) * allocno[v1].n_refs)
+ = (((double) (floor_log2 (allocno[v1].n_refs) * allocno[v1].freq)
/ allocno[v1].live_length)
* 10000 * allocno[v1].size);
register int pri2
- = (((double) (floor_log2 (allocno[v2].n_refs) * allocno[v2].n_refs)
+ = (((double) (floor_log2 (allocno[v2].n_refs) * allocno[v2].freq)
/ allocno[v2].live_length)
* 10000 * allocno[v2].size);
if (pri2 - pri1)
variables so as to avoid excess precision problems that occur
on a i386-unknown-sysv4.2 (unixware) host. */
- double tmp1 = ((double) local_reg_n_refs[regno]
+ double tmp1 = ((double) local_reg_freq[regno]
/ local_reg_live_length[regno]);
- double tmp2 = ((double) allocno[num].n_refs
+ double tmp2 = ((double) allocno[num].freq
/ allocno[num].live_length);
if (tmp1 < tmp2)
SET_HARD_REG_BIT (regs_used_so_far, j);
/* This is no longer a reg used just by local regs. */
local_reg_n_refs[j] = 0;
+ local_reg_freq[j] = 0;
}
/* For each other pseudo-reg conflicting with this one,
mark it as conflicting with the hard regs this one occupies. */
#ifdef L_bb
+#if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
+typedef long gcov_type;
+#else
+typedef long long gcov_type;
+#endif
+
+
/* Structure emitted by -a */
struct bb
{
long zero_word;
const char *filename;
- long *counts;
+ gcov_type *counts;
long ncounts;
struct bb *next;
const unsigned long *addresses;
for (i = 0; i < n_counts; i++)
{
- long v = 0;
+ gcov_type v = 0;
- if (__read_long (&v, da_file, 8) != 0)
+ if (__read_gcov_type (&v, da_file, 8) != 0)
{
fprintf (stderr, "arc profiling: Can't read output file %s.\n",
ptr->filename);
That way we can easily verify that the proper source/executable/
data file combination is being used from gcov. */
- if (__write_long (ptr->ncounts, da_file, 8) != 0)
+ if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0)
{
fprintf (stderr, "arc profiling: Error writing output file %s.\n",
else
{
int j;
- long *count_ptr = ptr->counts;
+ gcov_type *count_ptr = ptr->counts;
int ret = 0;
for (j = ptr->ncounts; j > 0; j--)
{
- if (__write_long (*count_ptr, da_file, 8) != 0)
+ if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
{
ret=1;
break;
int n_refs;
+ /* The frequency of uses of quantity Q. */
+
+ int freq;
+
/* Insn number (counting from head of basic block)
where quantity Q was born. -1 if birth has not been recorded. */
qty[qtyno].min_class = reg_preferred_class (regno);
qty[qtyno].alternate_class = reg_alternate_class (regno);
qty[qtyno].n_refs = REG_N_REFS (regno);
+ qty[qtyno].freq = REG_FREQ (regno);
qty[qtyno].changes_mode = REG_CHANGES_MODE (regno);
}
\f
remove_death (regno, insn);
REG_N_REFS (regno) = 0;
+ REG_FREQ (regno) = 0;
PUT_CODE (equiv_insn, NOTE);
NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (equiv_insn) = 0;
QTY_CMP_PRI is also used by qty_sugg_compare. */
#define QTY_CMP_PRI(q) \
- ((int) (((double) (floor_log2 (qty[q].n_refs) * qty[q].n_refs * qty[q].size) \
+ ((int) (((double) (floor_log2 (qty[q].n_refs) * qty[q].freq * qty[q].size) \
/ (qty[q].death - qty[q].birth)) * 10000))
static int
/* Update info about quantity SQTY. */
qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg);
qty[sqty].n_refs += REG_N_REFS (sreg);
+ qty[sqty].freq += REG_FREQ (sreg);
if (usize < ssize)
{
register int i;
#include "regs.h"
#include "expr.h"
#include "function.h"
-#include "gcov-io.h"
#include "toplev.h"
#include "ggc.h"
#include "hard-reg-set.h"
#include "basic-block.h"
+#include "gcov-io.h"
/* Additional information about the edges we need. */
struct edge_info
struct bb_info
{
unsigned int count_valid : 1;
- int succ_count;
- int pred_count;
+ gcov_type succ_count;
+ gcov_type pred_count;
};
#define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
num_edges++;
if (da_file)
{
- long value;
- __read_long (&value, da_file, 8);
+ gcov_type value;
+ __read_gcov_type (&value, da_file, 8);
e->count = value;
}
else
EDGE_INFO (e)->count_valid = 1;
BB_INFO (bb)->succ_count--;
BB_INFO (e->dest)->pred_count--;
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
+ bb->index, e->dest->index);
+ fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT) e->count);
+ }
}
}
if (rtl_dump_file)
- fprintf (rtl_dump_file, "%d edge counts read\n", num_edges);
+ fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
/* For every block in the file,
- if every exit/entrance edge has a known count, then set the block count
if (bi->succ_count == 0)
{
edge e;
- int total = 0;
+ gcov_type total = 0;
for (e = bb->succ; e; e = e->succ_next)
total += e->count;
else if (bi->pred_count == 0)
{
edge e;
- int total = 0;
+ gcov_type total = 0;
for (e = bb->pred; e; e = e->pred_next)
total += e->count;
if (bi->succ_count == 1)
{
edge e;
- int total = 0;
+ gcov_type total = 0;
/* One of the counts will be invalid, but it is zero,
so adding it in also doesn't hurt. */
if (bi->pred_count == 1)
{
edge e;
- int total = 0;
+ gcov_type total = 0;
/* One of the counts will be invalid, but it is zero,
so adding it in also doesn't hurt. */
basic_block bb = BASIC_BLOCK (i);
edge e;
rtx insn;
- int total;
+ gcov_type total;
rtx note;
total = bb->count;
gen_edge_profiler (edgeno)
int edgeno;
{
- enum machine_mode mode = mode_for_size (LONG_TYPE_SIZE, MODE_INT, 0);
+ enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
rtx mem_ref, tmp;
rtx sequence;
start_sequence ();
tmp = force_reg (Pmode, profiler_label);
- tmp = plus_constant (tmp, LONG_TYPE_SIZE / BITS_PER_UNIT * edgeno);
+ tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
tmp = expand_binop (mode, add_optab, mem_ref, const1_rtx,
char buf[20];
const char *cfnname;
rtx table_address;
- enum machine_mode mode = mode_for_size (LONG_TYPE_SIZE, MODE_INT, 0);
+ enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
int save_flag_inline_functions = flag_inline_functions;
int save_flag_test_coverage = flag_test_coverage;
int save_profile_arc_flag = profile_arc_flag;
/* This makes one more setting of new insns's dest. */
REG_N_SETS (REGNO (recog_data.operand[0]))++;
REG_N_REFS (REGNO (recog_data.operand[0]))++;
+ REG_FREQ (REGNO (recog_data.operand[0])) += loop_cost;
*recog_data.operand_loc[1] = recog_data.operand[0];
REG_N_REFS (REGNO (recog_data.operand[0]))++;
+ REG_FREQ (REGNO (recog_data.operand[0])) += loop_cost;
for (i = recog_data.n_dups - 1; i >= 0; i--)
if (recog_data.dup_num[i] == 1)
{
*recog_data.dup_loc[i] = recog_data.operand[0];
REG_N_REFS (REGNO (recog_data.operand[0]))++;
+ REG_FREQ (REGNO (recog_data.operand[0])) += loop_cost;
}
return PREV_INSN (newinsn);
/* fields set by flow_analysis */
int refs; /* # of times (REG n) is used or set */
+ int freq; /* # estimated frequency (REG n) is used or set */
int deaths; /* # of times (REG n) dies */
int live_length; /* # of instructions (REG n) is live */
int calls_crossed; /* # of calls (REG n) is live across */
extern varray_type reg_n_info;
-/* Indexed by n, gives number of times (REG n) is used or set.
- References within loops may be counted more times. */
+/* Indexed by n, gives number of times (REG n) is used or set. */
#define REG_N_REFS(N) (VARRAY_REG (reg_n_info, N)->refs)
+/* Estimate frequency of references to register N. */
+
+#define REG_FREQ(N) (VARRAY_REG (reg_n_info, N)->freq)
+
/* Indexed by n, gives number of times (REG n) is set.
??? both regscan and flow allocate space for this. We should settle
on just copy. */
count_pseudo (reg)
int reg;
{
- int n_refs = REG_N_REFS (reg);
+ int freq = REG_FREQ (reg);
int r = reg_renumber[reg];
int nregs;
if (r < 0)
abort ();
- spill_add_cost[r] += n_refs;
+ spill_add_cost[r] += freq;
nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
while (nregs-- > 0)
- spill_cost[r + nregs] += n_refs;
+ spill_cost[r + nregs] += freq;
}
/* Calculate the SPILL_COST and SPILL_ADD_COST arrays and determine the
SET_REGNO_REG_SET (&spilled_pseudos, reg);
- spill_add_cost[r] -= REG_N_REFS (reg);
+ spill_add_cost[r] -= REG_FREQ (reg);
while (nregs-- > 0)
- spill_cost[r + nregs] -= REG_N_REFS (reg);
+ spill_cost[r + nregs] -= REG_FREQ (reg);
}
/* Find reload register to use for reload number ORDER. */