This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Clean up unreachable blocks after local_alloc


the following test case failure on s390x-ibm-linux:
FAIL: pr83 -O3 compilation from bytecode
is caused by an abort in set_up_bb_rts_numbers (global.c) because an
unreachable basic block was present in the CFG, and
flow_reverse_top_sort_order_compute cannot cope with that.

The block was made unreachable by local_alloc, and nobody would clean
up unreachable blocks between local and global alloc.  The patch below
fixes this by adding a call to delete_unreachable_blocks after local_alloc,
if it did modify jumps.

The specific situation that caused a block to become unreachable by
local_alloc is as follows: We started out with an indirect jump via
a register with was set to one of two labels (this is the result of
translating Java bytecode corresponding to a try-finally block).
After GCSE the block containing one of those two sets was deleted as
unreachable, leaving only a single set.  (However the label, and thus
the block, referred to by the now deleted set was not removed, because
it was marked as forced_label.  Since we still have an indirect jump,
that block still counts as potential successor of the block containing
the indirect jump, and thus as reachable.)

Local alloc then recognizes the register as being equivalent to the
first value, and replaces the indirect jump with a direct jump to that
label.  Now that the indirect jump is gone (which was the only indirect
jump in the function), the block starting the with forced label
suddenly becomes unreachable ...

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux,
fixes the above test case regression.

OK for mainline?



	* passes.c (rest_of_handle_old_regalloc): Delete unreachable blocks
	if local_alloc modified jumps.

Index: gcc/passes.c
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.58
diff -c -p -r2.58 passes.c
*** gcc/passes.c	24 Nov 2004 11:32:23 -0000	2.58
--- gcc/passes.c	29 Nov 2004 20:32:06 -0000
*************** rest_of_handle_old_regalloc (void)
*** 502,507 ****
--- 502,508 ----
        rebuild_jump_labels (get_insns ());
        purge_all_dead_edges (0);
+       delete_unreachable_blocks ();
        timevar_pop (TV_JUMP);
  Dr. Ulrich Weigand
  Linux on zSeries Development

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]