/* Branch prediction routines for the GNU compiler.
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
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 2, or (at your option)
any later version.
GCC 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 GCC; 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 "hard-reg-set.h"
#include "basic-block.h"
#include "insn-config.h"
#include "regs.h"
#include "flags.h"
#include "output.h"
#include "function.h"
#include "except.h"
#include "toplev.h"
#include "recog.h"
#include "expr.h"
#include "predict.h"
/* Random guesstimation given names. */
#define PROB_NEVER (0)
#define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 10 - 1)
#define PROB_UNLIKELY (REG_BR_PROB_BASE * 4 / 10 - 1)
#define PROB_EVEN (REG_BR_PROB_BASE / 2)
#define PROB_LIKELY (REG_BR_PROB_BASE - PROB_UNLIKELY)
#define PROB_VERY_LIKELY (REG_BR_PROB_BASE - PROB_VERY_UNLIKELY)
#define PROB_ALWAYS (REG_BR_PROB_BASE)
static void combine_predictions_for_insn PARAMS ((rtx, basic_block));
static void dump_prediction PARAMS ((enum br_predictor, int,
basic_block, int));
static void estimate_loops_at_level PARAMS ((struct loop *loop));
static void propagate_freq PARAMS ((basic_block));
static void estimate_bb_frequencies PARAMS ((struct loops *));
static void counts_to_freqs PARAMS ((void));
/* Information we hold about each branch predictor.
Filled using information from predict.def. */
struct predictor_info
{
const char *const name; /* Name used in the debugging dumps. */
const int hitrate; /* Expected hitrate used by
predict_insn_def call. */
const int flags;
};
/* Use given predictor without Dempster-Shaffer theory if it matches
using first_match heuristics. */
#define PRED_FLAG_FIRST_MATCH 1
/* Recompute hitrate in percent to our representation. */
#define HITRATE(VAL) ((int)((VAL) * REG_BR_PROB_BASE + 50) / 100)
#define DEF_PREDICTOR(ENUM, NAME, HITRATE, FLAGS) {NAME, HITRATE, FLAGS},
static const struct predictor_info predictor_info[] = {
#include "predict.def"
/* Upper bound on predictors. */
{NULL, 0, 0}
};
#undef DEF_PREDICTOR
void
predict_insn (insn, predictor, probability)
rtx insn;
int probability;
enum br_predictor predictor;
{
if (!any_condjump_p (insn))
abort ();
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_BR_PRED,
gen_rtx_CONCAT (VOIDmode,
GEN_INT ((int) predictor),
GEN_INT ((int) probability)),
REG_NOTES (insn));
}
/* Predict insn by given predictor. */
void
predict_insn_def (insn, predictor, taken)
rtx insn;
enum br_predictor predictor;
enum prediction taken;
{
int probability = predictor_info[(int) predictor].hitrate;
if (taken != TAKEN)
probability = REG_BR_PROB_BASE - probability;
predict_insn (insn, predictor, probability);
}
/* Predict edge E with given probability if possible. */
void
predict_edge (e, predictor, probability)
edge e;
int probability;
enum br_predictor predictor;
{
rtx last_insn;
last_insn = e->src->end;
/* We can store the branch prediction information only about
conditional jumps. */
if (!any_condjump_p (last_insn))
return;
|