* [PATCH 0/2] Deduplicate edge predictors
@ 2016-06-02 11:57 marxin
2016-06-02 11:57 ` [PATCH 1/2] Introduce filtering for edge_predictions marxin
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: marxin @ 2016-06-02 11:57 UTC (permalink / raw)
To: gcc-patches; +Cc: hubicka
Hi.
Following small series makes deduplication of predictors in following 2 ways:
1) remove duplicate prediction that is guessed with the same probability
(different than 1/2) to both edges
2) remove duplicates for a prediction that belongs with the same probability
to a single edge
Patch also changes dump output format a bit, thus analyze_brprob.py script
has been also modified to understand the format.
Bootstrapped and regtested on x86_64-linux
Ready for trunk?
Martin
marxin (2):
Introduce filtering for edge_predictions.
Add edge predictions pruning
contrib/analyze_brprob.py | 10 +-
gcc/predict.c | 209 +++++++++++++++++++++++++----
gcc/testsuite/g++.dg/predict-loop-exit-1.C | 4 +-
gcc/testsuite/g++.dg/predict-loop-exit-2.C | 4 +-
gcc/testsuite/g++.dg/predict-loop-exit-3.C | 4 +-
gcc/testsuite/gcc.dg/predict-1.c | 2 +-
gcc/testsuite/gcc.dg/predict-3.c | 2 +-
gcc/testsuite/gcc.dg/predict-4.c | 2 +-
gcc/testsuite/gcc.dg/predict-5.c | 2 +-
gcc/testsuite/gcc.dg/predict-6.c | 2 +-
10 files changed, 201 insertions(+), 40 deletions(-)
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] Introduce filtering for edge_predictions.
2016-06-02 11:57 [PATCH 0/2] Deduplicate edge predictors marxin
@ 2016-06-02 11:57 ` marxin
2016-06-02 11:57 ` [PATCH 2/2] Add edge predictions pruning marxin
` (2 subsequent siblings)
3 siblings, 0 replies; 14+ messages in thread
From: marxin @ 2016-06-02 11:57 UTC (permalink / raw)
To: gcc-patches; +Cc: hubicka
gcc/ChangeLog:
2016-05-31 Martin Liska <mliska@suse.cz>
* predict.c (filter_predictions): New function.
(remove_predictions_associated_with_edge): Use the filter
function.
(equal_edge_p): New function.
---
gcc/predict.c | 38 ++++++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/gcc/predict.c b/gcc/predict.c
index e9dda20..51a9993 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -609,16 +609,16 @@ gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
}
}
-/* Remove all predictions on given basic block that are attached
- to edge E. */
+/* Filter edge predictions PREDS by a function FILTER. DATA are passed
+ to the filter function. */
+
void
-remove_predictions_associated_with_edge (edge e)
+filter_predictions (edge_prediction **preds,
+ bool (*filter) (edge_prediction *, void *), void *data)
{
if (!bb_predictions)
return;
- edge_prediction **preds = bb_predictions->get (e->src);
-
if (preds)
{
struct edge_prediction **prediction = preds;
@@ -626,18 +626,40 @@ remove_predictions_associated_with_edge (edge e)
while (*prediction)
{
- if ((*prediction)->ep_edge == e)
+ if ((*filter) (*prediction, data))
+ prediction = &((*prediction)->ep_next);
+ else
{
next = (*prediction)->ep_next;
free (*prediction);
*prediction = next;
}
- else
- prediction = &((*prediction)->ep_next);
}
}
}
+/* Filter function predicate that returns true for a edge predicate P
+ if its edge is equal to DATA. */
+
+bool
+equal_edge_p (edge_prediction *p, void *data)
+{
+ return p->ep_edge == (edge)data;
+}
+
+/* Remove all predictions on given basic block that are attached
+ to edge E. */
+
+void
+remove_predictions_associated_with_edge (edge e)
+{
+ if (!bb_predictions)
+ return;
+
+ edge_prediction **preds = bb_predictions->get (e->src);
+ filter_predictions (preds, equal_edge_p, e);
+}
+
/* Clears the list of predictions stored for BB. */
static void
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/2] Add edge predictions pruning
2016-06-02 11:57 [PATCH 0/2] Deduplicate edge predictors marxin
2016-06-02 11:57 ` [PATCH 1/2] Introduce filtering for edge_predictions marxin
@ 2016-06-02 11:57 ` marxin
2016-06-08 12:25 ` Martin Liška
2016-06-08 12:26 ` [PATCH 3/N] Add sorting support to analyze_brprob script Martin Liška
2016-06-08 12:29 ` [PATCH 4/N] Add new analyze_brprob_spec.py script Martin Liška
3 siblings, 1 reply; 14+ messages in thread
From: marxin @ 2016-06-02 11:57 UTC (permalink / raw)
To: gcc-patches; +Cc: hubicka
contrib/ChangeLog:
2016-06-01 Martin Liska <mliska@suse.cz>
* analyze_brprob.py: Cover new dump output format.
gcc/ChangeLog:
2016-06-01 Martin Liska <mliska@suse.cz>
* predict.c (dump_prediction): Add new argument.
(enum predictor_reason): New enum.
(struct predictor_hash): New struct.
(predictor_hash::hash): New function.
(predictor_hash::equal): Likewise.
(not_removed_prediction_p): New function.
(prune_predictions_for_bb): Likewise.
(combine_predictions_for_bb): Prune predictions.
gcc/testsuite/ChangeLog:
2016-06-02 Martin Liska <mliska@suse.cz>
* g++.dg/predict-loop-exit-1.C: Cover new dump format.
* g++.dg/predict-loop-exit-2.C: Likewise.
* g++.dg/predict-loop-exit-3.C: Likewise.
* gcc.dg/predict-1.c: Likewise.
* gcc.dg/predict-3.c: Likewise.
* gcc.dg/predict-4.c: Likewise.
* gcc.dg/predict-5.c: Likewise.
* gcc.dg/predict-6.c: Likewise.
---
contrib/analyze_brprob.py | 10 +-
gcc/predict.c | 171 ++++++++++++++++++++++++++---
gcc/testsuite/g++.dg/predict-loop-exit-1.C | 4 +-
gcc/testsuite/g++.dg/predict-loop-exit-2.C | 4 +-
gcc/testsuite/g++.dg/predict-loop-exit-3.C | 4 +-
gcc/testsuite/gcc.dg/predict-1.c | 2 +-
gcc/testsuite/gcc.dg/predict-3.c | 2 +-
gcc/testsuite/gcc.dg/predict-4.c | 2 +-
gcc/testsuite/gcc.dg/predict-5.c | 2 +-
gcc/testsuite/gcc.dg/predict-6.c | 2 +-
10 files changed, 171 insertions(+), 32 deletions(-)
diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
index 36371ff..9416eed 100755
--- a/contrib/analyze_brprob.py
+++ b/contrib/analyze_brprob.py
@@ -122,14 +122,14 @@ if len(sys.argv) != 2:
exit(1)
profile = Profile(sys.argv[1])
-r = re.compile(' (.*) heuristics: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
+r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
for l in open(profile.filename).readlines():
m = r.match(l)
- if m != None:
+ if m != None and m.group(3) == None:
name = m.group(1)
- prediction = float(m.group(2))
- count = int(m.group(3))
- hits = int(m.group(4))
+ prediction = float(m.group(4))
+ count = int(m.group(5))
+ hits = int(m.group(6))
profile.add(name, prediction, count, hits)
diff --git a/gcc/predict.c b/gcc/predict.c
index 51a9993..dab97ad 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -55,13 +55,25 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
+enum predictor_reason
+{
+ NONE,
+ IGNORED,
+ SINGLE_EDGE_DUPLICATE,
+ EDGE_PAIR_DUPLICATE
+};
+
+static const char *reason_messages[] = {"", " (ignored)",
+ " (single edge duplicate)", " (edge pair duplicate)"};
+
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
static sreal real_almost_one, real_br_prob_base,
real_inv_br_prob_base, real_one_half, real_bb_freq_max;
static void combine_predictions_for_insn (rtx_insn *, basic_block);
-static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
+static void dump_prediction (FILE *, enum br_predictor, int, basic_block,
+ enum predictor_reason, edge);
static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction);
static void predict_paths_leading_to_edge (edge, enum br_predictor, enum prediction);
static bool can_predict_insn_p (const rtx_insn *);
@@ -724,7 +736,8 @@ invert_br_probabilities (rtx insn)
static void
dump_prediction (FILE *file, enum br_predictor predictor, int probability,
- basic_block bb, int used)
+ basic_block bb, enum predictor_reason reason = NONE,
+ edge ep_edge = NULL)
{
edge e;
edge_iterator ei;
@@ -736,9 +749,17 @@ dump_prediction (FILE *file, enum br_predictor predictor, int probability,
if (! (e->flags & EDGE_FALLTHRU))
break;
- fprintf (file, " %s heuristics%s: %.1f%%",
+ char edge_info_str[128];
+ if (ep_edge)
+ sprintf (edge_info_str, " of edge %d->%d", ep_edge->src->index,
+ ep_edge->dest->index);
+ else
+ edge_info_str[0] = '\0';
+
+ fprintf (file, " %s heuristics%s%s: %.1f%%",
predictor_info[predictor].name,
- used ? "" : " (ignored)", probability * 100.0 / REG_BR_PROB_BASE);
+ edge_info_str, reason_messages[reason],
+ probability * 100.0 / REG_BR_PROB_BASE);
if (bb->count)
{
@@ -835,18 +856,18 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
if (!found)
dump_prediction (dump_file, PRED_NO_PREDICTION,
- combined_probability, bb, true);
+ combined_probability, bb);
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability,
- bb, !first_match);
+ bb, !first_match ? NONE : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability,
- bb, first_match);
+ bb, first_match ? NONE: IGNORED);
}
if (first_match)
combined_probability = best_probability;
- dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
while (*pnote)
{
@@ -857,7 +878,8 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
int probability = INTVAL (XEXP (XEXP (*pnote, 0), 1));
dump_prediction (dump_file, predictor, probability, bb,
- !first_match || best_predictor == predictor);
+ (!first_match || best_predictor == predictor)
+ ? NONE : IGNORED);
*pnote = XEXP (*pnote, 1);
}
else
@@ -888,6 +910,121 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
single_succ_edge (bb)->probability = REG_BR_PROB_BASE;
}
+/* Edge prediction hash traits. */
+
+struct predictor_hash: pointer_hash <edge_prediction>
+{
+
+ static inline hashval_t hash (const edge_prediction *);
+ static inline bool equal (const edge_prediction *, const edge_prediction *);
+};
+
+/* Calculate hash value of an edge prediction P based on predictor and
+ normalized probability. */
+
+inline hashval_t
+predictor_hash::hash (const edge_prediction *p)
+{
+ inchash::hash hstate;
+ hstate.add_int (p->ep_predictor);
+
+ int prob = p->ep_probability;
+ if (prob > REG_BR_PROB_BASE / 2)
+ prob = REG_BR_PROB_BASE - prob;
+
+ hstate.add_int (prob);
+
+ return hstate.end ();
+}
+
+/* Return true whether edge predictions P1 and P2 use the same predictor and
+ have equal (or opposed probability). */
+
+inline bool
+predictor_hash::equal (const edge_prediction *p1, const edge_prediction *p2)
+{
+ return (p1->ep_predictor == p2->ep_predictor
+ && (p1->ep_probability == p2->ep_probability
+ || p1->ep_probability == REG_BR_PROB_BASE - p2->ep_probability));
+}
+
+struct predictor_hash_traits: predictor_hash,
+ typed_noop_remove <edge_prediction *> {};
+
+/* Return true if edge prediction P is not in DATA hash set. */
+
+static bool
+not_removed_prediction_p (edge_prediction *p, void *data)
+{
+ hash_set<edge_prediction *> *remove = (hash_set<edge_prediction *> *) data;
+ return !remove->contains (p);
+}
+
+/* Prune predictions for a basic block BB. Currently we do following
+ clean-up steps:
+
+ 1) remove duplicate prediction that is guessed with the same probability
+ (different than 1/2) to both edge
+ 2) remove duplicates for a prediction that belongs with the same probability
+ to a single edge
+
+ */
+
+static void
+prune_predictions_for_bb (basic_block bb)
+{
+ edge_prediction **preds = bb_predictions->get (bb);
+
+ if (preds)
+ {
+ hash_table <predictor_hash_traits> s (13);
+ hash_set <edge_prediction *> remove;
+
+ /* Step 1: identify predictors that should be removed. */
+ for (edge_prediction *pred = *preds; pred; pred = pred->ep_next)
+ {
+ edge_prediction *existing = s.find (pred);
+ if (existing)
+ {
+ if (pred->ep_edge == existing->ep_edge
+ && pred->ep_probability == existing->ep_probability)
+ {
+ /* Remove a duplicate predictor. */
+ dump_prediction (dump_file, pred->ep_predictor,
+ pred->ep_probability, bb,
+ SINGLE_EDGE_DUPLICATE, pred->ep_edge);
+
+ remove.add (pred);
+ }
+ else if (pred->ep_edge != existing->ep_edge
+ && pred->ep_probability == existing->ep_probability
+ && pred->ep_probability != REG_BR_PROB_BASE / 2)
+ {
+ /* Remove both predictors as they predict the same
+ for both edges. */
+ dump_prediction (dump_file, existing->ep_predictor,
+ pred->ep_probability, bb,
+ EDGE_PAIR_DUPLICATE,
+ existing->ep_edge);
+ dump_prediction (dump_file, pred->ep_predictor,
+ pred->ep_probability, bb,
+ EDGE_PAIR_DUPLICATE,
+ pred->ep_edge);
+
+ remove.add (existing);
+ remove.add (pred);
+ }
+ }
+
+ edge_prediction **slot2 = s.find_slot (pred, INSERT);
+ *slot2 = pred;
+ }
+
+ /* Step 2: Remove predictors. */
+ filter_predictions (preds, not_removed_prediction_p, &remove);
+ }
+}
+
/* Combine predictions into single probability and store them into CFG.
Remove now useless prediction entries.
If DRY_RUN is set, only produce dumps and do not modify profile. */
@@ -936,7 +1073,10 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
if (dump_file)
fprintf (dump_file, "Predictions for bb %i\n", bb->index);
+ prune_predictions_for_bb (bb);
+
edge_prediction **preds = bb_predictions->get (bb);
+
if (preds)
{
/* We implement "first match" heuristics and use probability guessed
@@ -1002,18 +1142,18 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
first_match = true;
if (!found)
- dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb);
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability, bb,
- !first_match);
+ !first_match ? NONE : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability, bb,
- first_match);
+ first_match ? NONE : IGNORED);
}
if (first_match)
combined_probability = best_probability;
- dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
if (preds)
{
@@ -1022,10 +1162,9 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
enum br_predictor predictor = pred->ep_predictor;
int probability = pred->ep_probability;
- if (pred->ep_edge != EDGE_SUCC (bb, 0))
- probability = REG_BR_PROB_BASE - probability;
dump_prediction (dump_file, predictor, probability, bb,
- !first_match || best_predictor == predictor);
+ (!first_match || best_predictor == predictor)
+ ? NONE : IGNORED, pred->ep_edge);
}
}
clear_bb_predictions (bb);
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-1.C b/gcc/testsuite/g++.dg/predict-loop-exit-1.C
index 357397f..88262eb 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-1.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-1.C
@@ -9,5 +9,5 @@ void test() {
return;
}
-/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 2 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 3 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 3 "profile_estimate"} } */
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-2.C b/gcc/testsuite/g++.dg/predict-loop-exit-2.C
index 172fab1..15e9866 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-2.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-2.C
@@ -9,5 +9,5 @@ void test() {
return;
}
-/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 1 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 2 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 1 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-3.C b/gcc/testsuite/g++.dg/predict-loop-exit-3.C
index e6ceec8..61af84b 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-3.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-3.C
@@ -9,5 +9,5 @@ void test() {
return;
}
-/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 2 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 3 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 3 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-1.c b/gcc/testsuite/gcc.dg/predict-1.c
index a2a0604..852ccb1 100644
--- a/gcc/testsuite/gcc.dg/predict-1.c
+++ b/gcc/testsuite/gcc.dg/predict-1.c
@@ -23,4 +23,4 @@ void foo (int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 0.0%" 5 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*: 0.0%" 5 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-3.c b/gcc/testsuite/gcc.dg/predict-3.c
index e1be7cc..d41a4ac 100644
--- a/gcc/testsuite/gcc.dg/predict-3.c
+++ b/gcc/testsuite/gcc.dg/predict-3.c
@@ -25,4 +25,4 @@ void foo (int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 100.0%" 3 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*: 100.0%" 3 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-4.c b/gcc/testsuite/gcc.dg/predict-4.c
index 3e7fb74..5779da3 100644
--- a/gcc/testsuite/gcc.dg/predict-4.c
+++ b/gcc/testsuite/gcc.dg/predict-4.c
@@ -15,4 +15,4 @@ void foo (int bound)
}
}
-/* { dg-final { scan-tree-dump "loop iv compare heuristics: 50.0%" "profile_estimate"} } */
+/* { dg-final { scan-tree-dump "loop iv compare heuristics of edge\[^:\]*: 50.0%" "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-5.c b/gcc/testsuite/gcc.dg/predict-5.c
index 3e7cc6f..d9bc27e 100644
--- a/gcc/testsuite/gcc.dg/predict-5.c
+++ b/gcc/testsuite/gcc.dg/predict-5.c
@@ -21,4 +21,4 @@ void foo (int base, int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 100.0%" 4 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*: 100.0%" 4 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-6.c b/gcc/testsuite/gcc.dg/predict-6.c
index cda30e2..608eb7b 100644
--- a/gcc/testsuite/gcc.dg/predict-6.c
+++ b/gcc/testsuite/gcc.dg/predict-6.c
@@ -21,4 +21,4 @@ void foo (int base, int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 0.0%" 4 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*: 0.0%" 4 "profile_estimate"} } */
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] Add edge predictions pruning
2016-06-02 11:57 ` [PATCH 2/2] Add edge predictions pruning marxin
@ 2016-06-08 12:25 ` Martin Liška
2016-06-08 12:41 ` Jan Hubicka
0 siblings, 1 reply; 14+ messages in thread
From: Martin Liška @ 2016-06-08 12:25 UTC (permalink / raw)
To: gcc-patches; +Cc: Jan Hubicka
[-- Attachment #1: Type: text/plain, Size: 124 bytes --]
Hi.
I'm sending second version of the patch, where I fixed dump_prediction function to
dump a proper edge.
Thanks,
Martin
[-- Attachment #2: 0002-Add-edge-predictions-pruning-v2.patch --]
[-- Type: text/x-patch, Size: 10526 bytes --]
From 0d82e8def140636fe186888a525fe84e329d676b Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 31 May 2016 17:29:53 +0200
Subject: [PATCH 2/4] Add edge predictions pruning
contrib/ChangeLog:
2016-06-01 Martin Liska <mliska@suse.cz>
* analyze_brprob.py: Cover new dump output format.
gcc/ChangeLog:
2016-06-01 Martin Liska <mliska@suse.cz>
* predict.c (dump_prediction): Add new argument.
(enum predictor_reason): New enum.
(struct predictor_hash): New struct.
(predictor_hash::hash): New function.
(predictor_hash::equal): Likewise.
(not_removed_prediction_p): New function.
(prune_predictions_for_bb): Likewise.
(combine_predictions_for_bb): Prune predictions.
---
contrib/analyze_brprob.py | 10 +--
gcc/predict.c | 180 ++++++++++++++++++++++++++++++++++++++++------
2 files changed, 165 insertions(+), 25 deletions(-)
diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
index 36371ff..9416eed 100755
--- a/contrib/analyze_brprob.py
+++ b/contrib/analyze_brprob.py
@@ -122,14 +122,14 @@ if len(sys.argv) != 2:
exit(1)
profile = Profile(sys.argv[1])
-r = re.compile(' (.*) heuristics: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
+r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
for l in open(profile.filename).readlines():
m = r.match(l)
- if m != None:
+ if m != None and m.group(3) == None:
name = m.group(1)
- prediction = float(m.group(2))
- count = int(m.group(3))
- hits = int(m.group(4))
+ prediction = float(m.group(4))
+ count = int(m.group(5))
+ hits = int(m.group(6))
profile.add(name, prediction, count, hits)
diff --git a/gcc/predict.c b/gcc/predict.c
index e058793..f2ecc4a 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -55,13 +55,25 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
+enum predictor_reason
+{
+ NONE,
+ IGNORED,
+ SINGLE_EDGE_DUPLICATE,
+ EDGE_PAIR_DUPLICATE
+};
+
+static const char *reason_messages[] = {"", " (ignored)",
+ " (single edge duplicate)", " (edge pair duplicate)"};
+
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
static sreal real_almost_one, real_br_prob_base,
real_inv_br_prob_base, real_one_half, real_bb_freq_max;
static void combine_predictions_for_insn (rtx_insn *, basic_block);
-static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
+static void dump_prediction (FILE *, enum br_predictor, int, basic_block,
+ enum predictor_reason, edge);
static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction);
static void predict_paths_leading_to_edge (edge, enum br_predictor, enum prediction);
static bool can_predict_insn_p (const rtx_insn *);
@@ -723,21 +735,31 @@ invert_br_probabilities (rtx insn)
static void
dump_prediction (FILE *file, enum br_predictor predictor, int probability,
- basic_block bb, int used)
+ basic_block bb, enum predictor_reason reason = NONE,
+ edge ep_edge = NULL)
{
- edge e;
+ edge e = ep_edge;
edge_iterator ei;
if (!file)
return;
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (! (e->flags & EDGE_FALLTHRU))
- break;
+ if (e == NULL)
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (! (e->flags & EDGE_FALLTHRU))
+ break;
- fprintf (file, " %s heuristics%s: %.1f%%",
+ char edge_info_str[128];
+ if (ep_edge)
+ sprintf (edge_info_str, " of edge %d->%d", ep_edge->src->index,
+ ep_edge->dest->index);
+ else
+ edge_info_str[0] = '\0';
+
+ fprintf (file, " %s heuristics%s%s: %.1f%%",
predictor_info[predictor].name,
- used ? "" : " (ignored)", probability * 100.0 / REG_BR_PROB_BASE);
+ edge_info_str, reason_messages[reason],
+ probability * 100.0 / REG_BR_PROB_BASE);
if (bb->count)
{
@@ -834,18 +856,18 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
if (!found)
dump_prediction (dump_file, PRED_NO_PREDICTION,
- combined_probability, bb, true);
+ combined_probability, bb);
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability,
- bb, !first_match);
+ bb, !first_match ? NONE : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability,
- bb, first_match);
+ bb, first_match ? NONE: IGNORED);
}
if (first_match)
combined_probability = best_probability;
- dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
while (*pnote)
{
@@ -856,7 +878,8 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
int probability = INTVAL (XEXP (XEXP (*pnote, 0), 1));
dump_prediction (dump_file, predictor, probability, bb,
- !first_match || best_predictor == predictor);
+ (!first_match || best_predictor == predictor)
+ ? NONE : IGNORED);
*pnote = XEXP (*pnote, 1);
}
else
@@ -887,6 +910,121 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
single_succ_edge (bb)->probability = REG_BR_PROB_BASE;
}
+/* Edge prediction hash traits. */
+
+struct predictor_hash: pointer_hash <edge_prediction>
+{
+
+ static inline hashval_t hash (const edge_prediction *);
+ static inline bool equal (const edge_prediction *, const edge_prediction *);
+};
+
+/* Calculate hash value of an edge prediction P based on predictor and
+ normalized probability. */
+
+inline hashval_t
+predictor_hash::hash (const edge_prediction *p)
+{
+ inchash::hash hstate;
+ hstate.add_int (p->ep_predictor);
+
+ int prob = p->ep_probability;
+ if (prob > REG_BR_PROB_BASE / 2)
+ prob = REG_BR_PROB_BASE - prob;
+
+ hstate.add_int (prob);
+
+ return hstate.end ();
+}
+
+/* Return true whether edge predictions P1 and P2 use the same predictor and
+ have equal (or opposed probability). */
+
+inline bool
+predictor_hash::equal (const edge_prediction *p1, const edge_prediction *p2)
+{
+ return (p1->ep_predictor == p2->ep_predictor
+ && (p1->ep_probability == p2->ep_probability
+ || p1->ep_probability == REG_BR_PROB_BASE - p2->ep_probability));
+}
+
+struct predictor_hash_traits: predictor_hash,
+ typed_noop_remove <edge_prediction *> {};
+
+/* Return true if edge prediction P is not in DATA hash set. */
+
+static bool
+not_removed_prediction_p (edge_prediction *p, void *data)
+{
+ hash_set<edge_prediction *> *remove = (hash_set<edge_prediction *> *) data;
+ return !remove->contains (p);
+}
+
+/* Prune predictions for a basic block BB. Currently we do following
+ clean-up steps:
+
+ 1) remove duplicate prediction that is guessed with the same probability
+ (different than 1/2) to both edge
+ 2) remove duplicates for a prediction that belongs with the same probability
+ to a single edge
+
+ */
+
+static void
+prune_predictions_for_bb (basic_block bb)
+{
+ edge_prediction **preds = bb_predictions->get (bb);
+
+ if (preds)
+ {
+ hash_table <predictor_hash_traits> s (13);
+ hash_set <edge_prediction *> remove;
+
+ /* Step 1: identify predictors that should be removed. */
+ for (edge_prediction *pred = *preds; pred; pred = pred->ep_next)
+ {
+ edge_prediction *existing = s.find (pred);
+ if (existing)
+ {
+ if (pred->ep_edge == existing->ep_edge
+ && pred->ep_probability == existing->ep_probability)
+ {
+ /* Remove a duplicate predictor. */
+ dump_prediction (dump_file, pred->ep_predictor,
+ pred->ep_probability, bb,
+ SINGLE_EDGE_DUPLICATE, pred->ep_edge);
+
+ remove.add (pred);
+ }
+ else if (pred->ep_edge != existing->ep_edge
+ && pred->ep_probability == existing->ep_probability
+ && pred->ep_probability != REG_BR_PROB_BASE / 2)
+ {
+ /* Remove both predictors as they predict the same
+ for both edges. */
+ dump_prediction (dump_file, existing->ep_predictor,
+ pred->ep_probability, bb,
+ EDGE_PAIR_DUPLICATE,
+ existing->ep_edge);
+ dump_prediction (dump_file, pred->ep_predictor,
+ pred->ep_probability, bb,
+ EDGE_PAIR_DUPLICATE,
+ pred->ep_edge);
+
+ remove.add (existing);
+ remove.add (pred);
+ }
+ }
+
+ edge_prediction **slot2 = s.find_slot (pred, INSERT);
+ *slot2 = pred;
+ }
+
+ /* Step 2: Remove predictors. */
+ filter_predictions (preds, not_removed_prediction_p, &remove);
+ }
+}
+
/* Combine predictions into single probability and store them into CFG.
Remove now useless prediction entries.
If DRY_RUN is set, only produce dumps and do not modify profile. */
@@ -935,7 +1073,10 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
if (dump_file)
fprintf (dump_file, "Predictions for bb %i\n", bb->index);
+ prune_predictions_for_bb (bb);
+
edge_prediction **preds = bb_predictions->get (bb);
+
if (preds)
{
/* We implement "first match" heuristics and use probability guessed
@@ -1001,18 +1142,18 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
first_match = true;
if (!found)
- dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb);
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability, bb,
- !first_match);
+ !first_match ? NONE : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability, bb,
- first_match);
+ first_match ? NONE : IGNORED);
}
if (first_match)
combined_probability = best_probability;
- dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
if (preds)
{
@@ -1021,10 +1162,9 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
enum br_predictor predictor = pred->ep_predictor;
int probability = pred->ep_probability;
- if (pred->ep_edge != EDGE_SUCC (bb, 0))
- probability = REG_BR_PROB_BASE - probability;
dump_prediction (dump_file, predictor, probability, bb,
- !first_match || best_predictor == predictor);
+ (!first_match || best_predictor == predictor)
+ ? NONE : IGNORED, pred->ep_edge);
}
}
clear_bb_predictions (bb);
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/N] Add sorting support to analyze_brprob script
2016-06-02 11:57 [PATCH 0/2] Deduplicate edge predictors marxin
2016-06-02 11:57 ` [PATCH 1/2] Introduce filtering for edge_predictions marxin
2016-06-02 11:57 ` [PATCH 2/2] Add edge predictions pruning marxin
@ 2016-06-08 12:26 ` Martin Liška
2016-06-08 15:02 ` Jan Hubicka
2016-06-08 12:29 ` [PATCH 4/N] Add new analyze_brprob_spec.py script Martin Liška
3 siblings, 1 reply; 14+ messages in thread
From: Martin Liška @ 2016-06-08 12:26 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2842 bytes --]
Hello.
This is a small followup, where I would like to add new argument to analyze_brprob.py
script file. With the patch, one can sort predictors by e.g. hitrate:
Example CPU2006
HEURISTICS BRANCHES (REL) HITRATE COVERAGE COVERAGE (REL)
loop iv compare 33 0.1% 20.27% / 86.24% 30630826 30.63M 0.0%
no prediction 10406 19.5% 33.41% / 84.76% 139755242456 139.76G 14.1%
early return (on trees) 6328 11.9% 54.20% / 86.48% 33569991740 33.57G 3.4%
guessed loop iterations 112 0.2% 62.06% / 64.49% 958458522 958.46M 0.1%
fail alloc 595 1.1% 62.18% / 100.00% 595 595.00 0.0%
opcode values positive (on trees) 4266 8.0% 64.30% / 91.28% 16931889792 16.93G 1.7%
opcode values nonequal (on trees) 6600 12.4% 66.23% / 80.60% 71483051282 71.48G 7.2%
continue 507 0.9% 66.66% / 82.85% 10086808016 10.09G 1.0%
call 11351 21.3% 67.16% / 92.24% 34680666103 34.68G 3.5%
loop iterations 2689 5.0% 67.99% / 67.99% 408309517405 408.31G 41.3%
DS theory 26385 49.4% 68.62% / 85.44% 146974369890 146.97G 14.9%
const return 271 0.5% 69.39% / 87.09% 301566712 301.57M 0.0%
pointer (on trees) 6230 11.7% 69.59% / 87.18% 16667735314 16.67G 1.7%
combined 53398 100.0% 70.31% / 80.36% 989164856862 989.16G 100.0%
goto 78 0.1% 70.36% / 96.96% 951041538 951.04M 0.1%
first match 16607 31.1% 78.00% / 78.42% 702435244516 702.44G 71.0%
extra loop exit 141 0.3% 82.80% / 88.17% 1696946942 1.70G 0.2%
null return 393 0.7% 91.47% / 93.08% 3268678197 3.27G 0.3%
loop exit 9909 18.6% 91.80% / 92.81% 282927773783 282.93G 28.6%
guess loop iv compare 178 0.3% 97.81% / 97.85% 4375086453 4.38G 0.4%
negative return 277 0.5% 97.94% / 99.23% 1062119028 1.06G 0.1%
noreturn call 2372 4.4% 100.00% / 100.00% 8356562323 8.36G 0.8%
overflow 1282 2.4% 100.00% / 100.00% 175074177 175.07M 0.0%
zero-sized array 677 1.3% 100.00% / 100.00% 112723803 112.72M 0.0%
unconditional jump 103 0.2% 100.00% / 100.00% 491001 491.00K 0.0%
Martin
[-- Attachment #2: 0003-Add-sorting-support-to-analyze_brprob-script.patch --]
[-- Type: text/x-patch, Size: 2852 bytes --]
From fc40cf57a5b822558d32182b9937ba6dafd62377 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 2 Jun 2016 13:15:08 +0200
Subject: [PATCH 3/4] Add sorting support to analyze_brprob script
contrib/ChangeLog:
2016-06-08 Martin Liska <mliska@suse.cz>
* analyze_brprob.py: Add new argument --sorting.
---
contrib/analyze_brprob.py | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
index 9416eed..9808c46 100755
--- a/contrib/analyze_brprob.py
+++ b/contrib/analyze_brprob.py
@@ -65,6 +65,7 @@
import sys
import os
import re
+import argparse
def percentage(a, b):
return 100.0 * a / b
@@ -77,6 +78,9 @@ class Summary:
self.hits = 0
self.fits = 0
+ def get_hitrate(self):
+ return self.hits / self.count
+
def count_formatted(self):
v = self.count
for unit in ['','K','M','G','T','P','E','Z']:
@@ -108,22 +112,30 @@ class Profile:
def count_max(self):
return max([v.count for k, v in self.heuristics.items()])
- def dump(self):
+ def dump(self, sorting):
+ sorter = lambda x: x[1].branches
+ if sorting == 'hitrate':
+ sorter = lambda x: x[1].get_hitrate()
+ elif sorting == 'coverage':
+ sorter = lambda x: x[1].count
+
print('%-36s %8s %6s %-16s %14s %8s %6s' % ('HEURISTICS', 'BRANCHES', '(REL)',
'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)'))
- for (k, v) in sorted(self.heuristics.items(), key = lambda x: x[1].branches):
+ for (k, v) in sorted(self.heuristics.items(), key = sorter):
print('%-36s %8i %5.1f%% %6.2f%% / %6.2f%% %14i %8s %5.1f%%' %
(k, v.branches, percentage(v.branches, self.branches_max ()),
percentage(v.hits, v.count), percentage(v.fits, v.count),
v.count, v.count_formatted(), percentage(v.count, self.count_max()) ))
-if len(sys.argv) != 2:
- print('Usage: ./analyze_brprob.py dump_file')
- exit(1)
+parser = argparse.ArgumentParser()
+parser.add_argument('dump_file', metavar = 'dump_file', help = 'IPA profile dump file')
+parser.add_argument('-s', '--sorting', dest = 'sorting', choices = ['branches', 'hitrate', 'coverage'], default = 'branches')
+
+args = parser.parse_args()
profile = Profile(sys.argv[1])
r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
-for l in open(profile.filename).readlines():
+for l in open(args.dump_file).readlines():
m = r.match(l)
if m != None and m.group(3) == None:
name = m.group(1)
@@ -133,4 +145,4 @@ for l in open(profile.filename).readlines():
profile.add(name, prediction, count, hits)
-profile.dump()
+profile.dump(args.sorting)
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/N] Add new analyze_brprob_spec.py script
2016-06-02 11:57 [PATCH 0/2] Deduplicate edge predictors marxin
` (2 preceding siblings ...)
2016-06-08 12:26 ` [PATCH 3/N] Add sorting support to analyze_brprob script Martin Liška
@ 2016-06-08 12:29 ` Martin Liška
2016-06-08 15:12 ` Jan Hubicka
3 siblings, 1 reply; 14+ messages in thread
From: Martin Liška @ 2016-06-08 12:29 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 3635 bytes --]
Hi.
The second follow up patch adds new script which is a simple wrapper around
analyze_brprob.py and can be used to dump statistics for results that are in
different folder (like SPEC benchmarks).
Sample:
./contrib/analyze_brprob_spec.py --sorting=hitrate /home/marxin/Programming/cpu2006/benchspec/CPU2006/
Sample output:
401.bzip2
HEURISTICS BRANCHES (REL) HITRATE COVERAGE COVERAGE (REL)
no prediction 107 14.0% 19.45% / 84.37% 2768134733 2.77G 10.8%
opcode values nonequal (on trees) 76 10.0% 32.24% / 85.06% 4034681344 4.03G 15.8%
call 95 12.5% 45.50% / 93.31% 152224913 152.22M 0.6%
DS theory 275 36.1% 45.56% / 84.30% 7308863904 7.31G 28.6%
continue 14 1.8% 48.44% / 73.14% 1479774996 1.48G 5.8%
guessed loop iterations 12 1.6% 68.30% / 71.61% 269705737 269.71M 1.1%
combined 762 100.0% 69.52% / 89.32% 25553311262 25.55G 100.0%
goto 40 5.2% 72.41% / 98.80% 882062676 882.06M 3.5%
opcode values positive (on trees) 40 5.2% 76.74% / 88.09% 1394104926 1.39G 5.5%
pointer (on trees) 61 8.0% 83.79% / 100.00% 931107 931.11K 0.0%
early return (on trees) 31 4.1% 84.39% / 84.41% 2548058402 2.55G 10.0%
first match 380 49.9% 89.79% / 92.57% 15476312625 15.48G 60.6%
loop exit 316 41.5% 90.09% / 92.88% 15065219828 15.07G 59.0%
guess loop iv compare 2 0.3% 99.61% / 99.61% 26987995 26.99M 0.1%
loop iv compare 1 0.1% 99.61% / 99.61% 105411 105.41K 0.0%
loop iterations 38 5.0% 99.64% / 99.64% 140236649 140.24M 0.5%
null return 2 0.3% 100.00% / 100.00% 18 18.00 0.0%
noreturn call 13 1.7% 100.00% / 100.00% 1045000 1.04M 0.0%
const return 2 0.3% 100.00% / 100.00% 816 816.00 0.0%
negative return 62 8.1% 100.00% / 100.00% 618097152 618.10M 2.4%
410.bwaves
HEURISTICS BRANCHES (REL) HITRATE COVERAGE COVERAGE (REL)
call 1 0.6% 0.00% / 100.00% 20 20.00 0.0%
no prediction 6 3.7% 0.28% / 99.72% 2704184 2.70M 0.1%
opcode values nonequal (on trees) 4 2.4% 60.00% / 70.00% 200 200.00 0.0%
loop iterations 7 4.3% 80.00% / 80.00% 112892000 112.89M 2.4%
first match 83 50.6% 81.67% / 81.67% 4393885465 4.39G 92.1%
loop exit 76 46.3% 81.71% / 81.71% 4280993465 4.28G 89.8%
combined 164 100.0% 83.05% / 83.11% 4768545507 4.77G 100.0%
DS theory 75 45.7% 100.00% / 100.00% 371955858 371.96M 7.8%
early return (on trees) 3 1.8% 100.00% / 100.00% 688 688.00 0.0%
opcode values positive (on trees) 71 43.3% 100.00% / 100.00% 371955658 371.96M 7.8%
...
Thanks,
Martin
[-- Attachment #2: 0004-Add-new-analyze_brprob_spec.py-script.patch --]
[-- Type: text/x-patch, Size: 2498 bytes --]
From ca9806bf77bd90df43913f5f1552ed16379dcf38 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 Jun 2016 12:46:43 +0200
Subject: [PATCH 4/4] Add new analyze_brprob_spec.py script
contrib/ChangeLog:
2016-06-08 Martin Liska <mliska@suse.cz>
* analyze_brprob_spec.py: New file.
---
contrib/analyze_brprob_spec.py | 58 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100755 contrib/analyze_brprob_spec.py
diff --git a/contrib/analyze_brprob_spec.py b/contrib/analyze_brprob_spec.py
new file mode 100755
index 0000000..a28eaac
--- /dev/null
+++ b/contrib/analyze_brprob_spec.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+
+# 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 3, 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>. */
+
+import sys
+import os
+import subprocess
+import tempfile
+import argparse
+
+script_location = os.path.realpath(__file__)
+
+parser = argparse.ArgumentParser()
+parser.add_argument('location', metavar = 'dump_file', help = 'Location with SPEC benchmarks')
+parser.add_argument('-s', '--sorting', dest = 'sorting', choices = ['branches', 'hitrate', 'coverage'], default = 'branches')
+
+args = parser.parse_args()
+
+benchmarks = os.listdir(args.location)
+
+for b in sorted(benchmarks):
+ dumps = []
+ for root, dirs, files in os.walk(os.path.join(args.location, b)):
+ for x in files:
+ if x.endswith('.profile'):
+ dumps.append(os.path.join(root, x))
+
+ if len(dumps) == 0:
+ continue
+
+ temp = tempfile.NamedTemporaryFile(delete = False)
+ for d in dumps:
+ temp.write(open(d, 'rb').read())
+
+ temp.close()
+
+ print()
+ print(b)
+ sys.stdout.flush()
+ p = [os.path.join(os.path.dirname(script_location), 'analyze_brprob.py'), temp.name, '--sorting', args.sorting]
+ p = subprocess.check_call(p)
+ sys.stdout.flush()
+
+ os.remove(temp.name)
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] Add edge predictions pruning
2016-06-08 12:25 ` Martin Liška
@ 2016-06-08 12:41 ` Jan Hubicka
2016-06-09 11:24 ` Martin Liška
0 siblings, 1 reply; 14+ messages in thread
From: Jan Hubicka @ 2016-06-08 12:41 UTC (permalink / raw)
To: Martin Liška; +Cc: gcc-patches, Jan Hubicka
> 2016-06-01 Martin Liska <mliska@suse.cz>
>
> * analyze_brprob.py: Cover new dump output format.
>
> gcc/ChangeLog:
>
> 2016-06-01 Martin Liska <mliska@suse.cz>
>
> * predict.c (dump_prediction): Add new argument.
> (enum predictor_reason): New enum.
> (struct predictor_hash): New struct.
> (predictor_hash::hash): New function.
> (predictor_hash::equal): Likewise.
> (not_removed_prediction_p): New function.
> (prune_predictions_for_bb): Likewise.
> (combine_predictions_for_bb): Prune predictions.
> ---
> contrib/analyze_brprob.py | 10 +--
> gcc/predict.c | 180 ++++++++++++++++++++++++++++++++++++++++------
> 2 files changed, 165 insertions(+), 25 deletions(-)
>
> diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
> index 36371ff..9416eed 100755
> --- a/contrib/analyze_brprob.py
> +++ b/contrib/analyze_brprob.py
> @@ -122,14 +122,14 @@ if len(sys.argv) != 2:
> exit(1)
>
> profile = Profile(sys.argv[1])
> -r = re.compile(' (.*) heuristics: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
> +r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
> for l in open(profile.filename).readlines():
> m = r.match(l)
> - if m != None:
> + if m != None and m.group(3) == None:
> name = m.group(1)
> - prediction = float(m.group(2))
> - count = int(m.group(3))
> - hits = int(m.group(4))
> + prediction = float(m.group(4))
> + count = int(m.group(5))
> + hits = int(m.group(6))
>
> profile.add(name, prediction, count, hits)
>
> diff --git a/gcc/predict.c b/gcc/predict.c
> index e058793..f2ecc4a 100644
> --- a/gcc/predict.c
> +++ b/gcc/predict.c
> @@ -55,13 +55,25 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-ssa-loop.h"
> #include "tree-scalar-evolution.h"
>
> +enum predictor_reason
Add comment, please
> +{
> + NONE,
> + IGNORED,
> + SINGLE_EDGE_DUPLICATE,
> + EDGE_PAIR_DUPLICATE
> +};
> +
> +static const char *reason_messages[] = {"", " (ignored)",
> + " (single edge duplicate)", " (edge pair duplicate)"};
And here too.
> +
> /* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
> 1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
> static sreal real_almost_one, real_br_prob_base,
> real_inv_br_prob_base, real_one_half, real_bb_freq_max;
>
> static void combine_predictions_for_insn (rtx_insn *, basic_block);
> -static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
> +static void dump_prediction (FILE *, enum br_predictor, int, basic_block,
> + enum predictor_reason, edge);
> static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction);
> static void predict_paths_leading_to_edge (edge, enum br_predictor, enum prediction);
> static bool can_predict_insn_p (const rtx_insn *);
> @@ -723,21 +735,31 @@ invert_br_probabilities (rtx insn)
>
> static void
> dump_prediction (FILE *file, enum br_predictor predictor, int probability,
> - basic_block bb, int used)
> + basic_block bb, enum predictor_reason reason = NONE,
> + edge ep_edge = NULL)
> {
> - edge e;
> + edge e = ep_edge;
> edge_iterator ei;
>
> if (!file)
> return;
>
> - FOR_EACH_EDGE (e, ei, bb->succs)
> - if (! (e->flags & EDGE_FALLTHRU))
> - break;
> + if (e == NULL)
> + FOR_EACH_EDGE (e, ei, bb->succs)
> + if (! (e->flags & EDGE_FALLTHRU))
> + break;
>
> - fprintf (file, " %s heuristics%s: %.1f%%",
> + char edge_info_str[128];
> + if (ep_edge)
> + sprintf (edge_info_str, " of edge %d->%d", ep_edge->src->index,
> + ep_edge->dest->index);
> + else
> + edge_info_str[0] = '\0';
> +
> + fprintf (file, " %s heuristics%s%s: %.1f%%",
> predictor_info[predictor].name,
> - used ? "" : " (ignored)", probability * 100.0 / REG_BR_PROB_BASE);
> + edge_info_str, reason_messages[reason],
> + probability * 100.0 / REG_BR_PROB_BASE);
>
> if (bb->count)
> {
> @@ -834,18 +856,18 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
>
> if (!found)
> dump_prediction (dump_file, PRED_NO_PREDICTION,
> - combined_probability, bb, true);
> + combined_probability, bb);
> else
> {
> dump_prediction (dump_file, PRED_DS_THEORY, combined_probability,
> - bb, !first_match);
> + bb, !first_match ? NONE : IGNORED);
> dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability,
> - bb, first_match);
> + bb, first_match ? NONE: IGNORED);
> }
>
> if (first_match)
> combined_probability = best_probability;
> - dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
> + dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
>
> while (*pnote)
> {
> @@ -856,7 +878,8 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
> int probability = INTVAL (XEXP (XEXP (*pnote, 0), 1));
>
> dump_prediction (dump_file, predictor, probability, bb,
> - !first_match || best_predictor == predictor);
> + (!first_match || best_predictor == predictor)
> + ? NONE : IGNORED);
> *pnote = XEXP (*pnote, 1);
> }
> else
> @@ -887,6 +910,121 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
> single_succ_edge (bb)->probability = REG_BR_PROB_BASE;
> }
>
> +/* Edge prediction hash traits. */
> +
> +struct predictor_hash: pointer_hash <edge_prediction>
> +{
> +
> + static inline hashval_t hash (const edge_prediction *);
> + static inline bool equal (const edge_prediction *, const edge_prediction *);
> +};
> +
> +/* Calculate hash value of an edge prediction P based on predictor and
> + normalized probability. */
> +
> +inline hashval_t
> +predictor_hash::hash (const edge_prediction *p)
> +{
> + inchash::hash hstate;
> + hstate.add_int (p->ep_predictor);
> +
> + int prob = p->ep_probability;
> + if (prob > REG_BR_PROB_BASE / 2)
> + prob = REG_BR_PROB_BASE - prob;
> +
> + hstate.add_int (prob);
> +
> + return hstate.end ();
> +}
Adding hash for this prupose is bit of an overkill (there are
definitly cheaper ways of solving so), but it will hardly affect compile
time, so the pathc is OK.
Thanks,
Honza
> +
> +/* Return true whether edge predictions P1 and P2 use the same predictor and
> + have equal (or opposed probability). */
> +
> +inline bool
> +predictor_hash::equal (const edge_prediction *p1, const edge_prediction *p2)
> +{
> + return (p1->ep_predictor == p2->ep_predictor
> + && (p1->ep_probability == p2->ep_probability
> + || p1->ep_probability == REG_BR_PROB_BASE - p2->ep_probability));
> +}
> +
> +struct predictor_hash_traits: predictor_hash,
> + typed_noop_remove <edge_prediction *> {};
> +
> +/* Return true if edge prediction P is not in DATA hash set. */
> +
> +static bool
> +not_removed_prediction_p (edge_prediction *p, void *data)
> +{
> + hash_set<edge_prediction *> *remove = (hash_set<edge_prediction *> *) data;
> + return !remove->contains (p);
> +}
> +
> +/* Prune predictions for a basic block BB. Currently we do following
> + clean-up steps:
> +
> + 1) remove duplicate prediction that is guessed with the same probability
> + (different than 1/2) to both edge
> + 2) remove duplicates for a prediction that belongs with the same probability
> + to a single edge
> +
> + */
> +
> +static void
> +prune_predictions_for_bb (basic_block bb)
> +{
> + edge_prediction **preds = bb_predictions->get (bb);
> +
> + if (preds)
> + {
> + hash_table <predictor_hash_traits> s (13);
> + hash_set <edge_prediction *> remove;
> +
> + /* Step 1: identify predictors that should be removed. */
> + for (edge_prediction *pred = *preds; pred; pred = pred->ep_next)
> + {
> + edge_prediction *existing = s.find (pred);
> + if (existing)
> + {
> + if (pred->ep_edge == existing->ep_edge
> + && pred->ep_probability == existing->ep_probability)
> + {
> + /* Remove a duplicate predictor. */
> + dump_prediction (dump_file, pred->ep_predictor,
> + pred->ep_probability, bb,
> + SINGLE_EDGE_DUPLICATE, pred->ep_edge);
> +
> + remove.add (pred);
> + }
> + else if (pred->ep_edge != existing->ep_edge
> + && pred->ep_probability == existing->ep_probability
> + && pred->ep_probability != REG_BR_PROB_BASE / 2)
> + {
> + /* Remove both predictors as they predict the same
> + for both edges. */
> + dump_prediction (dump_file, existing->ep_predictor,
> + pred->ep_probability, bb,
> + EDGE_PAIR_DUPLICATE,
> + existing->ep_edge);
> + dump_prediction (dump_file, pred->ep_predictor,
> + pred->ep_probability, bb,
> + EDGE_PAIR_DUPLICATE,
> + pred->ep_edge);
> +
> + remove.add (existing);
> + remove.add (pred);
> + }
> + }
> +
> + edge_prediction **slot2 = s.find_slot (pred, INSERT);
> + *slot2 = pred;
> + }
> +
> + /* Step 2: Remove predictors. */
> + filter_predictions (preds, not_removed_prediction_p, &remove);
> + }
> +}
> +
> /* Combine predictions into single probability and store them into CFG.
> Remove now useless prediction entries.
> If DRY_RUN is set, only produce dumps and do not modify profile. */
> @@ -935,7 +1073,10 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
> if (dump_file)
> fprintf (dump_file, "Predictions for bb %i\n", bb->index);
>
> + prune_predictions_for_bb (bb);
> +
> edge_prediction **preds = bb_predictions->get (bb);
> +
> if (preds)
> {
> /* We implement "first match" heuristics and use probability guessed
> @@ -1001,18 +1142,18 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
> first_match = true;
>
> if (!found)
> - dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb, true);
> + dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb);
> else
> {
> dump_prediction (dump_file, PRED_DS_THEORY, combined_probability, bb,
> - !first_match);
> + !first_match ? NONE : IGNORED);
> dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability, bb,
> - first_match);
> + first_match ? NONE : IGNORED);
> }
>
> if (first_match)
> combined_probability = best_probability;
> - dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
> + dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
>
> if (preds)
> {
> @@ -1021,10 +1162,9 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
> enum br_predictor predictor = pred->ep_predictor;
> int probability = pred->ep_probability;
>
> - if (pred->ep_edge != EDGE_SUCC (bb, 0))
> - probability = REG_BR_PROB_BASE - probability;
> dump_prediction (dump_file, predictor, probability, bb,
> - !first_match || best_predictor == predictor);
> + (!first_match || best_predictor == predictor)
> + ? NONE : IGNORED, pred->ep_edge);
> }
> }
> clear_bb_predictions (bb);
> --
> 2.8.3
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/N] Add sorting support to analyze_brprob script
2016-06-08 12:26 ` [PATCH 3/N] Add sorting support to analyze_brprob script Martin Liška
@ 2016-06-08 15:02 ` Jan Hubicka
0 siblings, 0 replies; 14+ messages in thread
From: Jan Hubicka @ 2016-06-08 15:02 UTC (permalink / raw)
To: Martin Liška; +Cc: gcc-patches
> Hello.
>
> This is a small followup, where I would like to add new argument to analyze_brprob.py
> script file. With the patch, one can sort predictors by e.g. hitrate:
OK,
thanks!
Honza
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/N] Add new analyze_brprob_spec.py script
2016-06-08 12:29 ` [PATCH 4/N] Add new analyze_brprob_spec.py script Martin Liška
@ 2016-06-08 15:12 ` Jan Hubicka
0 siblings, 0 replies; 14+ messages in thread
From: Jan Hubicka @ 2016-06-08 15:12 UTC (permalink / raw)
To: Martin Liška; +Cc: gcc-patches
> Hi.
>
> The second follow up patch adds new script which is a simple wrapper around
> analyze_brprob.py and can be used to dump statistics for results that are in
> different folder (like SPEC benchmarks).
>
> Sample:
> ./contrib/analyze_brprob_spec.py --sorting=hitrate /home/marxin/Programming/cpu2006/benchspec/CPU2006/
>
> Sample output:
> 401.bzip2
> HEURISTICS BRANCHES (REL) HITRATE COVERAGE COVERAGE (REL)
> no prediction 107 14.0% 19.45% / 84.37% 2768134733 2.77G 10.8%
> opcode values nonequal (on trees) 76 10.0% 32.24% / 85.06% 4034681344 4.03G 15.8%
> call 95 12.5% 45.50% / 93.31% 152224913 152.22M 0.6%
> DS theory 275 36.1% 45.56% / 84.30% 7308863904 7.31G 28.6%
> continue 14 1.8% 48.44% / 73.14% 1479774996 1.48G 5.8%
> guessed loop iterations 12 1.6% 68.30% / 71.61% 269705737 269.71M 1.1%
> combined 762 100.0% 69.52% / 89.32% 25553311262 25.55G 100.0%
> goto 40 5.2% 72.41% / 98.80% 882062676 882.06M 3.5%
> opcode values positive (on trees) 40 5.2% 76.74% / 88.09% 1394104926 1.39G 5.5%
> pointer (on trees) 61 8.0% 83.79% / 100.00% 931107 931.11K 0.0%
> early return (on trees) 31 4.1% 84.39% / 84.41% 2548058402 2.55G 10.0%
> first match 380 49.9% 89.79% / 92.57% 15476312625 15.48G 60.6%
> loop exit 316 41.5% 90.09% / 92.88% 15065219828 15.07G 59.0%
> guess loop iv compare 2 0.3% 99.61% / 99.61% 26987995 26.99M 0.1%
> loop iv compare 1 0.1% 99.61% / 99.61% 105411 105.41K 0.0%
> loop iterations 38 5.0% 99.64% / 99.64% 140236649 140.24M 0.5%
> null return 2 0.3% 100.00% / 100.00% 18 18.00 0.0%
> noreturn call 13 1.7% 100.00% / 100.00% 1045000 1.04M 0.0%
> const return 2 0.3% 100.00% / 100.00% 816 816.00 0.0%
> negative return 62 8.1% 100.00% / 100.00% 618097152 618.10M 2.4%
>
> 410.bwaves
> HEURISTICS BRANCHES (REL) HITRATE COVERAGE COVERAGE (REL)
> call 1 0.6% 0.00% / 100.00% 20 20.00 0.0%
> no prediction 6 3.7% 0.28% / 99.72% 2704184 2.70M 0.1%
> opcode values nonequal (on trees) 4 2.4% 60.00% / 70.00% 200 200.00 0.0%
> loop iterations 7 4.3% 80.00% / 80.00% 112892000 112.89M 2.4%
> first match 83 50.6% 81.67% / 81.67% 4393885465 4.39G 92.1%
> loop exit 76 46.3% 81.71% / 81.71% 4280993465 4.28G 89.8%
> combined 164 100.0% 83.05% / 83.11% 4768545507 4.77G 100.0%
> DS theory 75 45.7% 100.00% / 100.00% 371955858 371.96M 7.8%
> early return (on trees) 3 1.8% 100.00% / 100.00% 688 688.00 0.0%
> opcode values positive (on trees) 71 43.3% 100.00% / 100.00% 371955658 371.96M 7.8%
>
> ...
>
> Thanks,
> Martin
>
> >From ca9806bf77bd90df43913f5f1552ed16379dcf38 Mon Sep 17 00:00:00 2001
> From: marxin <mliska@suse.cz>
> Date: Fri, 3 Jun 2016 12:46:43 +0200
> Subject: [PATCH 4/4] Add new analyze_brprob_spec.py script
>
> contrib/ChangeLog:
>
> 2016-06-08 Martin Liska <mliska@suse.cz>
>
> * analyze_brprob_spec.py: New file.
OK,
thanks
Honza
> ---
> contrib/analyze_brprob_spec.py | 58 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 58 insertions(+)
> create mode 100755 contrib/analyze_brprob_spec.py
>
> diff --git a/contrib/analyze_brprob_spec.py b/contrib/analyze_brprob_spec.py
> new file mode 100755
> index 0000000..a28eaac
> --- /dev/null
> +++ b/contrib/analyze_brprob_spec.py
> @@ -0,0 +1,58 @@
> +#!/usr/bin/env python3
> +
> +# 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 3, 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 COPYING3. If not see
> +# <http://www.gnu.org/licenses/>. */
> +
> +import sys
> +import os
> +import subprocess
> +import tempfile
> +import argparse
> +
> +script_location = os.path.realpath(__file__)
> +
> +parser = argparse.ArgumentParser()
> +parser.add_argument('location', metavar = 'dump_file', help = 'Location with SPEC benchmarks')
> +parser.add_argument('-s', '--sorting', dest = 'sorting', choices = ['branches', 'hitrate', 'coverage'], default = 'branches')
> +
> +args = parser.parse_args()
> +
> +benchmarks = os.listdir(args.location)
> +
> +for b in sorted(benchmarks):
> + dumps = []
> + for root, dirs, files in os.walk(os.path.join(args.location, b)):
> + for x in files:
> + if x.endswith('.profile'):
> + dumps.append(os.path.join(root, x))
> +
> + if len(dumps) == 0:
> + continue
> +
> + temp = tempfile.NamedTemporaryFile(delete = False)
> + for d in dumps:
> + temp.write(open(d, 'rb').read())
> +
> + temp.close()
> +
> + print()
> + print(b)
> + sys.stdout.flush()
> + p = [os.path.join(os.path.dirname(script_location), 'analyze_brprob.py'), temp.name, '--sorting', args.sorting]
> + p = subprocess.check_call(p)
> + sys.stdout.flush()
> +
> + os.remove(temp.name)
> --
> 2.8.3
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] Add edge predictions pruning
2016-06-08 12:41 ` Jan Hubicka
@ 2016-06-09 11:24 ` Martin Liška
2016-06-12 11:55 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan-Benedict Glaw
0 siblings, 1 reply; 14+ messages in thread
From: Martin Liška @ 2016-06-09 11:24 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 356 bytes --]
On 06/08/2016 02:41 PM, Jan Hubicka wrote:
> Adding hash for this prupose is bit of an overkill (there are
> definitly cheaper ways of solving so), but it will hardly affect compile
> time, so the pathc is OK.
>
> Thanks,
> Honza
Hi
Sending the final version where I added comments and I also changed
dump scanning to cover the new dump format.
Martin
[-- Attachment #2: 0002-Add-edge-predictions-pruning-v3.patch --]
[-- Type: text/x-patch, Size: 16828 bytes --]
From f83a515c952f3f17b45c757a3a84761d95959a39 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 31 May 2016 17:29:53 +0200
Subject: [PATCH 2/4] Add edge predictions pruning
contrib/ChangeLog:
2016-06-01 Martin Liska <mliska@suse.cz>
* analyze_brprob.py: Cover new dump output format.
gcc/ChangeLog:
2016-06-01 Martin Liska <mliska@suse.cz>
* predict.c (dump_prediction): Add new argument.
(enum predictor_reason): New enum.
(struct predictor_hash): New struct.
(predictor_hash::hash): New function.
(predictor_hash::equal): Likewise.
(not_removed_prediction_p): New function.
(prune_predictions_for_bb): Likewise.
(combine_predictions_for_bb): Prune predictions.
gcc/testsuite/ChangeLog:
2016-06-08 Martin Liska <mliska@suse.cz>
* g++.dg/predict-loop-exit-1.C: Scan for a new dump format.
* g++.dg/predict-loop-exit-2.C: Likewise.
* g++.dg/predict-loop-exit-3.C: Likewise.
* gcc.dg/predict-1.c: Likewise.
* gcc.dg/predict-2.c: Likewise.
* gcc.dg/predict-3.c: Likewise.
* gcc.dg/predict-4.c: Likewise.
* gcc.dg/predict-5.c: Likewise.
* gcc.dg/predict-6.c: Likewise.
* gcc.dg/predict-7.c: Likewise.
---
contrib/analyze_brprob.py | 10 +-
gcc/predict.c | 184 +++++++++++++++++++++++++----
gcc/testsuite/g++.dg/predict-loop-exit-1.C | 4 +-
gcc/testsuite/g++.dg/predict-loop-exit-2.C | 4 +-
gcc/testsuite/g++.dg/predict-loop-exit-3.C | 4 +-
gcc/testsuite/gcc.dg/predict-1.c | 2 +-
gcc/testsuite/gcc.dg/predict-2.c | 2 +-
gcc/testsuite/gcc.dg/predict-3.c | 2 +-
gcc/testsuite/gcc.dg/predict-4.c | 2 +-
gcc/testsuite/gcc.dg/predict-5.c | 2 +-
gcc/testsuite/gcc.dg/predict-6.c | 2 +-
gcc/testsuite/gcc.dg/predict-7.c | 2 +-
12 files changed, 182 insertions(+), 38 deletions(-)
diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
index 36371ff..9416eed 100755
--- a/contrib/analyze_brprob.py
+++ b/contrib/analyze_brprob.py
@@ -122,14 +122,14 @@ if len(sys.argv) != 2:
exit(1)
profile = Profile(sys.argv[1])
-r = re.compile(' (.*) heuristics: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
+r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
for l in open(profile.filename).readlines():
m = r.match(l)
- if m != None:
+ if m != None and m.group(3) == None:
name = m.group(1)
- prediction = float(m.group(2))
- count = int(m.group(3))
- hits = int(m.group(4))
+ prediction = float(m.group(4))
+ count = int(m.group(5))
+ hits = int(m.group(6))
profile.add(name, prediction, count, hits)
diff --git a/gcc/predict.c b/gcc/predict.c
index e058793..a61e01c 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -55,13 +55,29 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
+/* Enum with reasons why a predictor is ignored. */
+
+enum predictor_reason
+{
+ NONE,
+ IGNORED,
+ SINGLE_EDGE_DUPLICATE,
+ EDGE_PAIR_DUPLICATE
+};
+
+/* String messages for the aforementioned enum. */
+
+static const char *reason_messages[] = {"", " (ignored)",
+ " (single edge duplicate)", " (edge pair duplicate)"};
+
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
static sreal real_almost_one, real_br_prob_base,
real_inv_br_prob_base, real_one_half, real_bb_freq_max;
static void combine_predictions_for_insn (rtx_insn *, basic_block);
-static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
+static void dump_prediction (FILE *, enum br_predictor, int, basic_block,
+ enum predictor_reason, edge);
static void predict_paths_leading_to (basic_block, enum br_predictor, enum prediction);
static void predict_paths_leading_to_edge (edge, enum br_predictor, enum prediction);
static bool can_predict_insn_p (const rtx_insn *);
@@ -723,21 +739,31 @@ invert_br_probabilities (rtx insn)
static void
dump_prediction (FILE *file, enum br_predictor predictor, int probability,
- basic_block bb, int used)
+ basic_block bb, enum predictor_reason reason = NONE,
+ edge ep_edge = NULL)
{
- edge e;
+ edge e = ep_edge;
edge_iterator ei;
if (!file)
return;
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (! (e->flags & EDGE_FALLTHRU))
- break;
+ if (e == NULL)
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (! (e->flags & EDGE_FALLTHRU))
+ break;
+
+ char edge_info_str[128];
+ if (ep_edge)
+ sprintf (edge_info_str, " of edge %d->%d", ep_edge->src->index,
+ ep_edge->dest->index);
+ else
+ edge_info_str[0] = '\0';
- fprintf (file, " %s heuristics%s: %.1f%%",
+ fprintf (file, " %s heuristics%s%s: %.1f%%",
predictor_info[predictor].name,
- used ? "" : " (ignored)", probability * 100.0 / REG_BR_PROB_BASE);
+ edge_info_str, reason_messages[reason],
+ probability * 100.0 / REG_BR_PROB_BASE);
if (bb->count)
{
@@ -834,18 +860,18 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
if (!found)
dump_prediction (dump_file, PRED_NO_PREDICTION,
- combined_probability, bb, true);
+ combined_probability, bb);
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability,
- bb, !first_match);
+ bb, !first_match ? NONE : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability,
- bb, first_match);
+ bb, first_match ? NONE: IGNORED);
}
if (first_match)
combined_probability = best_probability;
- dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
while (*pnote)
{
@@ -856,7 +882,8 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
int probability = INTVAL (XEXP (XEXP (*pnote, 0), 1));
dump_prediction (dump_file, predictor, probability, bb,
- !first_match || best_predictor == predictor);
+ (!first_match || best_predictor == predictor)
+ ? NONE : IGNORED);
*pnote = XEXP (*pnote, 1);
}
else
@@ -887,6 +914,121 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
single_succ_edge (bb)->probability = REG_BR_PROB_BASE;
}
+/* Edge prediction hash traits. */
+
+struct predictor_hash: pointer_hash <edge_prediction>
+{
+
+ static inline hashval_t hash (const edge_prediction *);
+ static inline bool equal (const edge_prediction *, const edge_prediction *);
+};
+
+/* Calculate hash value of an edge prediction P based on predictor and
+ normalized probability. */
+
+inline hashval_t
+predictor_hash::hash (const edge_prediction *p)
+{
+ inchash::hash hstate;
+ hstate.add_int (p->ep_predictor);
+
+ int prob = p->ep_probability;
+ if (prob > REG_BR_PROB_BASE / 2)
+ prob = REG_BR_PROB_BASE - prob;
+
+ hstate.add_int (prob);
+
+ return hstate.end ();
+}
+
+/* Return true whether edge predictions P1 and P2 use the same predictor and
+ have equal (or opposed probability). */
+
+inline bool
+predictor_hash::equal (const edge_prediction *p1, const edge_prediction *p2)
+{
+ return (p1->ep_predictor == p2->ep_predictor
+ && (p1->ep_probability == p2->ep_probability
+ || p1->ep_probability == REG_BR_PROB_BASE - p2->ep_probability));
+}
+
+struct predictor_hash_traits: predictor_hash,
+ typed_noop_remove <edge_prediction *> {};
+
+/* Return true if edge prediction P is not in DATA hash set. */
+
+static bool
+not_removed_prediction_p (edge_prediction *p, void *data)
+{
+ hash_set<edge_prediction *> *remove = (hash_set<edge_prediction *> *) data;
+ return !remove->contains (p);
+}
+
+/* Prune predictions for a basic block BB. Currently we do following
+ clean-up steps:
+
+ 1) remove duplicate prediction that is guessed with the same probability
+ (different than 1/2) to both edge
+ 2) remove duplicates for a prediction that belongs with the same probability
+ to a single edge
+
+ */
+
+static void
+prune_predictions_for_bb (basic_block bb)
+{
+ edge_prediction **preds = bb_predictions->get (bb);
+
+ if (preds)
+ {
+ hash_table <predictor_hash_traits> s (13);
+ hash_set <edge_prediction *> remove;
+
+ /* Step 1: identify predictors that should be removed. */
+ for (edge_prediction *pred = *preds; pred; pred = pred->ep_next)
+ {
+ edge_prediction *existing = s.find (pred);
+ if (existing)
+ {
+ if (pred->ep_edge == existing->ep_edge
+ && pred->ep_probability == existing->ep_probability)
+ {
+ /* Remove a duplicate predictor. */
+ dump_prediction (dump_file, pred->ep_predictor,
+ pred->ep_probability, bb,
+ SINGLE_EDGE_DUPLICATE, pred->ep_edge);
+
+ remove.add (pred);
+ }
+ else if (pred->ep_edge != existing->ep_edge
+ && pred->ep_probability == existing->ep_probability
+ && pred->ep_probability != REG_BR_PROB_BASE / 2)
+ {
+ /* Remove both predictors as they predict the same
+ for both edges. */
+ dump_prediction (dump_file, existing->ep_predictor,
+ pred->ep_probability, bb,
+ EDGE_PAIR_DUPLICATE,
+ existing->ep_edge);
+ dump_prediction (dump_file, pred->ep_predictor,
+ pred->ep_probability, bb,
+ EDGE_PAIR_DUPLICATE,
+ pred->ep_edge);
+
+ remove.add (existing);
+ remove.add (pred);
+ }
+ }
+
+ edge_prediction **slot2 = s.find_slot (pred, INSERT);
+ *slot2 = pred;
+ }
+
+ /* Step 2: Remove predictors. */
+ filter_predictions (preds, not_removed_prediction_p, &remove);
+ }
+}
+
/* Combine predictions into single probability and store them into CFG.
Remove now useless prediction entries.
If DRY_RUN is set, only produce dumps and do not modify profile. */
@@ -935,7 +1077,10 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
if (dump_file)
fprintf (dump_file, "Predictions for bb %i\n", bb->index);
+ prune_predictions_for_bb (bb);
+
edge_prediction **preds = bb_predictions->get (bb);
+
if (preds)
{
/* We implement "first match" heuristics and use probability guessed
@@ -1001,18 +1146,18 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
first_match = true;
if (!found)
- dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_NO_PREDICTION, combined_probability, bb);
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability, bb,
- !first_match);
+ !first_match ? NONE : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability, bb,
- first_match);
+ first_match ? NONE : IGNORED);
}
if (first_match)
combined_probability = best_probability;
- dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb);
if (preds)
{
@@ -1021,10 +1166,9 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
enum br_predictor predictor = pred->ep_predictor;
int probability = pred->ep_probability;
- if (pred->ep_edge != EDGE_SUCC (bb, 0))
- probability = REG_BR_PROB_BASE - probability;
dump_prediction (dump_file, predictor, probability, bb,
- !first_match || best_predictor == predictor);
+ (!first_match || best_predictor == predictor)
+ ? NONE : IGNORED, pred->ep_edge);
}
}
clear_bb_predictions (bb);
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-1.C b/gcc/testsuite/g++.dg/predict-loop-exit-1.C
index 357397f..88262eb 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-1.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-1.C
@@ -9,5 +9,5 @@ void test() {
return;
}
-/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 2 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 3 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 3 "profile_estimate"} } */
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-2.C b/gcc/testsuite/g++.dg/predict-loop-exit-2.C
index 172fab1..15e9866 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-2.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-2.C
@@ -9,5 +9,5 @@ void test() {
return;
}
-/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 1 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 2 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 1 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-3.C b/gcc/testsuite/g++.dg/predict-loop-exit-3.C
index e6ceec8..61af84b 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-3.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-3.C
@@ -9,5 +9,5 @@ void test() {
return;
}
-/* { dg-final { scan-tree-dump-times "extra loop exit heuristics:" 2 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "loop exit heuristics:" 3 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "extra loop exit heuristics of edge\[^:\]*:" 2 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop exit heuristics of edge\[^:\]*:" 3 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-1.c b/gcc/testsuite/gcc.dg/predict-1.c
index 94f6b019..d0924f2 100644
--- a/gcc/testsuite/gcc.dg/predict-1.c
+++ b/gcc/testsuite/gcc.dg/predict-1.c
@@ -23,4 +23,4 @@ void foo (int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 2.0%" 5 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*: 2.0%" 5 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-2.c b/gcc/testsuite/gcc.dg/predict-2.c
index f2fc49d..3011686 100644
--- a/gcc/testsuite/gcc.dg/predict-2.c
+++ b/gcc/testsuite/gcc.dg/predict-2.c
@@ -23,4 +23,4 @@ void foo (int base, int bound)
}
}
-/* { dg-final { scan-tree-dump-not "loop iv compare heuristics" "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-not "loop iv compare heuristics of edge\[^:\]*:" "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-3.c b/gcc/testsuite/gcc.dg/predict-3.c
index 08db59a..6768c36 100644
--- a/gcc/testsuite/gcc.dg/predict-3.c
+++ b/gcc/testsuite/gcc.dg/predict-3.c
@@ -25,4 +25,4 @@ void foo (int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 98.0%" 3 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*:: 98.0%" 3 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-4.c b/gcc/testsuite/gcc.dg/predict-4.c
index 3e7fb74..5779da3 100644
--- a/gcc/testsuite/gcc.dg/predict-4.c
+++ b/gcc/testsuite/gcc.dg/predict-4.c
@@ -15,4 +15,4 @@ void foo (int bound)
}
}
-/* { dg-final { scan-tree-dump "loop iv compare heuristics: 50.0%" "profile_estimate"} } */
+/* { dg-final { scan-tree-dump "loop iv compare heuristics of edge\[^:\]*: 50.0%" "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-5.c b/gcc/testsuite/gcc.dg/predict-5.c
index 32178a8..56ada30 100644
--- a/gcc/testsuite/gcc.dg/predict-5.c
+++ b/gcc/testsuite/gcc.dg/predict-5.c
@@ -21,4 +21,4 @@ void foo (int base, int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 98.0%" 4 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*: 98.0%" 4 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-6.c b/gcc/testsuite/gcc.dg/predict-6.c
index 16ad16f..9ed41ed 100644
--- a/gcc/testsuite/gcc.dg/predict-6.c
+++ b/gcc/testsuite/gcc.dg/predict-6.c
@@ -21,4 +21,4 @@ void foo (int base, int bound)
}
}
-/* { dg-final { scan-tree-dump-times "loop iv compare heuristics: 2.0%" 4 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics of edge\[^:\]*: 2.0%" 4 "profile_estimate"} } */
diff --git a/gcc/testsuite/gcc.dg/predict-7.c b/gcc/testsuite/gcc.dg/predict-7.c
index a0ea37b..fe34ca5 100644
--- a/gcc/testsuite/gcc.dg/predict-7.c
+++ b/gcc/testsuite/gcc.dg/predict-7.c
@@ -13,4 +13,4 @@ void foo (int base)
bar (i);
}
-/* { dg-final { scan-tree-dump-times "loop branch heuristics" 0 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop branch heuristics of edge\[^:\]*" 0 "profile_estimate"} } */
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning)
2016-06-09 11:24 ` Martin Liška
@ 2016-06-12 11:55 ` Jan-Benedict Glaw
2016-06-13 7:25 ` [BUILDROBOT] MPS430 build problem due to new enum Martin Liška
2016-06-13 8:47 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan Hubicka
0 siblings, 2 replies; 14+ messages in thread
From: Jan-Benedict Glaw @ 2016-06-12 11:55 UTC (permalink / raw)
To: Martin Liška; +Cc: Jan Hubicka, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 3139 bytes --]
Hi Martin,
On Thu, 2016-06-09 13:24:10 +0200, Martin Liška <mliska@suse.cz> wrote:
> On 06/08/2016 02:41 PM, Jan Hubicka wrote:
> > Adding hash for this prupose is bit of an overkill (there are
> > definitly cheaper ways of solving so), but it will hardly affect compile
> > time, so the pathc is OK.
>
> Sending the final version where I added comments and I also changed
> dump scanning to cover the new dump format.
I just noticed a build problem my Build Robot found
(http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=569576):
g++ -fno-PIE -c -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common -DHAVE_CONFIG_H -I. -I. -I/scratch/4/jbglaw/regular/repos/gcc/gcc -I/scratch/4/jbglaw/regular/repos/gcc/gcc/. -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../include -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libcpp/include -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libdecnumber -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libbacktrace -o predict.o -MT predict.o -MMD -MP -MF ./.deps/predict.TPo /scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c
/scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c:62:3: error: redeclaration of ‘NONE’
NONE,
^
In file included from ./options.h:8:0,
from ./tm.h:16,
from /scratch/4/jbglaw/regular/repos/gcc/gcc/backend.h:28,
from /scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c:33:
/scratch/4/jbglaw/regular/repos/gcc/gcc/config/msp430/msp430-opts.h:25:3: note: previous declaration ‘msp430_hwmult_types NONE’
NONE,
^
/scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c:743:23: error: could not convert ‘NONE’ from ‘msp430_hwmult_types’ to ‘predictor_reason’
edge ep_edge = NULL)
^
/scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c: In function ‘void combine_predictions_for_insn(rtx_insn*, basic_block)’:
/scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c:863:32: error: cannot convert ‘msp430_hwmult_types’ to ‘predictor_reason’ for argument ‘5’ to ‘void dump_prediction(FILE*, br_predictor, int, basic_block, predictor_reason, edge)’
combined_probability, bb);
^
/scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c:867:36: warning: enumeral mismatch in conditional expression: ‘msp430_hwmult_types’ vs ‘predictor_reason’ [-Wenum-compare]
bb, !first_match ? NONE : IGNORED);
^
[...]
The new `NONE' from your enum clashes with a NONE used in a MSP430
private enum.
MfG, JBG
--
Jan-Benedict Glaw jbglaw@lug-owl.de +49-172-7608481
Signature of: They that give up essential liberty to obtain temporary safety,
the second : deserve neither liberty nor safety. (Ben Franklin)
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [BUILDROBOT] MPS430 build problem due to new enum
2016-06-12 11:55 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan-Benedict Glaw
@ 2016-06-13 7:25 ` Martin Liška
2016-06-13 8:47 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan Hubicka
1 sibling, 0 replies; 14+ messages in thread
From: Martin Liška @ 2016-06-13 7:25 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 304 bytes --]
On 06/12/2016 01:55 PM, Jan-Benedict Glaw wrote:
> The new `NONE' from your enum clashes with a NONE used in a MSP430
> private enum.
>
> MfG, JBG
Hi.
Thanks for having heads up, I've been testing following patch. The patch
survives with --target=msp430-elf.
Ready after it finishes?
Thanks,
Martin
[-- Attachment #2: 0001-Change-enum-value-to-not-to-clash-with-a-MSP430-priv.patch --]
[-- Type: text/x-patch, Size: 2637 bytes --]
From 540c82e618ef6b38b69160c77533705d4e160895 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 13 Jun 2016 09:20:10 +0200
Subject: [PATCH] Change enum value to not to clash with a MSP430 private enum
gcc/ChangeLog:
2016-06-13 Martin Liska <mliska@suse.cz>
* predict.c (enum predictor_reason): Rename NONE to VALID.
(combine_predictions_for_insn): Likewise.
(combine_predictions_for_bb): Likewise.
---
gcc/predict.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/gcc/predict.c b/gcc/predict.c
index 0fa8c5b..e1d161a 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -59,7 +59,7 @@ along with GCC; see the file COPYING3. If not see
enum predictor_reason
{
- NONE,
+ VALID,
IGNORED,
SINGLE_EDGE_DUPLICATE,
EDGE_PAIR_DUPLICATE
@@ -739,7 +739,7 @@ invert_br_probabilities (rtx insn)
static void
dump_prediction (FILE *file, enum br_predictor predictor, int probability,
- basic_block bb, enum predictor_reason reason = NONE,
+ basic_block bb, enum predictor_reason reason = VALID,
edge ep_edge = NULL)
{
edge e = ep_edge;
@@ -864,9 +864,9 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability,
- bb, !first_match ? NONE : IGNORED);
+ bb, !first_match ? VALID : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability,
- bb, first_match ? NONE: IGNORED);
+ bb, first_match ? VALID : IGNORED);
}
if (first_match)
@@ -883,7 +883,7 @@ combine_predictions_for_insn (rtx_insn *insn, basic_block bb)
dump_prediction (dump_file, predictor, probability, bb,
(!first_match || best_predictor == predictor)
- ? NONE : IGNORED);
+ ? VALID : IGNORED);
*pnote = XEXP (*pnote, 1);
}
else
@@ -1150,9 +1150,9 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
else
{
dump_prediction (dump_file, PRED_DS_THEORY, combined_probability, bb,
- !first_match ? NONE : IGNORED);
+ !first_match ? VALID : IGNORED);
dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability, bb,
- first_match ? NONE : IGNORED);
+ first_match ? VALID : IGNORED);
}
if (first_match)
@@ -1168,7 +1168,7 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
dump_prediction (dump_file, predictor, probability, bb,
(!first_match || best_predictor == predictor)
- ? NONE : IGNORED, pred->ep_edge);
+ ? VALID : IGNORED, pred->ep_edge);
}
}
clear_bb_predictions (bb);
--
2.8.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning)
2016-06-12 11:55 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan-Benedict Glaw
2016-06-13 7:25 ` [BUILDROBOT] MPS430 build problem due to new enum Martin Liška
@ 2016-06-13 8:47 ` Jan Hubicka
2016-06-13 10:01 ` [BUILDROBOT] MPS430 build problem due to new enum Martin Liška
1 sibling, 1 reply; 14+ messages in thread
From: Jan Hubicka @ 2016-06-13 8:47 UTC (permalink / raw)
To: Jan-Benedict Glaw; +Cc: Martin Liška, Jan Hubicka, gcc-patches
> Hi Martin,
>
> On Thu, 2016-06-09 13:24:10 +0200, Martin Liška <mliska@suse.cz> wrote:
> > On 06/08/2016 02:41 PM, Jan Hubicka wrote:
> > > Adding hash for this prupose is bit of an overkill (there are
> > > definitly cheaper ways of solving so), but it will hardly affect compile
> > > time, so the pathc is OK.
> >
> > Sending the final version where I added comments and I also changed
> > dump scanning to cover the new dump format.
>
> I just noticed a build problem my Build Robot found
> (http://toolchain.lug-owl.de/buildbot/show_build_details.php?id=569576):
>
> g++ -fno-PIE -c -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common -DHAVE_CONFIG_H -I. -I. -I/scratch/4/jbglaw/regular/repos/gcc/gcc -I/scratch/4/jbglaw/regular/repos/gcc/gcc/. -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../include -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libcpp/include -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libdecnumber -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I/scratch/4/jbglaw/regular/repos/gcc/gcc/../libbacktrace -o predict.o -MT predict.o -MMD -MP -MF ./.deps/predict.TPo /scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c
> /scratch/4/jbglaw/regular/repos/gcc/gcc/predict.c:62:3: error: redeclaration of âNONEâ
> NONE,
Hmm, namespace conflict. I guess renaming enum items to REASON_* should solve it easily.
Or we can add a namespace.
Martin, both variants of fix are pre-approved.
Honza
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [BUILDROBOT] MPS430 build problem due to new enum
2016-06-13 8:47 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan Hubicka
@ 2016-06-13 10:01 ` Martin Liška
0 siblings, 0 replies; 14+ messages in thread
From: Martin Liška @ 2016-06-13 10:01 UTC (permalink / raw)
To: gcc-patches; +Cc: Jan Hubicka
On 06/13/2016 10:46 AM, Jan Hubicka wrote:
> Hmm, namespace conflict. I guess renaming enum items to REASON_* should solve it easily.
> Or we can add a namespace.
>
> Martin, both variants of fix are pre-approved.
> Honza
OK, I've just installed (r237370) a patch that prefixes all enum values.
Martin
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2016-06-13 10:01 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-02 11:57 [PATCH 0/2] Deduplicate edge predictors marxin
2016-06-02 11:57 ` [PATCH 1/2] Introduce filtering for edge_predictions marxin
2016-06-02 11:57 ` [PATCH 2/2] Add edge predictions pruning marxin
2016-06-08 12:25 ` Martin Liška
2016-06-08 12:41 ` Jan Hubicka
2016-06-09 11:24 ` Martin Liška
2016-06-12 11:55 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan-Benedict Glaw
2016-06-13 7:25 ` [BUILDROBOT] MPS430 build problem due to new enum Martin Liška
2016-06-13 8:47 ` [BUILDROBOT] MPS430 build problem due to new enum (was: [PATCH 2/2] Add edge predictions pruning) Jan Hubicka
2016-06-13 10:01 ` [BUILDROBOT] MPS430 build problem due to new enum Martin Liška
2016-06-08 12:26 ` [PATCH 3/N] Add sorting support to analyze_brprob script Martin Liška
2016-06-08 15:02 ` Jan Hubicka
2016-06-08 12:29 ` [PATCH 4/N] Add new analyze_brprob_spec.py script Martin Liška
2016-06-08 15:12 ` Jan Hubicka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).