Commit 0b4a2ee4 authored by Kimon Hoffmann's avatar Kimon Hoffmann
Browse files

Refactored interference graph into seperate header and source.

parent 82bfe0eb
......@@ -26,7 +26,7 @@ SOURCES += Makefile.in besched.h belistsched.h belistsched.c \
sp_matrix.c becopyoptmain.c becopyopt.c becopyheur.c \
becopyilp.c becopystat.c bearch_firm.c bearch.c bechordal_draw.c \
bechordal_draw.h beirgmod.c beirgmod.h benode.c benode_t.h \
mps.c lpp.c lpp_local.c lpp_remote.c bessadestr.c
mps.c lpp.c lpp_local.c lpp_remote.c bessadestr.c beifg.c
include $(topdir)/MakeRules
......
......@@ -354,15 +354,15 @@ static void pressure(ir_node *block, void *env_ptr)
struct list_head *head;
pset *live_in = put_live_in(block, pset_new_ptr_default());
pset *live_end = put_live_end(block, pset_new_ptr_default());
const arch_register_class_t *cls = env->cls;
const arch_register_class_t *cls = env->cls;
DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block));
bitset_clear_all(live);
/* Set up the border list in the block info */
head = obstack_alloc(&env->obst, sizeof(*head));
head = obstack_alloc(&env->obst, sizeof(*head));
INIT_LIST_HEAD(head);
pmap_insert(env->border_heads, block, head);
pmap_insert(env->border_heads, block, head);
/*
* Make final uses of all values live out of the block.
......@@ -371,10 +371,9 @@ static void pressure(ir_node *block, void *env_ptr)
for(irn = pset_first(live_end); irn; irn = pset_next(live_end)) {
DBG((dbg, LEVEL_3, "\tMaking live: %+F/%d\n", irn, get_irn_graph_nr(irn)));
bitset_set(live, get_irn_graph_nr(irn));
if(arch_irn_has_reg_class(env->arch_env, irn, 0, cls))
border_use(irn, step, 0);
if(arch_irn_has_reg_class(env->arch_env, irn, 0, cls))
border_use(irn, step, 0);
}
++step;
/*
......@@ -385,20 +384,20 @@ static void pressure(ir_node *block, void *env_ptr)
DBG((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure));
DBG((dbg, LEVEL_2, "\tlive: %b\n", live));
/*
* If the node defines some value, which can put into a
* register of the current class, make a border for it.
*/
/*
* If the node defines some value, which can put into a
* register of the current class, make a border for it.
*/
if(arch_irn_has_reg_class(env->arch_env, irn, 0, cls)) {
bitset_pos_t elm;
bitset_pos_t elm;
int nr = get_irn_graph_nr(irn);
bitset_clear(live, nr);
border_def(irn, step, 1);
#ifdef BUILD_GRAPH
bitset_foreach(live, elm)
add_if(env, nr, (int) elm);
bitset_foreach(live, elm)
add_if(env, nr, (int) elm);
#endif
}
......@@ -421,7 +420,6 @@ static void pressure(ir_node *block, void *env_ptr)
}
}
}
++step;
}
......@@ -560,7 +558,7 @@ be_chordal_env_t *be_ra_chordal(ir_graph *irg,
const arch_register_class_t *cls)
{
int node_count = get_graph_node_count(irg);
int colors_n = arch_register_class_n_regs(cls);
int colors_n = arch_register_class_n_regs(cls);
be_chordal_env_t *env = malloc(sizeof(*env));
if(get_irg_dom_state(irg) != dom_consistent)
......@@ -577,10 +575,10 @@ be_chordal_env_t *be_ra_chordal(ir_graph *irg,
env->colors = bitset_obstack_alloc(&env->obst, colors_n);
env->in_colors = bitset_obstack_alloc(&env->obst, colors_n);
env->colors_n = colors_n;
env->cls = cls;
env->arch_env = arch_env;
env->irg = irg;
env->border_heads = pmap_create();
env->cls = cls;
env->arch_env = arch_env;
env->irg = irg;
env->border_heads = pmap_create();
/* First, determine the pressure */
dom_tree_walk_irg(irg, pressure, NULL, env);
......@@ -592,23 +590,22 @@ be_chordal_env_t *be_ra_chordal(ir_graph *irg,
dom_tree_walk_irg(irg, assign, NULL, env);
#ifdef DUMP_IFG
dump_ifg(env);
dump_ifg(env);
#endif
#ifdef DUMP_INTERVALS
{
char buf[128];
plotter_t *plotter;
plotter_t *plotter;
ir_snprintf(buf, sizeof(buf), "ifg_%s_%F.eps", cls->name, irg);
plotter = new_plotter_ps(buf);
plotter = new_plotter_ps(buf);
draw_interval_tree(&draw_chordal_def_opts, env, plotter, arch_env, cls);
plotter_free(plotter);
draw_interval_tree(&draw_chordal_def_opts, env, plotter, arch_env, cls);
plotter_free(plotter);
}
#endif
return env;
return env;
}
void be_ra_chordal_done(be_chordal_env_t *env)
......
/**
* Common use interference graph.
* Originally written by Sebastian Hack. Refactored into a seperate
* source file and header by Kimon Hoffmann.
* @author Sebastian Hack
* @date 27.06.2005
*/
#include <malloc.h>
#include "debug.h"
#include "beifg_t.h"
#define IF_EDGE_HASH(e) ((e)->sourceNode)
#define IF_NODE_HASH(n) ((n)->nodeNumber)
#define IF_NODE_NEIGHBOUR_SLOTS 8
static int if_edge_cmp(const void* p1, const void* p2, size_t size) {
const be_if_edge_t* e1 = p1;
const be_if_edge_t* e2 = p2;
return !((e1->sourceNode == e2->sourceNode) && (e1->targetNode == e2->targetNode));
}
static int if_node_cmp(const void* p1, const void* p2, size_t size) {
const be_if_node_t* n1 = p1;
const be_if_node_t* n2 = p2;
return (n1->nodeNumber != n2->nodeNumber);
}
static INLINE be_if_edge_t *edge_init(be_if_edge_t* edge, int source, int target) {
/* Bring the smaller entry to src. */
if (source > target) {
edge->sourceNode = target;
edge->targetNode = source;
} else {
edge->sourceNode = source;
edge->targetNode = target;
}
return edge;
}
be_if_graph_t* be_ifg_new(int slots) {
be_if_graph_t* graph = malloc(sizeof(*graph));
graph->edges = new_set(if_edge_cmp, slots);
graph->nodes = new_set(if_node_cmp, slots);
return graph;
}
void be_ifg_free(be_if_graph_t* graph) {
be_if_node_t* ifn;
for (ifn = set_first(graph->nodes); ifn; ifn = set_next(graph->nodes)) {
free(ifn->neighbourNodes);
ifn->neighbourNodes = 0;
}
free(graph->nodes);
graph->nodes = 0;
free(graph->edges);
graph->edges = 0;
free(graph);
}
void be_ifg_add_interference(be_if_graph_t* graph, int source, int target) {
/* insert edge */
be_if_edge_t edge;
edge_init(&edge, source, target);
set_insert(graph->edges, &edge, sizeof(edge), IF_EDGE_HASH(&edge));
/* insert nodes */
be_if_node_t node;
node.nodeNumber = source;
node.neighbourNodes = pset_new_ptr(IF_NODE_NEIGHBOUR_SLOTS);
be_if_node_t* sourceNode = set_insert(graph->nodes, &node, sizeof(node), IF_NODE_HASH(&node));
node.nodeNumber = target;
node.neighbourNodes = pset_new_ptr(IF_NODE_NEIGHBOUR_SLOTS);
be_if_node_t* targetNode = set_insert(graph->nodes, &node, sizeof(node), IF_NODE_HASH(&node));
/* insert neighbors into nodes */
pset_insert_ptr(sourceNode->neighbourNodes, targetNode);
pset_insert_ptr(targetNode->neighbourNodes, sourceNode);
}
static INLINE int are_connected(const be_if_graph_t* graph, int source, int target) {
be_if_edge_t edge;
edge_init(&edge, source, target);
return set_find(graph->edges, &edge, sizeof(edge), IF_EDGE_HASH(&edge)) != NULL;
}
int be_ifg_has_edge(const be_if_graph_t* graph, const be_if_node_t* n1, const be_if_node_t* n2) {
return are_connected(graph, n1->nodeNumber, n2->nodeNumber);
}
/**
* Common use interference graph.
* Originally written by Sebastian Hack. Refactored into a seperate
* source file and header by Kimon Hoffmann.
* @author Sebastian Hack
* @date 27.06.2005
*/
#ifndef _BEIFG_H_
#define _BEIFG_H_
typedef struct _be_if_graph_t be_if_graph_t;
typedef struct _be_if_node_t be_if_node_t;
typedef struct _be_if_edge_t be_if_edge_t;
/**
* Creates a new interference graph with the specified number of
* initial slots.
* @param slots the initial number of slots used for hashing.
* Must be greater than 0.
* @return the created, empty interference graph.
*/
be_if_graph_t* be_ifg_new(int slots);
/**
* Frees the passed interference graph an all contained nodes.
* @param graph the interference graph that shall be freed. Please note
* that after a call to this function all pointers to the graph,
* its edges or its nodes are invalid.
*/
void be_ifg_free(be_if_graph_t* graph);
/**
* Adds a new undirected interference edge between the two nodes
* specified by their node numbers. If the corresponding nodes do
* not yet exist in the iunterference grpah they are created pririor
* to creation of the edge.
* @param graph the graph to add the interference edge to.
* @param source the key of the source node.
* @param target the key of the target node.
*/
void be_ifg_add_interference(be_if_graph_t* graph, int source, int target);
/**
* Returns the set of all edges within the specified
* graph.
* @param graph the graph the return the set of edges of.
* @return A set of all edges within the specified graph as
* be_if_edge_t instances.
*/
set* be_get_ifg_edges(const be_if_graph_t* graph);
/**
* Returns the set of all nodes within the specified
* graph.
* @param graph the graph the return the set of nodes of.
* @return A set of all nodes within the specified graph as
* be_if_node_t instances.
*/
set* be_get_ifg_nodes(const be_if_graph_t* graph);
/**
* Returns whether the specified graph alreadz contains an undirected
* edge between the two passed nodes.
* @param graph the graph to which containment both nodes @p n1 and
* @p n2 belong.
* @param n1 the one end of the edge to query the graph for.
* @param n2 the other end of the edge.
* @return TRUE if the graph contains an edge between @p n1 and @p n2,
* otherwise FALSE.
*/
int be_ifg_has_edge(const be_if_graph_t* graph, const be_if_node_t* n1, const be_if_node_t* n2);
#define be_ifn_get_degree(ifnode) \
pset_count(ifnode->neighb)
#define be_ifn_foreach_neighbour(ifnode, curr) \
for (curr = pset_first(ifnode->neighb); curr; curr = pset_next(ifnode->neighb))
#endif /*_BEIFG_H_*/
/**
* Common use interference graph.
* Originally written by Sebastian Hack. Refactored into a seperate
* source file and header by Kimon Hoffmann.
* @author Sebastian Hack
* @date 27.06.2005
*/
#ifndef _BEIFG_T_H_
#define _BEIFG_T_H_
#include "pset.h"
#include "set.h"
#include "beifg.h"
/**
* Structure that represents a single interference graph.
*/
struct _be_if_graph_t {
/**
* Set of nodes in this graph as be_if_node_t structs.
*/
set* nodes;
/**
* Set of edges in this graph as be_if_edge_t structs.
*/
set* edges;
};
/**
* Node type contained in i0nterference graphs.
*/
struct _be_if_node_t {
int nodeNumber;
pset* neighbourNodes;
};
/**
* Edge type contained in interference graphs.
*/
struct _be_if_edge_t {
int sourceNode;
int targetNode;
};
#endif /*_BEIFG_T_H_*/
......@@ -141,8 +141,8 @@ static void be_main_loop(void)
/* Schedule the graphs. */
list_sched(irg, trivial_selector);
/* Verify the schedule */
sched_verify_irg(irg);
/* Verify the schedule */
sched_verify_irg(irg);
/* Liveness analysis */
be_liveness(irg);
......@@ -164,7 +164,7 @@ static void be_main_loop(void)
copystat_collect_cls(chordal_env);
be_copy_opt(chordal_env);
be_ssa_destruction(&session, chordal_env);
// be_ssa_destruction(&session, chordal_env);
be_ra_chordal_done(chordal_env);
}
copystat_dump_pretty(irg);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment