This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[cfg-branch]
- 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: Tue, 27 Nov 2001 01:09:51 +0100
- Subject: [cfg-branch]
Hi,
I've installed the attached patch that hopes to improve the opcode heuristics.
Honza
Hi,
this is updated patch to refine opcode heuristic. I believe that the low
overall coverage of opcode heuristic is caused by fact, that we mix
too many different things together. For instance test whether FP values
are unordered should be much better predictable than test whether integer
is 0, as such test is often used in boolean expression.
For this putpose I split OPCODE heurostic to OPCODE_POSITIVE - declaring that
values should be positive (this is usually strong one), OPCODE_NONZERO -
declaring that values usually does not equal zero (very weak one - perhaps we
may want to drop it, but I would like to see overall results first),
OPCODE_NONEQUAL - declaring that two values are usually not equal in case
neighter of them is 0 (it is unlikely value to be 42, while more likely to be
0). In the past I was also experimenting with OPCODE_NONONE doing the
same as NONZERO, but given the usual C coding style, boolean expressions
are not test agains 1.
The patch also refines the pointer heuristic to match even when only one of
operands is known to be pointer - this is important in case the pointer
is compared to constant, that is load to temporary register, as that register
don't have pointer flag anymore.
As a next step I would like to move opcode and pointer heuristics after first
CSE pass, as the insn chain is more similar to what programmer really wanted.
Sat Aug 25 14:55:23 CEST 2001 Jan Hubicka <jh@suse.cz>
* predict.c (estimate_probability): Refine pointer heuristic;
split opcode into multiple heuristics.
* predict.def (PRED_OPCODE_POSITIVE, PRED_OPCODE_NONZERO,
PRED_OPCODE_NONEQUAL, PRED_FPOPCODE): New.
Index: predict.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/predict.c,v
retrieving revision 1.38
diff -c -3 -p -r1.38 predict.c
*** predict.c 2001/08/22 14:35:31 1.38
--- predict.c 2001/08/25 12:38:32
*************** estimate_probability (loops_info)
*** 435,508 ****
/* Try "pointer heuristic."
A comparison ptr == 0 is predicted as false.
Similarly, a comparison ptr1 == ptr2 is predicted as false. */
! switch (GET_CODE (cond))
! {
! case EQ:
! if (GET_CODE (XEXP (cond, 0)) == REG
! && REG_POINTER (XEXP (cond, 0))
! && (XEXP (cond, 1) == const0_rtx
! || (GET_CODE (XEXP (cond, 1)) == REG
! && REG_POINTER (XEXP (cond, 1)))))
!
predict_insn_def (last_insn, PRED_POINTER, NOT_TAKEN);
! break;
! case NE:
! if (GET_CODE (XEXP (cond, 0)) == REG
! && REG_POINTER (XEXP (cond, 0))
! && (XEXP (cond, 1) == const0_rtx
! || (GET_CODE (XEXP (cond, 1)) == REG
! && REG_POINTER (XEXP (cond, 1)))))
predict_insn_def (last_insn, PRED_POINTER, TAKEN);
! break;
!
! default:
! break;
! }
!
/* Try "opcode heuristic."
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. */
! predict_insn_def (last_insn, PRED_UNCONDITIONAL,
! cond == const0_rtx ? NOT_TAKEN : TAKEN);
! break;
! case EQ:
! case UNEQ:
! predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
! break;
! case NE:
! case LTGT:
! predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
! break;
! case ORDERED:
! predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
! break;
! case UNORDERED:
! predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
! break;
! case LE:
! case LT:
! if (XEXP (cond, 1) == const0_rtx
! || (GET_CODE (XEXP (cond, 1)) == CONST_INT
! && INTVAL (XEXP (cond, 1)) == -1))
! predict_insn_def (last_insn, PRED_OPCODE, NOT_TAKEN);
! break;
! case GE:
! case GT:
! if (XEXP (cond, 1) == const0_rtx
! || (GET_CODE (XEXP (cond, 1)) == CONST_INT
! && INTVAL (XEXP (cond, 1)) == -1))
! predict_insn_def (last_insn, PRED_OPCODE, TAKEN);
! break;
! default:
! break;
! }
}
/* Attach the combined probability to each conditional jump. */
--- 435,507 ----
/* Try "pointer heuristic."
A comparison ptr == 0 is predicted as false.
Similarly, a comparison ptr1 == ptr2 is predicted as false. */
! if (GET_RTX_CLASS (GET_CODE (cond)) == '<'
! && ((REG_P (XEXP (cond, 0)) && REG_POINTER (XEXP (cond, 0)))
! || (REG_P (XEXP (cond, 1)) && REG_POINTER (XEXP (cond, 1)))))
! switch (GET_CODE (cond))
! {
! case EQ:
predict_insn_def (last_insn, PRED_POINTER, NOT_TAKEN);
! break;
! case NE:
predict_insn_def (last_insn, PRED_POINTER, TAKEN);
! break;
! default:
! break;
! }
! else
/* Try "opcode heuristic."
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. */
! predict_insn_def (last_insn, PRED_UNCONDITIONAL,
! cond == const0_rtx ? NOT_TAKEN : TAKEN);
! break;
! case EQ:
! case UNEQ:
! if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
! predict_insn_def (last_insn, PRED_FPOPCODE, NOT_TAKEN);
! else if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 0) == const0_rtx)
! predict_insn_def (last_insn, PRED_OPCODE_NONZERO, NOT_TAKEN);
! else
! predict_insn_def (last_insn, PRED_OPCODE_NONEQUAL, NOT_TAKEN);
! break;
! case NE:
! case LTGT:
! if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
! predict_insn_def (last_insn, PRED_FPOPCODE, TAKEN);
! else if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 0) == const0_rtx)
! predict_insn_def (last_insn, PRED_OPCODE_NONZERO, TAKEN);
! else
! predict_insn_def (last_insn, PRED_OPCODE_NONEQUAL, TAKEN);
! break;
! case ORDERED:
! predict_insn_def (last_insn, PRED_FPOPCODE, TAKEN);
! break;
! case UNORDERED:
! predict_insn_def (last_insn, PRED_FPOPCODE, NOT_TAKEN);
! break;
! case LE:
! case LT:
! if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 1) == const1_rtx
! || XEXP (cond, 1) == constm1_rtx)
! predict_insn_def (last_insn, PRED_OPCODE_POSITIVE, NOT_TAKEN);
! break;
! case GE:
! case GT:
! if (XEXP (cond, 1) == const0_rtx || XEXP (cond, 1) == const1_rtx
! || XEXP (cond, 1) == constm1_rtx)
! predict_insn_def (last_insn, PRED_OPCODE_POSITIVE, TAKEN);
! break;
! default:
! break;
! }
}
/* Attach the combined probability to each conditional jump. */
Index: predict.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/predict.def,v
retrieving revision 1.11
diff -c -3 -p -r1.11 predict.def
*** predict.def 2001/08/22 14:35:31 1.11
--- predict.def 2001/08/25 12:38:32
*************** DEF_PREDICTOR (PRED_LOOP_HEADER, "loop h
*** 89,95 ****
DEF_PREDICTOR (PRED_POINTER, "pointer", HITRATE (83), 0)
/* NE is probable, EQ not etc... */
! DEF_PREDICTOR (PRED_OPCODE, "opcode", HITRATE (55), 0)
/* Branch guarding call is probably taken. */
DEF_PREDICTOR (PRED_CALL, "call", HITRATE (70), 0)
--- 89,98 ----
DEF_PREDICTOR (PRED_POINTER, "pointer", HITRATE (83), 0)
/* NE is probable, EQ not etc... */
! DEF_PREDICTOR (PRED_OPCODE_POSITIVE, "opcode values positive", HITRATE (71), 0)
! DEF_PREDICTOR (PRED_OPCODE_NONZERO, "opcode values nonzero", HITRATE (52), 0)
! DEF_PREDICTOR (PRED_OPCODE_NONEQUAL, "opcode values nonequal", HITRATE (62), 0)
! DEF_PREDICTOR (PRED_FPOPCODE, "fp_opcode", HITRATE (90), 0)
/* Branch guarding call is probably taken. */
DEF_PREDICTOR (PRED_CALL, "call", HITRATE (70), 0)