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 )