Ejemplo n.º 1
0
	static void walk_topo_helper(ir_node* irn, std::function<void (ir_node*, void*)> walker, void* env)
	{
		if (irn_visited(irn))
			return;

		/* only break loops at phi/block nodes */
		const bool is_loop_breaker = is_Phi(irn) || is_Block(irn);

		if (is_loop_breaker)
			mark_irn_visited(irn);

		if (!is_Block(irn))
		{
			ir_node* block = get_nodes_block(irn);

			if (block != NULL)
				walk_topo_helper(block, walker, env);
		}

		for (int i = 0; i < get_irn_arity(irn); ++i)
		{
			ir_node* pred = get_irn_n(irn, i);
			walk_topo_helper(pred, walker, env);
		}

		if (is_loop_breaker || !irn_visited(irn))
			walker(irn, env);

		mark_irn_visited(irn);
	}
Ejemplo n.º 2
0
/**
 * Adds a control dependence from node to dep_on.
 */
static void add_cdep(ir_node *node, ir_node *dep_on)
{
	ir_cdep *dep = find_cdep(node);

	assert(is_Block(dep_on));
	if (dep == NULL) {
		ir_cdep *newdep = OALLOC(&cdep_data->obst, ir_cdep);

		newdep->node = dep_on;
		newdep->next = NULL;
		pmap_insert(cdep_data->cdep_map, node, newdep);
	} else {
		ir_cdep *newdep;

		for (;;) {
			if (get_cdep_node(dep) == dep_on)
				return;
			if (dep->next == NULL)
				break;
			dep = dep->next;
		}
		newdep = OALLOC(&cdep_data->obst, ir_cdep);
		newdep->node = dep_on;
		newdep->next = NULL;
		dep->next = newdep;
	}
}
Ejemplo n.º 3
0
/**
 * Edge hook to dump the schedule edges.
 */
static void sched_edge_hook(FILE *F, const ir_node *irn)
{
	ir_graph *irg = get_irn_irg(irn);
	if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND))
		return;

	if (is_Proj(irn) || is_Block(irn) || !sched_is_scheduled(irn))
		return;

	ir_node *const prev = sched_prev(irn);
	if (!sched_is_begin(prev)) {
		fprintf(F, "edge:{sourcename: ");
		print_nodeid(F, irn);
		fprintf(F, " targetname: ");
		print_nodeid(F, prev);
		fprintf(F, " color:magenta}\n");
	}
}
Ejemplo n.º 4
0
/**
 * Compute the height of a node in a block.
 * @param h   The heights object.
 * @param irn The node.
 * @param bl  The block.
 */
static unsigned compute_height(ir_heights_t *h, ir_node *irn, const ir_node *bl)
{
	irn_height_t *ih = get_height_data(h, irn);

	/* bail out if we already visited that node. */
	if (ih->visited >= h->visited)
		return ih->height;

	ih->visited = h->visited;
	ih->height  = 0;

	foreach_out_edge(irn, edge) {
		ir_node *dep = get_edge_src_irn(edge);

		if (!is_Block(dep) && !is_Phi(dep) && get_nodes_block(dep) == bl) {
			unsigned dep_height = compute_height(h, dep, bl);
			ih->height          = MAX(ih->height, dep_height+1);
		}
	}
Ejemplo n.º 5
0
/**
 * specialized version of irg_walk_2, called if only post callback exists
 */
static void irg_walk_2_post(ir_node *node, irg_walk_func *post, void *env)
{
	ir_graph    *irg     = get_irn_irg(node);
	ir_visited_t visited = irg->visited;

	set_irn_visited(node, visited);

	if (!is_Block(node)) {
		ir_node *pred = get_nodes_block(node);
		if (pred->visited < visited)
			irg_walk_2_post(pred, post, env);
	}
	foreach_irn_in_r(node, i, pred) {
		if (pred->visited < visited)
			irg_walk_2_post(pred, post, env);
	}

	post(node, env);
}
Ejemplo n.º 6
0
void instrument_initcall(ir_graph *irg, ir_entity *ent)
{
	ir_node        *initial_exec;
	ir_node        *first_block = NULL;
	int             i, idx, need_new_block;
	symconst_symbol sym;

	assure_edges(irg);

	/* find the first block */
	initial_exec = get_irg_initial_exec(irg);

	foreach_out_edge(initial_exec, edge) {
		ir_node *succ = get_edge_src_irn(edge);

		if (is_Block(succ)) {
			/* found the first block */
			first_block = succ;
			break;
		}
	}
Ejemplo n.º 7
0
static void dump_backend_info_hook(void *context, FILE *F, const ir_node *node)
{
	(void)context;

	ir_graph *const irg = get_irn_irg(node);
	if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_BACKEND))
		return;

	be_dump_reqs_and_registers(F, node);

	if (is_Block(node)) {
		be_lv_t *const lv = be_get_irg_liveness(irg);
		if (lv->sets_valid)
			be_dump_liveness_block(lv, F, node);
	}

#ifndef NDEBUG
	if (!is_Proj(node)) {
		char const *const orig = be_get_info(node)->orig_node;
		fprintf(F, "orig node = %s\n", orig ? orig : "n/a");
	}
#endif
}
Ejemplo n.º 8
0
void exchange_cdep(ir_node *old, const ir_node *nw)
{
	ir_cdep *cdep = find_cdep(nw);
	assert(is_Block(old));
	pmap_insert(cdep_data->cdep_map, old, cdep);
}
Ejemplo n.º 9
0
ir_cdep *find_cdep(const ir_node *block)
{
	assert(is_Block(block));
	return pmap_get(ir_cdep, cdep_data->cdep_map, block);
}
Ejemplo n.º 10
0
static ir_node *get_irn_safe_n(const ir_node *node, int n)
{
	if (n == -1 && is_Block(node))
		return NULL;
	return get_irn_n(node, n);
}
Ejemplo n.º 11
0
static inline const ir_dom_info *get_pdom_info_const(const ir_node *block)
{
	assert(is_Block(block));
	return &block->attr.block.pdom;
}
Ejemplo n.º 12
0
static inline ir_dom_info *get_dom_info(ir_node *block)
{
	assert(is_Block(block));
	return &block->attr.block.dom;
}
Ejemplo n.º 13
0
/**
 * Pre-walker for connecting DAGs and counting.
 */
