aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordalej <dalej@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-28 19:40:48 +0000
committerdalej <dalej@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-28 19:40:48 +0000
commit516d9d2d1421dbafa970cd7e73dd013b56d38907 (patch)
tree2851263ab7fbe143c9b3b63dabf1b540977e2b2b
parent7b66c36145608816d35f3406d18824df3ce5ae1c (diff)
2005-10-28 Dale Johannesen <dalej@apple.com>apple/gcc-5246
Radar 4318818 * varasm.c (output_constructor): Do not check DECL_BIT_FIELD when reversing initializer list for types with reversed_flag set. 2005-10-28 Dale Johannesen <dalej@apple.com> Radar 4319602 * cfgloopmanip.c (create_loop_notes): Add code to move code logically inside a loop but physically outside, to a place physically inside. * ifcvt.c (find_if_case_1): Adjust cost test for ppc. (find_if_case_2): Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/apple-200511-release-branch@105950 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.apple-ppc16
-rw-r--r--gcc/cfgloopmanip.c147
-rw-r--r--gcc/ifcvt.c12
-rw-r--r--gcc/varasm.c2
4 files changed, 175 insertions, 2 deletions
diff --git a/gcc/ChangeLog.apple-ppc b/gcc/ChangeLog.apple-ppc
index 4bc6788e332..b0fe6cf9e65 100644
--- a/gcc/ChangeLog.apple-ppc
+++ b/gcc/ChangeLog.apple-ppc
@@ -1,3 +1,19 @@
+2005-10-28 Dale Johannesen <dalej@apple.com>
+
+ Radar 4318818
+ * varasm.c (output_constructor): Do not check
+ DECL_BIT_FIELD when reversing initializer list for
+ types with reversed_flag set.
+
+2005-10-28 Dale Johannesen <dalej@apple.com>
+
+ Radar 4319602
+ * cfgloopmanip.c (create_loop_notes): Add code to move
+ code logically inside a loop but physically outside,
+ to a place physically inside.
+ * ifcvt.c (find_if_case_1): Adjust cost test for ppc.
+ (find_if_case_2): Ditto.
+
2005-10-21 Dale Johannesen <dalej@apple.com>
* opts.c (set_flags_from_O): Revert 10-17 change.
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index c07571014af..e6f651ca333 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1279,7 +1279,22 @@ loop_split_edge_with (edge e, rtx insns)
return new_bb;
}
-/* Uses the natural loop discovery to recreate loop notes. */
+/* APPLE LOCAL begin 4203984 */
+/* Uses the natural loop discovery to recreate loop notes.
+
+ The RTL loop optimizer is sensitive to lexical order of
+ blocks, unfortunately. For now, look for cases where there
+ is a jump from a loop into a region that's not between the
+ header and the latch, and all paths from there wind up going
+ back inside the loop (similar to Fortran 66 Extended DO).
+ (The "logically inside the loop" property falls out of the
+ dominator computation that is already being done.)
+ Move the blocks involved in that between the header/latch
+ if there is a place to do that (i.e. unconditional branch
+ within the loop). This may result in branch-to-next-insn
+ in some cases which will get cleaned up later. More
+ rearrangements along this line are possible. */
+/* APPLE LOCAL end 4203984 */
void
create_loop_notes (void)
{
@@ -1288,6 +1303,8 @@ create_loop_notes (void)
struct loop *loop;
basic_block *first, *last, bb, pbb;
struct loop **stack, **top;
+ /* APPLE LOCAL 4203984 */
+ unsigned int i;
#ifdef ENABLE_CHECKING
/* Verify that there really are no loop notes. */
@@ -1300,6 +1317,134 @@ create_loop_notes (void)
free_dominance_info (CDI_DOMINATORS);
if (loops.num > 1)
{
+ /* APPLE LOCAL begin 4203984 */
+ basic_block * shadow;
+ signed char * in_body;
+ /* Make a pass to find a spot in each loop where we might be able
+ to move code that belongs in that loop, i.e. a block ending
+ in an unconditional branch. Could be extended for noreturn
+ calls, etc. */
+ shadow = xcalloc (loops.num, sizeof (basic_block));
+ /* in_body: 0 before header or latch seen, 1 after header and before latch,
+ -1 otherwise (which includes case where latch precedes header).
+ When header==latch there is no zone where in_body==1. */
+ in_body = xcalloc (loops.num, sizeof (signed char));
+ FOR_EACH_BB (bb)
+ {
+ loop = bb->loop_father;
+ if (loop->num == 0)
+ continue;
+ if (bb == loop->header && in_body[loop->num] == 0)
+ in_body[loop->num] = 1;
+ if (bb == loop->latch)
+ in_body[loop->num] = -1;
+ if (in_body[loop->num] == 1
+ && shadow[loop->num] == 0
+ && BB_END (bb)
+ && JUMP_P (BB_END (bb))
+ && onlyjump_p (BB_END (bb))
+ && any_uncondjump_p (BB_END (bb)))
+ shadow[loop->num] = bb;
+ }
+ /* Check for loops where the header and/or latch are not marked as part of the
+ loop. Exceptionally twisted CFGs can produce these, and this code won't
+ work with them. */
+ for (i = 1; i < loops.num; i++)
+ {
+ loop = loops.parray[i];
+ if (loop->header->loop_father != loop
+ || loop->latch->loop_father != loop)
+ shadow[i] = 0;
+ }
+ /* Make a pass to find code outside the loop that belongs inside, and
+ moves it in. */
+ memset (in_body, 0, sizeof(char) * loops.num);
+ FOR_EACH_BB (bb)
+ {
+ loop = bb->loop_father;
+ if (loop->num == 0 || shadow[loop->num] == 0)
+ continue;
+ if (bb == loop->header)
+ {
+ if (in_body[loop->num] == 0)
+ in_body[loop->num] = 1;
+ }
+ if (bb == loop->latch)
+ in_body[loop->num] = -1;
+ if (bb != loop->header && bb != loop->latch && in_body[loop->num] != 1)
+ {
+ rtx last_insn, table;
+ basic_block next_bb = bb->next_bb;
+ basic_block prev_bb = bb->prev_bb;
+ basic_block restart_bb = prev_bb;
+ edge e = find_edge (bb, next_bb);
+ edge e2 = find_edge (prev_bb, bb);
+ /* If all exits from bb are non-fallthrough, we can just move it.
+ If there is a fallthrough and it belongs to the same loop we
+ do, the next iteration will move it up to follow bb in its new
+ location, and again we can just move it. If fallthrough leads
+ outside the loop, add an unconditional branch to the end of bb,
+ or a new block containing a branch to the fallthrough block if
+ there is already a conditional branch at the end of bb; that
+ gets us into one of the first two cases. Creating
+ a new block hoses the dominator-based info stored in loops->cfg;
+ however, that is not used anywhere. */
+ if (e && (e->flags & EDGE_FALLTHRU) && next_bb->loop_father != loop)
+ {
+ basic_block new_bb;
+ /* force_nonfallthru doesn't work if the destination is EXIT_BLOCK.
+ Create a new block in between for force_nonfallthru to jump to. */
+ if (e->dest == EXIT_BLOCK_PTR)
+ {
+ new_bb = split_edge (e);
+ new_bb->loop_father = EXIT_BLOCK_PTR->loop_father;
+ new_bb->loop_depth = 0;
+ }
+ new_bb = force_nonfallthru (e);
+ if (new_bb)
+ {
+ new_bb->loop_father = loop;
+ new_bb->loop_depth = shadow[loop->num]->loop_depth;
+ }
+ }
+ /* If we have a fallthrough edge leading into this block, and the source is
+ not in the same loop as we are, we must fix up the predecessor similarly.
+ (If the predecessor is in the same loop, at this point it has been
+ moved and is no longer prev_bb but the edge is still there; we need do
+ nothing, the edge will be correct again after we move this block.
+ If the predecessor is not in the same loop and we moved it, the
+ fallthrough edge was removed earlier by the code above.) */
+ if (e2 && (e2->flags & EDGE_FALLTHRU) && prev_bb->loop_father != loop)
+ {
+ basic_block new_bb = force_nonfallthru (e2);
+ if (new_bb)
+ {
+ new_bb->loop_father = prev_bb->loop_father;
+ new_bb->loop_depth = prev_bb->loop_depth;
+ restart_bb = new_bb;
+ }
+ }
+ /* Move insns in block within insn list, with following jump
+ table and BARRIER if any. */
+ last_insn = BB_END (bb);
+ if (tablejump_p (last_insn, NULL, &table))
+ last_insn = table;
+ if (BARRIER_P (NEXT_INSN (last_insn)))
+ last_insn = NEXT_INSN (last_insn);
+ reorder_insns_nobb(BB_HEAD (bb), last_insn,
+ PREV_INSN (BB_HEAD (shadow[loop->num]->next_bb)));
+ /* Move block within block list. */
+ unlink_block (bb);
+ link_block (bb, shadow[loop->num]);
+ /* Next block to be moved will go after this one. */
+ shadow[loop->num] = bb;
+ bb = restart_bb;
+ }
+ }
+ free (in_body);
+ free (shadow);
+ /* APPLE LOCAL end 4203984 */
+
last = xcalloc (loops.num, sizeof (basic_block));
FOR_EACH_BB (bb)
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 39fced43b24..ff1e4a92691 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2929,7 +2929,13 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
test_bb->index, then_bb->index);
/* THEN is small. */
+ /* APPLE LOCAL begin 4203984 */
+#ifdef TARGET_POWERPC
+ if (! cheap_bb_rtx_cost_p (then_bb, COSTS_N_INSNS (BRANCH_COST + 1)))
+#else
if (! cheap_bb_rtx_cost_p (then_bb, COSTS_N_INSNS (BRANCH_COST)))
+#endif
+ /* APPLE LOCAL end 4203984 */
return FALSE;
/* Registers set are dead, or are predicable. */
@@ -3047,7 +3053,13 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
test_bb->index, else_bb->index);
/* ELSE is small. */
+ /* APPLE LOCAL begin 4203984 */
+#ifdef TARGET_POWERPC
+ if (! cheap_bb_rtx_cost_p (else_bb, COSTS_N_INSNS (BRANCH_COST + 1)))
+#else
if (! cheap_bb_rtx_cost_p (else_bb, COSTS_N_INSNS (BRANCH_COST)))
+#endif
+ /* APPLE LOCAL end 4203984 */
return FALSE;
/* Registers set are dead, or are predicable. */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index f12bcab0317..51115cf92d6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3999,7 +3999,7 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT size,
head;
prev = head, head = TREE_CHAIN (head))
{
- if (TREE_PURPOSE (head) && DECL_BIT_FIELD (TREE_PURPOSE (head)))
+ if (TREE_PURPOSE (head))
{
HOST_WIDE_INT pos = int_bit_position (TREE_PURPOSE (head));
/* Find next field that isn't a bitfield, or is after "head"