diff options
Diffstat (limited to 'recipes-microblaze/gcc/files/gcc-Cherry-pick-mainline-patch-to-resolve-MB-k.patch')
-rw-r--r-- | recipes-microblaze/gcc/files/gcc-Cherry-pick-mainline-patch-to-resolve-MB-k.patch | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/recipes-microblaze/gcc/files/gcc-Cherry-pick-mainline-patch-to-resolve-MB-k.patch b/recipes-microblaze/gcc/files/gcc-Cherry-pick-mainline-patch-to-resolve-MB-k.patch new file mode 100644 index 00000000..1cdc4029 --- /dev/null +++ b/recipes-microblaze/gcc/files/gcc-Cherry-pick-mainline-patch-to-resolve-MB-k.patch @@ -0,0 +1,110 @@ +Subject: Cherry-pick mainline patch to resolve MB kernel panic + +Cherry-pick backend optimization patch from gcc HEAD which 'resolves' a kernel +panic for microblaze when compiled with -Os + +Upstream HEAD (soon to be gcc 4.9) does not exhibt this error any longer, +and this patch when applied as a workaround on the 4.8 branch also hides the +kernel panic resulting from incorrect branch-delay slot filling. + + * tree-ssa-threadedge.c (thread_around_empty_block): Remove + checks for the number of predecessors and successors allowed. + * tree-ssa-threadupdate.c (mark_threaded_blocks): Ignore requests + which require copying a joiner block if there is a request which + is a subpath that requires no joiner block copying. + +Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> +Upstream-Status: Backport +--- + gcc/tree-ssa-threadedge.c | 8 ------- + gcc/tree-ssa-threadupdate.c | 49 ++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 44 insertions(+), 13 deletions(-) + +diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c +index b31e961..ab58ae8 100644 +--- a/gcc/tree-ssa-threadedge.c ++++ b/gcc/tree-ssa-threadedge.c +@@ -761,14 +761,6 @@ thread_around_empty_block (edge taken_edge, + gimple stmt; + tree cond; + +- /* This block must have a single predecessor (E->dest). */ +- if (!single_pred_p (bb)) +- return NULL; +- +- /* This block must have more than one successor. */ +- if (single_succ_p (bb)) +- return NULL; +- + /* This block can have no PHI nodes. This is overly conservative. */ + if (!gsi_end_p (gsi_start_phis (bb))) + return NULL; +diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c +index 0e4cbc9..cf8df8e 100644 +--- a/gcc/tree-ssa-threadupdate.c ++++ b/gcc/tree-ssa-threadupdate.c +@@ -1146,17 +1146,56 @@ mark_threaded_blocks (bitmap threaded_blocks) + edge e; + edge_iterator ei; + ++ /* It is possible to have jump threads in which one is a subpath ++ of the other. ie, (A, B), (B, C), (C, D) where B is a joiner ++ block and (B, C), (C, D) where no joiner block exists. ++ ++ When this occurs ignore the jump thread request with the joiner ++ block. It's totally subsumed by the simpler jump thread request. ++ ++ This results in less block copying, simpler CFGs. More improtantly, ++ when we duplicate the joiner block, B, in this case we will create ++ a new threading opportunity that we wouldn't be able to optimize ++ until the next jump threading iteration. ++ ++ So first convert the jump thread requests which do not require a ++ joiner block. */ + for (i = 0; i < threaded_edges.length (); i += 3) + { + edge e = threaded_edges[i]; +- edge *x = XNEWVEC (edge, 2); + +- e->aux = x; +- THREAD_TARGET (e) = threaded_edges[i + 1]; +- THREAD_TARGET2 (e) = threaded_edges[i + 2]; +- bitmap_set_bit (tmp, e->dest->index); ++ if (threaded_edges[i + 2] == NULL) ++ { ++ edge *x = XNEWVEC (edge, 2); ++ ++ e->aux = x; ++ THREAD_TARGET (e) = threaded_edges[i + 1]; ++ THREAD_TARGET2 (e) = NULL; ++ bitmap_set_bit (tmp, e->dest->index); ++ } + } + ++ ++ /* Now iterate again, converting cases where we threaded through ++ a joiner block, but ignoring those where we have already ++ threaded through the joiner block. */ ++ for (i = 0; i < threaded_edges.length (); i += 3) ++ { ++ edge e = threaded_edges[i]; ++ ++ if (threaded_edges[i + 2] != NULL ++ && threaded_edges[i + 1]->aux == NULL) ++ { ++ edge *x = XNEWVEC (edge, 2); ++ ++ e->aux = x; ++ THREAD_TARGET (e) = threaded_edges[i + 1]; ++ THREAD_TARGET2 (e) = threaded_edges[i + 2]; ++ bitmap_set_bit (tmp, e->dest->index); ++ } ++ } ++ ++ + /* If optimizing for size, only thread through block if we don't have + to duplicate it or it's an otherwise empty redirection block. */ + if (optimize_function_for_size_p (cfun)) +-- +1.7.9.5 + |