static void connect_dags(ir_node *node, void *env)
{
	dag_env_t   *dag_env = (dag_env_t*)env;
	int         i, arity;
	ir_node     *block;
	dag_entry_t *entry;
	ir_mode     *mode;

	if (is_Block(node))
		return;

	block = get_nodes_block(node);

	/* ignore start end end blocks */
	ir_graph *const irg = get_Block_irg(block);
	if (block == get_irg_start_block(irg) || block == get_irg_end_block(irg))
		return;

	/* ignore Phi nodes */
	if (is_Phi(node))
		return;

	if (dag_env->options & FIRMSTAT_ARGS_ARE_ROOTS && is_arg(node))
		return;

	mode = get_irn_mode(node);
	if (mode == mode_X || mode == mode_M) {
		/* do NOT count mode_X and mode_M nodes */
		return;
	}

	/* if this option is set, Loads are always leaves */
	if (dag_env->options & FIRMSTAT_LOAD_IS_LEAVE && is_Load(node))
		return;

	if (dag_env->options & FIRMSTAT_CALL_IS_LEAVE && is_Call(node))
		return;

	entry = get_irn_dag_entry(node);

	if (! entry) {
		/* found an unassigned node, maybe a new root */
		entry = new_dag_entry(dag_env, node);
	}

	/* put the predecessors into the same DAG as the current */
	for (i = 0, arity = get_irn_arity(node); i < arity; ++i) {
		ir_node *prev = get_irn_n(node, i);
		ir_mode *mode = get_irn_mode(prev);

		if (is_Phi(prev))
			continue;

		if (mode == mode_X || mode == mode_M)
			continue;

		/*
		 * copy constants if requested into the DAG's
		 * beware, do NOT add a link, as this will result in
		 * wrong intersections
		 */
		if (dag_env->options & FIRMSTAT_COPY_CONSTANTS) {
			if (is_irn_constlike(prev)) {
				++entry->num_nodes;
				++entry->num_inner_nodes;
			}
		}

		/* only nodes from the same block goes into the DAG */
		if (get_nodes_block(prev) == block) {
			dag_entry_t *prev_entry = get_irn_dag_entry(prev);

			if (! prev_entry) {
				/* not assigned node, put it into the same DAG */
				set_irn_dag_entry(prev, entry);
				++entry->num_nodes;
				++entry->num_inner_nodes;
			} else {
				if (prev_entry == entry) {
					/* We found a node that is already assigned to this DAG.
					   This DAG is not a tree. */
					entry->is_tree = 0;
				} else {
					/* two DAGs intersect: copy the data to one of them
					   and kill the other */
					entry->num_roots       += prev_entry->num_roots;
					entry->num_nodes       += prev_entry->num_nodes;
					entry->num_inner_nodes += prev_entry->num_inner_nodes;
					entry->is_tree         &= prev_entry->is_tree;

					--dag_env->num_of_dags;

					prev_entry->is_dead = 1;
					prev_entry->link    = entry;
				}
			}
		}
	}
}
Ejemplo n.º 14
0
/**
 * Post-walker to detect DAG roots that are referenced form other blocks
 */
static void find_dag_roots(ir_node *node, void *env)
{
	dag_env_t   *dag_env = (dag_env_t*)env;
	int         i, arity;
	dag_entry_t *entry;
	ir_node     *block;

	if (is_Block(node))
		return;

	block = get_nodes_block(node);

	/* ignore start end end blocks */
	ir_graph *const irg = get_Block_irg(block);
	if (block == get_irg_start_block(irg) || block == get_irg_end_block(irg))
		return;

	/* Phi nodes always references nodes from "other" block */
	if (is_Phi(node)) {
		if (get_irn_mode(node) != mode_M) {
			for (i = 0, arity = get_irn_arity(node); i < arity; ++i) {
				ir_node *prev = get_irn_n(node, i);

				if (is_Phi(prev))
					continue;

				if (dag_env->options & FIRMSTAT_COPY_CONSTANTS) {
					if (is_irn_constlike(prev))
						continue;
				}

				entry = get_irn_dag_entry(prev);

				if (! entry) {
					/* found an unassigned node, a new root */
					entry = new_dag_entry(dag_env, node);
					entry->is_ext_ref = 1;
				}
			}
		}
	} else {

		for (i = 0, arity = get_irn_arity(node); i < arity; ++i) {
				ir_node *prev = get_irn_n(node, i);
				ir_mode *mode = get_irn_mode(prev);

				if (mode == mode_X || mode == mode_M)
					continue;

				if (is_Phi(prev))
					continue;

				if (dag_env->options & FIRMSTAT_COPY_CONSTANTS) {
					if (is_irn_constlike(prev))
						continue;
				}

				if (get_nodes_block(prev) != block) {
					/* The predecessor is from another block. It forms
					   a root. */
					entry = get_irn_dag_entry(prev);
					if (! entry) {
						/* found an unassigned node, a new root */
						entry = new_dag_entry(dag_env, node);
						entry->is_ext_ref = 1;
					}
				}
			}
	}
}