예제 #1
0
파일: rm_bads.c 프로젝트: MatzeB/libfirm
/**
 * Block-walker, remove Bad block predecessors and shorten Phis.
 * Phi links must be up-to-date.
 */
static void block_remove_bads(ir_node *block)
{
	/* 1. Create a new block without Bad inputs */
	ir_graph  *irg     = get_irn_irg(block);
	const int  max     = get_Block_n_cfgpreds(block);
	ir_node  **new_in  = ALLOCAN(ir_node*, max);
	unsigned   new_max = 0;
	for (int i = 0; i < max; ++i) {
		ir_node *const block_pred = get_Block_cfgpred(block, i);
		if (!is_Bad(block_pred)) {
			new_in[new_max++] = block_pred;
		}
	}

	/* If the end block is unreachable, it might have zero predecessors. */
	if (new_max == 0) {
		ir_node *end_block = get_irg_end_block(irg);
		if (block == end_block) {
			set_irn_in(block, new_max, new_in);
			return;
		}
	}

	dbg_info  *dbgi         = get_irn_dbg_info(block);
	ir_node   *new_block    = new_rd_Block(dbgi, irg, new_max, new_in);
	ir_entity *block_entity = get_Block_entity(block);
	set_Block_entity(new_block, block_entity);

	/* 2. Remove inputs on Phis, where the block input is Bad. */
	for (ir_node *phi = get_Block_phis(block), *next; phi != NULL; phi = next) {
		next = get_Phi_next(phi);

		assert(get_irn_arity(phi) == max);

		unsigned j = 0;
		foreach_irn_in(phi, i, pred) {
			ir_node *const block_pred = get_Block_cfgpred(block, i);
			if (!is_Bad(block_pred)) {
				new_in[j++] = pred;
			}
		}
		assert(j == new_max);

		/* shortcut if only 1 phi input is left */
		if (new_max == 1) {
			ir_node *new_node = new_in[0];
			/* can happen inside unreachable endless loops */
			if (new_node == phi)
				return;
			if (get_Phi_loop(phi))
				remove_keep_alive(phi);
			exchange(phi, new_node);
		} else {
			set_irn_in(phi, new_max, new_in);
		}
	}
예제 #2
0
파일: cdep.c 프로젝트: lu-zero/libfirm
/**
 * Pre-block-walker: calculate the control dependence
 */
static void cdep_pre(ir_node *node, void *ctx)
{
	(void)ctx;
	for (int i = get_Block_n_cfgpreds(node); i-- > 0; ) {
		ir_node *pred = get_Block_cfgpred_block(node, i);
		if (is_Bad(pred))
			continue;

		ir_node *pdom = get_Block_ipostdom(pred);
		for (ir_node *dependee = node; dependee != pdom;
		     dependee = get_Block_ipostdom(dependee)) {
			assert(!is_Bad(pdom));
			add_cdep(dependee, pred);
		}
	}
}
예제 #3
0
/**
 * Get the predecessor block.
 */
static ir_node *get_block_n(const ir_node *block, int pos)
{
	ir_node *cfgpred = get_cf_op(get_Block_cfgpred(block, pos));
	if (is_Bad(cfgpred))
		return NULL;
	return get_nodes_block(cfgpred);
}
예제 #4
0
int Socket::write( const char* pBuf, int nLen,int p_itime_out)
{
	int	  iLeft = nLen,i_timeleft=p_itime_out;
  time_t  t_start = time(NULL);
	while( iLeft > 0 )
	{
		int	i = ::send( m_nSock, pBuf, iLeft,0);
		if( i <= 0 )   return -1;
		iLeft -= i;
		pBuf += i;
		if(iLeft <=0|| i_timeleft<=0) break;
					
		do
		{ 
			fd_set events;
			struct timeval tm;
			FD_ZERO(&events);
			FD_SET(m_nSock, &events);
			tm.tv_sec = i_timeleft;
			tm.tv_usec = 0;
			while ((i = select(m_nSock+1, NULL,&events, NULL, &tm)) < 0 
				&& errno == EINTR);
			if( i < 0 ) return	-1;
			if(FD_ISSET(m_nSock,&events)) break;
			i_timeleft = t_start+p_itime_out - time(NULL);
			if(i==0&&is_Bad()) 	return -1;
			}
		while (i_timeleft >0) ;
	}
	return ( nLen - iLeft);
}
예제 #5
0
파일: return.c 프로젝트: qznc/libfirm
/**
 * Check, whether a Return can be moved on block upwards.
 *
 * In a block with a Return, all live nodes must be linked
 * with the Return, otherwise they are dead (because the Return leaves
 * the graph, so no more users of the other nodes can exists.
 *
 * We can move a Return, if its predecessors are Phi nodes or
 * comes from another block. In the later case, it is always possible
 * to move the Return one block up, because the predecessor block must
 * dominate the Return block (SSA) and then it dominates the predecessor
 * block of the Return block as well.
 *
 * All predecessors of the Return block must be Jmp's of course, or we
 * cannot move it up, so we add blocks if needed.
 */
static bool can_move_ret(ir_node *ret)
{
    ir_node *retbl = get_nodes_block(ret);
    int i, n = get_irn_arity(ret);

    for (i = 0; i < n; ++i) {
        ir_node *pred = get_irn_n(ret, i);

        if (! is_Phi(pred) && retbl == get_nodes_block(pred)) {
            /* first condition failed, found a non-Phi predecessor
             * then is in the Return block */
            return false;
        }
    }

    /* check, that predecessors are Jmps */
    n = get_Block_n_cfgpreds(retbl);
    /* we cannot move above a labeled block, as this might kill the block */
    if (n <= 1 || get_Block_entity(retbl) != NULL)
        return false;
    for (i = 0; i < n; ++i) {
        ir_node *pred = get_Block_cfgpred(retbl, i);

        pred = skip_Tuple(pred);
        if (! is_Jmp(pred) && !is_Bad(pred)) {
            /* simply place a new block here */
            ir_graph *irg  = get_irn_irg(retbl);
            ir_node *block = new_r_Block(irg, 1, &pred);
            ir_node *jmp   = new_r_Jmp(block);
            set_Block_cfgpred(retbl, i, jmp);
        }
    }
    return true;
}
예제 #6
0
파일: dags.c 프로젝트: lu-zero/libfirm
/**
 * a vcg attribute hook
 */
static int stat_dag_mark_hook(FILE *F, const ir_node *n, const ir_node *l)
{
	static const char *colors[] = { "purple", "pink", "lightblue", "orange", "khaki", "orchid", "lilac", "turquoise" };
	dag_entry_t *entry;

	/* do not count Bad / NoMem */
	if (l) {
		if (is_NoMem(l) || is_Bad(l))
			return DEFAULT_RET;

		/* check for additional options */
		if (mark_options & FIRMSTAT_LOAD_IS_LEAVE && is_Load(n))
			return DEFAULT_RET;

		if (mark_options & FIRMSTAT_CALL_IS_LEAVE && is_Call(n))
			return DEFAULT_RET;
	}

	entry = get_irn_dag_entry(n);
	if (! entry)
		return DEFAULT_RET;

	fprintf(F, "color: %s info3: \"DAG id: %u\"", colors[entry->id & 7], entry->id);

	/* I know the color! */
	return COLOR_RET;
}
예제 #7
0
/* Walks back from n until it finds a real cf op. */
static ir_node *get_cf_op(ir_node *n)
{
	while (!is_cfop(n) && !is_fragile_op(n) && !is_Bad(n)) {
		n = skip_Tuple(n);
		n = skip_Proj(n);
	}
	return n;
}
예제 #8
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;
}
예제 #9
0
파일: return.c 프로젝트: qznc/libfirm
/*
 * Normalize the Returns of a graph by moving
 * the Returns upwards as much as possible.
 * This might be preferred for code generation.
 *
 * In pseudocode, it means:
 *
 * if (a)
 *   res = b;
 * else
 *   res = c;
 * return res;
 *
 * is transformed into
 *
 * if (a)
 *   return b;
 * else
 *   return c;
 */
void normalize_n_returns(ir_graph *irg)
{
    int i, j, n;
    ir_node  *list     = NULL;
    ir_node  *final    = NULL;
    unsigned  n_rets   = 0;
    unsigned  n_finals = 0;
    ir_node  *endbl    = get_irg_end_block(irg);
    int       n_ret_vals;
    ir_node **in;
    ir_node  *end;

    /*
     * First, link all returns:
     * These must be predecessors of the endblock.
     * Place Returns that can be moved on list, all others
     * on final.
     */
    n = get_Block_n_cfgpreds(endbl);
    for (i = 0; i < n; ++i) {
        ir_node *ret = get_Block_cfgpred(endbl, i);

        if (is_Bad(ret)) {
            continue;
        } else if (is_Return(ret) && can_move_ret(ret)) {
            /*
             * Ok, all conditions met, we can move this Return, put it
             * on our work list.
             */
            set_irn_link(ret, list);
            list = ret;
            ++n_rets;
        } else {
            /* Put all nodes that are not changed on the final list. */
            set_irn_link(ret, final);
            final = ret;
            ++n_finals;
        }
    }