branches to branches before live variable analysis, so that
the back ends don't need to worry about jump threading.
+ * jit/jit-block.c, jit/jit-live.c: treat dead blocks as empty
+ when peepholing branches to the next block.
+
2004-05-15 Rhys Weatherley <rweather@southern-storm.com.au>
* tools/gen-apply.c: fix a macro generation bug for Win32 systems.
return block->ends_in_dead;
}
+/*
+ * Determine if a block is empty or is never entered.
+ */
+static int block_is_empty_or_dead(jit_block_t block)
+{
+ if(block->first_insn > block->last_insn)
+ {
+ return 1;
+ }
+ else if(!(block->entered_via_top) && !(block->entered_via_branch))
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
/*
* Determine if the next block after "block" has "label".
*/
{
return 1;
}
- if(block->first_insn < block->last_insn)
- {
- /* This block contains more than one instruction, so the
- first cannot be an unconditional branch */
- break;
- }
- else if(block->first_insn == block->last_insn)
+ if(!block_is_empty_or_dead(block))
{
- insn = block->func->builder->insns[block->first_insn];
- if(insn->opcode == JIT_OP_BR)
+ if(block->first_insn < block->last_insn)
{
- /* If the instruction branches to its next block,
- then it is equivalent to an empty block. If it
- does not, then we have to stop scanning here */
- if(!block_branches_to_next(block, (jit_label_t)(insn->dest)))
- {
- return 0;
- }
+ /* This block contains more than one instruction, so the
+ first cannot be an unconditional branch */
+ break;
}
else
{
- /* The block does not contain an unconditional branch */
- break;
+ insn = block->func->builder->insns[block->first_insn];
+ if(insn->opcode == JIT_OP_BR)
+ {
+ /* If the instruction branches to its next block,
+ then it is equivalent to an empty block. If it
+ does not, then we have to stop scanning here */
+ if(!block_branches_to_next
+ (block, (jit_label_t)(insn->dest)))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ /* The block does not contain an unconditional branch */
+ break;
+ }
}
}
block = block->next;
while(label != block->label && count > 0)
{
new_block = jit_block_from_label(block->func, label);
- while(new_block != 0 && new_block->first_insn > new_block->last_insn)
+ while(new_block != 0 && block_is_empty_or_dead(new_block))
{
/* Skip past empty blocks */
new_block = new_block->next;
jit_block_t block = func->builder->first_block;
while(block != 0)
{
+ /* If the block is never entered, then replace it with empty */
+ if(!(block->entered_via_top) && !(block->entered_via_branch))
+ {
+ block->last_insn = block->first_insn - 1;
+ }
+
+ /* Perform peephole optimization on branches to branches */
_jit_block_peephole_branch(block);
+
+ /* Compute the liveness flags for the block */
compute_liveness_for_block(block);
+
+ /* Move on to the next block in the function */
block = block->next;
}
}