Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-block.c view on Meta::CPAN
func->builder->entry_block->next = func->builder->exit_block;
func->builder->exit_block->prev = func->builder->entry_block;
return 1;
}
void
_jit_block_free(jit_function_t func)
{
jit_block_t block, next;
free_order(func);
block = func->builder->entry_block;
while(block)
{
next = block->next;
_jit_block_destroy(block);
block = next;
}
block = func->builder->deleted_blocks;
while(block)
{
next = block->next;
_jit_block_destroy(block);
block = next;
}
func->builder->entry_block = 0;
func->builder->exit_block = 0;
}
void
_jit_block_build_cfg(jit_function_t func)
{
/* Count the edges */
build_edges(func, 0);
/* Allocate memory for edges */
alloc_edges(func);
/* Actually build the edges */
build_edges(func, 1);
}
void
_jit_block_clean_cfg(jit_function_t func)
{
int index, changed;
jit_block_t block;
jit_insn_t insn;
/*
* The code below is based on the Clean algorithm described in
* "Engineering a Compiler" by Keith D. Cooper and Linda Torczon,
* section 10.3.1 "Eliminating Useless and Unreachable Code"
* (originally presented in a paper by Rob Shillner and John Lu
* http://www.cs.princeton.edu/~ras/clean.ps).
*
* Because libjit IR differs from ILOC the algorithm here has
* some differences too.
*/
if(!_jit_block_compute_postorder(func))
{
jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
}
set_address_of(func);
eliminate_unreachable(func);
loop:
changed = 0;
/* Go through blocks in post order skipping the entry and exit blocks */
for(index = 1; index < (func->builder->num_block_order - 1); index++)
{
block = func->builder->block_order[index];
if(block->num_succs == 0)
{
continue;
}
/* Take care of redundant branches that is, if possible, either
replace a branch with NOP turning it to a fallthrough case
or reduce a conditional branch to unconditional */
if(block->succs[0]->flags == _JIT_EDGE_BRANCH)
{
insn = _jit_block_get_last(block);
if(insn->opcode == JIT_OP_JUMP_TABLE)
{
/* skip jump tables, handle only branches */
continue;
}
if(block->succs[0]->dst == block->next)
{
/* Replace useless branch with NOP */
changed = 1;
insn->opcode = JIT_OP_NOP;
if(block->num_succs == 2)
{
/* For conditional branch delete the branch
edge while leaving the fallthough edge
intact */
#ifdef _JIT_BLOCK_DEBUG
printf("%d cbranch->fallthru %d\n", index, block->label);
#endif
delete_edge(func, block->succs[0]);
}
else
{
/* For unconditional branch replace the branch
edge with a fallthrough edge */
#ifdef _JIT_BLOCK_DEBUG
printf("%d ubranch->fallthru %d\n", index, block->label);
#endif
block->ends_in_dead = 0;
block->succs[0]->flags = _JIT_EDGE_FALLTHRU;
}
}
( run in 0.544 second using v1.01-cache-2.11-cpan-0068ddc7af1 )