Пример #1
0
/**
 * This function returns the last definition of a value.  In case
 * this value was last defined in a previous block, Phi nodes are
 * inserted.  If the part of the firm graph containing the definition
 * is not yet constructed, a dummy Phi node is returned.
 *
 * @param block   the current block
 * @param pos     the value number of the value searched
 * @param mode    the mode of this value (needed for Phi construction)
 */
static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
{
	ir_node *res = block->attr.block.graph_arr[pos];
	if (res != NULL)
		return res;

	/* in a matured block we can immediately determine the phi arguments */
	if (get_Block_matured(block)) {
		ir_graph *const irg   = get_irn_irg(block);
		int       const arity = get_irn_arity(block);
		/* no predecessors: use unknown value */
		if (arity == 0) {
			if (block == get_irg_start_block(irg)) {
				if (default_initialize_local_variable != NULL) {
					ir_node *rem = get_r_cur_block(irg);
					set_r_cur_block(irg, block);
					res = default_initialize_local_variable(irg, mode, pos - 1);
					set_r_cur_block(irg, rem);
				} else {
					res = new_r_Unknown(irg, mode);
				}
			} else {
				goto bad; /* unreachable block, use Bad */
			}
		/* one predecessor just use its value */
		} else if (arity == 1) {
			ir_node *cfgpred = get_Block_cfgpred(block, 0);
			if (is_Bad(cfgpred)) {
bad:
				res = new_r_Bad(irg, mode);
			} else {
				ir_node *cfgpred_block = get_nodes_block(cfgpred);
				res = get_r_value_internal(cfgpred_block, pos, mode);
			}
		} else {
			/* multiple predecessors construct Phi */
			res = new_rd_Phi0(NULL, block, mode, pos);
			/* enter phi0 into our variable value table to break cycles
			 * arising from set_phi_arguments */
			block->attr.block.graph_arr[pos] = res;
			res = set_phi_arguments(res, pos);
		}
	} else {
		/* in case of immature block we have to keep a Phi0 */
		res = new_rd_Phi0(NULL, block, mode, pos);
		/* enqueue phi so we can set arguments once the block matures */
		res->attr.phi.next     = block->attr.block.phis;
		block->attr.block.phis = res;
	}
	block->attr.block.graph_arr[pos] = res;
	return res;
}
Пример #2
0
static ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc)
{
	ir_graph *const res = alloc_graph();

	/* Inform statistics here, as blocks will be already built on this graph. */
	hook_new_graph(res, ent);

	/* graphs are in construction mode by default */
	add_irg_constraints(res, IR_GRAPH_CONSTRAINT_CONSTRUCTION);
	irg_set_nloc(res, n_loc);

	res->irg_pinned_state  = op_pin_state_pinned;
	res->callee_info_state = irg_callee_info_none;
	res->mem_disambig_opt  = aa_opt_inherited;

	/*-- Type information for the procedure of the graph --*/
	res->ent = ent;
	if (ent)
		set_entity_irg(ent, res);

	/*--  a class type so that it can contain "inner" methods as in Pascal. --*/
	res->frame_type = new_type_frame();

	/* the Anchor node must be created first */
	res->anchor = new_r_Anchor(res);

	/*-- Nodes needed in every graph --*/
	set_irg_end_block(res, new_r_immBlock(res));
	set_irg_end(res, new_r_End(res, 0, NULL));

	ir_node *const start_block = new_r_Block_noopt(res, 0, NULL);
	set_irg_start_block(res, start_block);
	set_irg_no_mem(res, new_r_NoMem(res));

	res->index = get_irp_new_irg_idx();
#ifdef DEBUG_libfirm
	res->graph_nr = get_irp_new_node_nr();
#endif

	set_r_cur_block(res, start_block);

	return res;
}