This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[cfg-branch] hot/cold predicates
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, gcc-pdo at atrey dot karlin dot mff dot cuni dot cz
- Date: Thu, 20 Dec 2001 21:19:13 +0100
- Subject: [cfg-branch] hot/cold predicates
Hi,
this patch adds simple predicates for identifying hot/cold basic
block to avoid using random heuristics over the code.
Honza
Thu Dec 20 21:17:03 CET 2001 Jan Hubicka <jh@suse.cz>
* basic-block.h (maybe_hot_bb_p, probably_cold_bb_p,
probably_never_executed_bb_p): New functions.
* cfgcleanup.c (outgoing_edges_match): Use them.
* predict.c (MIN_COUNT, MIN_FREQUENCY): New macros.
(maybe_hot_bb_p, probably_cold_bb_p,
probably_never_executed_bb_p): New functions.
* tracer.c (ignore_bb_p): Use them.
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.127.2.4
diff -c -3 -p -r1.127.2.4 basic-block.h
*** basic-block.h 2001/12/11 09:42:40 1.127.2.4
--- basic-block.h 2001/12/20 20:12:45
*************** extern rtx emit_block_insn_before PARAMS
*** 625,630 ****
--- 625,633 ----
extern void estimate_probability PARAMS ((struct loops *));
extern void expected_value_to_br_prob PARAMS ((void));
extern void note_prediction_to_br_prob PARAMS ((void));
+ extern bool maybe_hot_bb_p PARAMS ((basic_block));
+ extern bool probably_cold_bb_p PARAMS ((basic_block));
+ extern bool probably_never_executed_bb_p PARAMS ((basic_block));
/* In flow.c */
extern void init_flow PARAMS ((void));
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgcleanup.c,v
retrieving revision 1.18.2.9
diff -c -3 -p -r1.18.2.9 cfgcleanup.c
*** cfgcleanup.c 2001/12/14 23:07:45 1.18.2.9
--- cfgcleanup.c 2001/12/20 20:12:45
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1045,1073 ****
we will only have one branch prediction bit to work with. Thus
we require the existing branches to have probabilities that are
roughly similar. */
! /* ??? We should use bb->frequency to allow merging in infrequently
! executed blocks, but at the moment it is not available when
! cleanup_cfg is run. */
! if (match && !optimize_size)
{
! rtx note1, note2;
! int prob1, prob2;
! note1 = find_reg_note (bb1->end, REG_BR_PROB, 0);
! note2 = find_reg_note (bb2->end, REG_BR_PROB, 0);
! if (note1 && note2)
! {
! prob1 = INTVAL (XEXP (note1, 0));
! prob2 = INTVAL (XEXP (note2, 0));
! if (reverse)
! prob2 = REG_BR_PROB_BASE - prob2;
! /* Fail if the difference in probabilities is
! greater than 5%. */
! if (abs (prob1 - prob2) > REG_BR_PROB_BASE / 20)
! return false;
! }
! else if (note1 || note2)
return false;
}
--- 1045,1065 ----
we will only have one branch prediction bit to work with. Thus
we require the existing branches to have probabilities that are
roughly similar. */
! if (match
! && (!optimize_size
! || !maybe_hot_bb_p (bb1)
! || !maybe_hot_bb_p (bb2)))
{
! int prob2;
! if (b1->dest == b2->dest)
! prob2 = b2->probability;
! else
! prob2 = f2->probability;
! /* Fail if the difference in probabilities is
! greater than 5%. */
! if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 20)
return false;
}
Index: predict.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/predict.c,v
retrieving revision 1.44.2.14
diff -c -3 -p -r1.44.2.14 predict.c
*** predict.c 2001/12/14 23:08:22 1.44.2.14
--- predict.c 2001/12/20 20:12:46
***************
*** 48,53 ****
--- 48,60 ----
#include "expr.h"
#include "predict.h"
+ /* Minimal number of executions of the basic block per execution
+ of program to make it "hot". */
+ #define MIN_COUNT 100
+
+ /* Minimal frequency of the basic block to make it "hot". */
+ #define MIN_FREQUENCY BB_FREQ_MAX/1000
+
/* Random guesstimation given names. */
#define PROB_NEVER (0)
#define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 10 - 1)
*************** static const struct predictor_info predi
*** 99,104 ****
--- 106,148 ----
};
#undef DEF_PREDICTOR
+ /* Return true in case BB can be CPU intensive and should be optimized
+ for maximal perofmrance. */
+
+ bool
+ maybe_hot_bb_p (bb)
+ basic_block bb;
+ {
+ if (flag_branch_probabilities && bb->count < MIN_COUNT)
+ return false;
+ if (bb->frequency < MIN_FREQUENCY)
+ return false;
+ return true;
+ }
+
+ /* Return true in case BB is cold and should be optimized for size. */
+
+ bool
+ probably_cold_bb_p (bb)
+ basic_block bb;
+ {
+ if (flag_branch_probabilities && bb->count < MIN_COUNT)
+ return true;
+ if (bb->frequency < MIN_FREQUENCY)
+ return true;
+ return false;
+ }
+
+ /* Return true in case BB is probably never executed. */
+ bool
+ probably_never_executed_bb_p (bb)
+ basic_block bb;
+ {
+ if (flag_branch_probabilities)
+ return bb->count == 0;
+ return false;
+ }
+
/* Return true if the one of outgoing edges is already predicted by
PREDICTOR. */
*************** predicted_by_p (bb, predictor)
*** 112,118 ****
return false;
for (note = REG_NOTES (bb->end); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_BR_PRED
! && INTVAL (XEXP (XEXP (note, 0), 0)) == predictor)
return true;
return false;
}
--- 156,162 ----
return false;
for (note = REG_NOTES (bb->end); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_BR_PRED
! && INTVAL (XEXP (XEXP (note, 0), 0)) == (int)predictor)
return true;
return false;
}
Index: tracer.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Attic/tracer.c,v
retrieving revision 1.1.2.14
diff -c -3 -p -r1.1.2.14 tracer.c
*** tracer.c 2001/12/12 15:21:53 1.1.2.14
--- tracer.c 2001/12/20 20:12:47
*************** static bool ignore_bb_p PARAMS ((basic
*** 93,104 ****
static bool
ignore_bb_p (basic_block bb)
{
- if (flag_branch_probabilities && bb->count < MIN_COUNT)
- return true;
- if (bb->frequency < MIN_FREQUENCY)
- return true;
- /* Rule out entry and exit blocks. */
if (bb->index < 0)
return true;
return false;
}
--- 93,101 ----
static bool
ignore_bb_p (basic_block bb)
{
if (bb->index < 0)
+ return true;
+ if (!maybe_hot_bb_p (bb))
return true;
return false;
}