predict.c: New file.

Thu Jan 13 14:46:03 2000  Jason Eckhardt  <jle@cygnus.com>
                          Stan Cox  <scox@cygnus.com>

	* predict.c: New file. Preliminary infrastructure work for static
	branch prediction and basic block reordering.
	* basic-block.h: Add prototype for estimate_probability.
	* Makefile.in: Add rules for predict.o.

Co-Authored-By: Stan Cox <scox@cygnus.com>

From-SVN: r31402
This commit is contained in:
Jason Eckhardt 2000-01-14 02:01:21 +00:00 committed by Jason Eckhardt
parent 91baa91841
commit f1ebdfc52a
4 changed files with 158 additions and 1 deletions

View File

@ -1,3 +1,11 @@
Thu Jan 13 14:46:03 2000 Jason Eckhardt <jle@cygnus.com>
Stan Cox <scox@cygnus.com>
* predict.c: New file. Preliminary infrastructure work for static
branch prediction and basic block reordering.
* basic-block.h: Add prototype for estimate_probability.
* Makefile.in: Add rules for predict.o.
2000-01-13 Jason Merrill <jason@yorick.cygnus.com>
* fixincludes (va_list): Use __not_va_list__ for the dummy.

View File

@ -673,7 +673,7 @@ OBJS = diagnostic.o \
insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \
profile.o insn-attrtab.o $(out_object_file) $(EXTRA_OBJS) convert.o \
mbchar.o dyn-string.o splay-tree.o graph.o sbitmap.o resource.o hash.o \
lists.o ggc-common.o $(GGC) simplify-rtx.o
predict.o lists.o ggc-common.o $(GGC) simplify-rtx.o
# GEN files are listed separately, so they can be built before doing parallel
# makes for cc1 or cc1plus. Otherwise sequent parallel make attempts to load
@ -1620,6 +1620,9 @@ reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) $(RECOG_H) \
$(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
varray.h function.h
dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h
predict.o: predict.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) insn-flags.h function.h except.h expr.h
lists.o: lists.c $(CONFIG_H) system.h toplev.h $(RTL_H) ggc.h
$(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) ggc.h \

View File

@ -384,4 +384,7 @@ extern void compute_available PARAMS ((sbitmap *, sbitmap *,
extern rtx emit_block_insn_after PARAMS ((rtx, rtx, basic_block));
extern rtx emit_block_insn_before PARAMS ((rtx, rtx, basic_block));
/* In predict.c */
extern void estimate_probability PARAMS ((struct loops *));
#endif /* _BASIC_BLOCK_H */

143
gcc/predict.c Normal file
View File

@ -0,0 +1,143 @@
/* Branch prediction routines for the GNU compiler.
Copyright (C) 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* References:
[1] "Branch Prediction for Free"
Ball and Larus; PLDI '93.
[2] "Static Branch Frequency and Program Profile Analysis"
Wu and Larus; MICRO-27.
[3] "Corpus-based Static Branch Prediction"
Calder, Grunwald, Lindsay, Martin, Mozer, and Zorn; PLDI '95.
*/
#include "config.h"
#include "system.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "basic-block.h"
#include "insn-config.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "output.h"
#include "function.h"
#include "except.h"
#include "toplev.h"
#include "recog.h"
#include "insn-flags.h"
#include "expr.h"
/* Statically estimate the probability that a branch will be taken.
??? In the next revision there will be a number of other predictors added
from the above references. Further, each heuristic will be factored out
into its own function for clarity (and to facilitate the combination of
predictions). */
void
estimate_probability (loops_info)
struct loops *loops_info;
{
int i;
/* Try to predict out blocks in a loop that are not part of a natural loop */
for (i = 0; i < loops_info->num; i++)
{
int j;
for (j = loops_info->array[i].header->index;
j <= loops_info->array[i].latch->index;
++j)
{
edge e;
if (! TEST_BIT (loops_info->array[i].nodes, j))
for (e = BASIC_BLOCK(j)->pred; e; e = e->pred_next)
if (TEST_BIT (loops_info->array[i].nodes, e->src->index))
{
rtx last_insn = BLOCK_END (e->src->index);
rtx cond, earliest;
if (GET_CODE (last_insn) != JUMP_INSN
|| ! condjump_p (last_insn) || simplejump_p (last_insn))
continue;
cond = get_condition (last_insn, &earliest);
if (!cond)
continue;
if (! find_reg_note (last_insn, REG_BR_PROB, 0))
REG_NOTES (last_insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE),
REG_NOTES (last_insn));
}
}
}
/* Try to predict condjumps using same algorithm as mostly_true_jump */
for (i = 0; i < n_basic_blocks - 1; i++)
{
rtx last_insn = BLOCK_END (i);
rtx cond, earliest;
int prob = 0;
if (GET_CODE (last_insn) != JUMP_INSN
|| ! condjump_p (last_insn) || simplejump_p (last_insn))
continue;
cond = get_condition (last_insn, &earliest);
if (! cond)
continue;
/* EQ tests are usually false and NE tests are usually true. Also,
most quantities are positive, so we can make the appropriate guesses
about signed comparisons against zero. */
switch (GET_CODE (cond))
{
case CONST_INT:
/* Unconditional branch. */
prob = REG_BR_PROB_BASE / 2;
case EQ:
prob = REG_BR_PROB_BASE / 10;
case NE:
prob = REG_BR_PROB_BASE / 2;
case LE:
case LT:
if (XEXP (cond, 1) == const0_rtx)
prob = REG_BR_PROB_BASE / 10;
break;
case GE:
case GT:
if (XEXP (cond, 1) == const0_rtx
|| (GET_CODE (XEXP (cond, 1)) == CONST_INT
&& INTVAL (XEXP (cond, 1)) == -1))
prob = REG_BR_PROB_BASE / 2;
break;
default:
prob = 0;
}
if (! find_reg_note (last_insn, REG_BR_PROB, 0))
REG_NOTES (last_insn)
= gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
REG_NOTES (last_insn));
}
}