Commit 06e69d97 authored by Sebastian Hack's avatar Sebastian Hack
Browse files

Fixed a bug in scheduling and adapted coloring

parent 8ccaa22c
......@@ -14,6 +14,7 @@
#include <ctype.h>
#include "obst.h"
#include "pset.h"
#include "list.h"
#include "bitset.h"
#include "iterator.h"
......@@ -240,7 +241,7 @@ static void dump_ifg(const be_chordal_env_t *env)
ir_node *irn = get_irn_for_graph_nr(irg, nr);
int color = get_irn_color(irn);
ir_fprintf(f, "\tn%d [label=\"%n\",color=\"%s\"]\n", nr, irn,
ir_fprintf(f, "\tn%d [label=\"%+F\",color=\"%s\"]\n", nr, irn,
color >= 0 && color < n_colors ? colors[color] : "black");
}
......@@ -321,7 +322,7 @@ static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head
b->irn = irn;
b->step = step;
list_add_tail(&b->list, head);
DBG((dbg, LEVEL_5, "\t\t%s adding %n, step: %d\n",
DBG((dbg, LEVEL_5, "\t\t%s adding %+F, step: %d\n",
is_def ? "def" : "use", irn, step));
return b;
......@@ -351,11 +352,11 @@ static void pressure(ir_node *block, void *env_ptr)
unsigned step = 0;
unsigned pressure = 0;
struct list_head *head;
pset *live_in = get_live_in(block);
pset *live_end = get_live_end(block);
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;
DBG((dbg, LEVEL_1, "Computing pressure in block %n\n", block));
DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block));
bitset_clear_all(live);
/* Set up the border list in the block info */
......@@ -368,7 +369,7 @@ static void pressure(ir_node *block, void *env_ptr)
* They are neccessary to build up real intervals.
*/
for(irn = pset_first(live_end); irn; irn = pset_next(live_end)) {
DBG((dbg, LEVEL_3, "\tMaking live: %n/%d\n", irn, get_irn_graph_nr(irn)));
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);
......@@ -381,7 +382,7 @@ static void pressure(ir_node *block, void *env_ptr)
* relevant for the interval borders.
*/
sched_foreach_reverse(block, irn) {
DBG((dbg, LEVEL_1, "\tinsn: %n, pressure: %d\n", irn, pressure));
DBG((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure));
DBG((dbg, LEVEL_2, "\tlive: %b\n", live));
/*
......@@ -411,7 +412,7 @@ static void pressure(ir_node *block, void *env_ptr)
if(arch_irn_has_reg_class(env->arch_env, op, 0, cls)) {
int nr = get_irn_graph_nr(op);
DBG((dbg, LEVEL_4, "\t\tpos: %d, use: %n\n", i, op));
DBG((dbg, LEVEL_4, "\t\tpos: %d, use: %+F\n", i, op));
if(!bitset_is_set(live, nr)) {
border_use(op, step, 1);
......@@ -437,6 +438,9 @@ static void pressure(ir_node *block, void *env_ptr)
border_def(irn, step, 0);
}
}
del_pset(live_in);
del_pset(live_end);
}
static void assign(ir_node *block, void *env_ptr)
......@@ -446,7 +450,7 @@ static void assign(ir_node *block, void *env_ptr)
bitset_t *live = env->live;
bitset_t *colors = env->colors;
bitset_t *in_colors = env->in_colors;
const arch_register_class_t *cls = env->cls;
const arch_register_class_t *cls = env->cls;
/* Mark the obstack level and allocate the temporary tmp_colors */
void *obstack_level = obstack_base(obst);
......@@ -455,16 +459,16 @@ static void assign(ir_node *block, void *env_ptr)
const ir_node *irn;
border_t *b;
struct list_head *head = get_block_border_head(env, block);
pset *live_in = get_live_in(block);
pset *live_in = put_live_in(block, pset_new_ptr_default());
bitset_clear_all(live);
bitset_clear_all(colors);
bitset_clear_all(in_colors);
DBG((dbg, LEVEL_4, "Assigning colors for block %n\n", block));
DBG((dbg, LEVEL_4, "Assigning colors for block %+F\n", block));
DBG((dbg, LEVEL_4, "\tusedef chain for block\n"));
list_for_each_entry(border_t, b, head, list) {
DBG((dbg, LEVEL_4, "\t%s %n/%d\n", b->is_def ? "def" : "use",
DBG((dbg, LEVEL_4, "\t%s %+F/%d\n", b->is_def ? "def" : "use",
b->irn, get_irn_graph_nr(b->irn)));
}
......@@ -478,7 +482,7 @@ static void assign(ir_node *block, void *env_ptr)
const arch_register_t *reg = arch_get_irn_register(env->arch_env, irn, 0);
int col;
assert(reg && "Nodfe must have been assigned a register");
assert(reg && "Node must have been assigned a register");
col = arch_register_get_index(reg);
/* Mark the color of the live in value as used. */
......@@ -520,7 +524,7 @@ static void assign(ir_node *block, void *env_ptr)
bitset_set(live, nr);
arch_set_irn_register(env->arch_env, irn, 0, reg);
DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %n\n",
DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %+F\n",
arch_register_get_name(reg), col, irn));
}
......@@ -541,6 +545,8 @@ static void assign(ir_node *block, void *env_ptr)
/* Free the auxillary data on the obstack. */
obstack_free(obst, obstack_level);
del_pset(live_in);
}
void be_ra_chordal_init(void)
......
......@@ -97,25 +97,6 @@ typedef struct _block_sched_env_t {
/**
* Checks, if a node is to appear in a schedule. Such nodes either
* consume real data (mode datab) or produce such.
* @param irn The node to check for.
* @return 1, if the node consumes/produces data, false if not.
*/
static INLINE int to_appear_in_schedule(ir_node *irn)
{
int i, n;
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
ir_node *op = get_irn_n(irn, i);
if(mode_is_datab(get_irn_mode(op)))
return 1;
}
return mode_is_datab(get_irn_mode(irn));
}
/**
* Try to put a node in the ready set.
......@@ -147,7 +128,7 @@ static INLINE int make_ready(block_sched_env_t *env, ir_node *irn)
return 0;
}
DBG((env->dbg, LEVEL_2, "\tmaking ready: %n\n", irn));
DBG((env->dbg, LEVEL_2, "\tmaking ready: %+F\n", irn));
pset_insert_ptr(env->ready_set, irn);
return 1;
......@@ -213,10 +194,10 @@ static ir_node *add_to_sched(block_sched_env_t *env, ir_node *irn)
if(to_appear_in_schedule(irn)) {
sched_info_t *info = get_irn_sched_info(irn);
INIT_LIST_HEAD(&info->list);
info->time_step = env->curr_time;
info->scheduled = 1;
sched_add_before(env->block, irn);
DBG((env->dbg, LEVEL_2, "\tadding %n\n", irn));
DBG((env->dbg, LEVEL_2, "\tadding %+F\n", irn));
}
/* Insert the node in the set of all already scheduled nodes. */
......@@ -300,10 +281,12 @@ static void list_sched_block(ir_node *block, void *env_ptr)
be.ready_set = new_pset(node_cmp_func, get_irn_n_outs(block));
be.already_scheduled = new_pset(node_cmp_func, get_irn_n_outs(block));
firm_dbg_set_mask(be.dbg, 0);
if(selector->init_block)
block_env = selector->init_block(env->selector_env, block);
DBG((be.dbg, LEVEL_1, "scheduling %n\n", block));
DBG((be.dbg, LEVEL_1, "scheduling %+F\n", block));
/* Then one can add all nodes are ready to the set. */
for(i = 0, n = get_irn_n_outs(block); i < n; ++i) {
......@@ -338,7 +321,7 @@ static void list_sched_block(ir_node *block, void *env_ptr)
/* Make the node ready, if all operands live in a foreign block */
if(ready) {
DBG((be.dbg, LEVEL_2, "\timmediately ready: %n\n", irn));
DBG((be.dbg, LEVEL_2, "\timmediately ready: %+F\n", irn));
make_ready(&be, irn);
}
}
......@@ -348,12 +331,12 @@ static void list_sched_block(ir_node *block, void *env_ptr)
be.curr_time += phi_seen;
while(pset_count(be.ready_set) > 0) {
DBG((be.dbg, LEVEL_2, "\tready set: %*n\n", pset_iterator, be.ready_set));
// DBG((be.dbg, LEVEL_2, "\tready set: %*n\n", pset_iterator, be.ready_set));
/* select a node to be scheduled and check if it was ready */
irn = selector->select(env->selector_env, block_env, &info->list, be.curr_time, be.ready_set);
DBG((be.dbg, LEVEL_3, "\tpicked node %n\n", irn));
DBG((be.dbg, LEVEL_3, "\tpicked node %+F\n", irn));
/* Add the node to the schedule. */
add_to_sched(&be, irn);
......
......@@ -4,7 +4,8 @@
#include "impl.h"
#include "irprintf.h"
#include "irgwalk.h"
#include "irnode.h"
#include "irnode_t.h"
#include "iredges_t.h"
#include "debug.h"
#include "besched_t.h"
......@@ -28,9 +29,10 @@ static void block_sched_dumper(ir_node *block, void *env)
FILE *f = env;
const ir_node *curr;
ir_fprintf(f, "%n:\n", block);
ir_fprintf(f, "%+F:\n", block);
sched_foreach(block, curr) {
ir_fprintf(f, "\t%n\n", curr);
sched_info_t *info = get_irn_sched_info(curr);
ir_fprintf(f, "\t%6d: %+F\n", info->time_step, curr);
}
}
......@@ -83,6 +85,10 @@ int sched_verify(const ir_node *block)
const ir_node *irn;
int i, n;
int *save_time_step;
const ir_edge_t *edge;
pset *scheduled_nodes = pset_new_ptr_default();
firm_dbg_set_mask(dbg_sched, -1);
/* Count the number of nodes in the schedule. */
n = 0;
......@@ -96,6 +102,7 @@ int sched_verify(const ir_node *block)
sched_info_t *info = get_irn_sched_info(irn);
save_time_step[i] = info->time_step;
info->time_step = i;
pset_insert_ptr(scheduled_nodes, irn);
i += 1;
}
......@@ -111,7 +118,7 @@ int sched_verify(const ir_node *block)
for(i = 0, n = get_irn_arity(irn); i < n; i++) {
ir_node *op = get_irn_n(irn, i);
if(mode_is_datab(get_irn_mode(op))
if(to_appear_in_schedule(op)
&& get_nodes_block(op) == block
&& sched_get_time_step(op) > step) {
......@@ -139,6 +146,14 @@ int sched_verify(const ir_node *block)
info->time_step = save_time_step[i++];
}
/* Check for all nodes in the block if they are scheduled. */
foreach_out_edge(block, edge) {
ir_node *irn = get_edge_src_irn(edge);
if(to_appear_in_schedule(irn) && !pset_find_ptr(scheduled_nodes, irn))
DBG((dbg_sched, LEVEL_DEFAULT, "%+F is in block but not scheduled\n", irn));
}
del_pset(scheduled_nodes);
free(save_time_step);
return res;
}
......
......@@ -16,7 +16,7 @@ ir_node *(sched_prev)(const ir_node *irn);
ir_node *(sched_first)(const ir_node *block);
ir_node *(sched_last)(const ir_node *block);
ir_node *(sched_add_before)(ir_node *before, ir_node *irn);
ir_node *(sched_add_before)(ir_node *before, ir_node *irn);
ir_node *(sched_add_after)(ir_node *before, ir_node *irn);
/**
* A shorthand macro for iterating over a schedule.
......@@ -24,7 +24,7 @@ ir_node *(sched_add_before)(ir_node *before, ir_node *irn);
* @param irn A ir node pointer used as an iterator.
*/
#define sched_foreach(block,irn) \
for(irn = sched_first(block); sched_has_next(irn); irn = sched_next(irn))
for(irn = sched_first(block); !is_Block(irn); irn = sched_next(irn))
/**
* A shorthand macro for reversely iterating over a schedule.
......@@ -32,6 +32,6 @@ ir_node *(sched_add_before)(ir_node *before, ir_node *irn);
* @param irn A ir node pointer used as an iterator.
*/
#define sched_foreach_reverse(block,irn) \
for(irn = sched_last(block); sched_has_prev(irn); irn = sched_prev(irn))
for(irn = sched_last(block); !is_Block(irn); irn = sched_prev(irn))
#endif
......@@ -46,6 +46,25 @@ static INLINE int _sched_get_time_step(const ir_node *irn)
return get_irn_sched_info(irn)->time_step;
}
/**
* Checks, if a node is to appear in a schedule. Such nodes either
* consume real data (mode datab) or produce such.
* @param irn The node to check for.
* @return 1, if the node consumes/produces data, false if not.
*/
static INLINE int to_appear_in_schedule(ir_node *irn)
{
int i, n;
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
ir_node *op = get_irn_n(irn, i);
if(mode_is_datab(get_irn_mode(op)))
return 1;
}
return mode_is_datab(get_irn_mode(irn));
}
/**
* Check, if an ir_node has a scheduling successor.
* @param irn The ir node.
......@@ -53,7 +72,7 @@ static INLINE int _sched_get_time_step(const ir_node *irn)
*/
static INLINE int _sched_has_next(const ir_node *irn)
{
const ir_node *block = is_Block(irn) ? irn : get_nodes_block(irn);
const ir_node *block = is_Block(irn) ? irn : get_nodes_block(irn);
const sched_info_t *info = get_irn_sched_info(irn);
const sched_info_t *block_info = get_irn_sched_info(block);
return info->list.next != &block_info->list;
......@@ -66,7 +85,7 @@ static INLINE int _sched_has_next(const ir_node *irn)
*/
static INLINE int _sched_has_prev(const ir_node *irn)
{
const ir_node *block = is_Block(irn) ? irn : get_nodes_block(irn);
const ir_node *block = is_Block(irn) ? irn : get_nodes_block(irn);
const sched_info_t *info = get_irn_sched_info(irn);
const sched_info_t *block_info = get_irn_sched_info(block);
return info->list.prev != &block_info->list;
......@@ -182,7 +201,7 @@ static INLINE ir_node *_sched_add_after(ir_node *after, ir_node *irn)
*/
static INLINE int _sched_is_scheduled(ir_node *irn)
{
return get_irn_sched_info(irn)->scheduled;
return get_irn_sched_info(irn)->scheduled;
}
/**
......
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