int pos = last_pos - seen[nr];
int end_pos = last_pos - b->step;
int live_in = is_live_in(block, irn);
- int live_out = is_live_out(block, irn);
+ int live_end = is_live_end(block, irn);
int y_val = y_dist * col;
int red = 0;
- int green = live_out;
+ int green = live_end;
int blue = live_in;
fprintf(f, "0 0 0 setrgbcolor\n");
border_t *b;
struct list_head head;
pset *live_in = get_live_in(block);
- pset *live_out = get_live_out(block);
+ pset *live_end = get_live_end(block);
ir_node *idom = get_Block_idom(block);
/*
* Make final uses of all values live out of the block.
* They are neccessary to build up real intervals.
*/
- for(irn = pset_first(live_out); irn; irn = pset_next(live_out)) {
+ for(irn = pset_first(live_end); irn; irn = pset_next(live_end)) {
DBG((dbg, LEVEL_3, "Making live: %n/%d\n", irn, get_irn_graph_nr(irn)));
bitset_set(live, get_irn_graph_nr(irn));
if(!is_Phi(irn) && is_allocatable_irn(irn))
free(env);
}
+int phi_ops_interfere(const ir_node *a, const ir_node *b)
+{
+ return values_interfere(a, b);
+}
+
+#if 0
int phi_ops_interfere(const ir_node *a, const ir_node *b)
{
ir_graph *irg = get_irn_irg(a);
return are_connected(env, get_irn_graph_nr(a), get_irn_graph_nr(b));
}
+#endif
#include "beutil.h"
#include "belive_t.h"
+#define DEFAULT_LIVE_SET_SIZE 8
+
FIRM_IMPL2(is_live_in, int, const ir_node *, const ir_node *)
FIRM_IMPL2(is_live_out, int, const ir_node *, const ir_node *)
+FIRM_IMPL2(is_live_end, int, const ir_node *, const ir_node *)
/** The offset of the liveness information in a firm node. */
size_t live_irn_data_offset = 0;
pset_insert_ptr(info->out, irn);
}
+static INLINE void mark_live_end(ir_node *block, const ir_node *irn)
+{
+ block_live_info_t *info = get_block_live_info(block);
+ pset_insert_ptr(info->end, irn);
+}
+
/**
* Mark a node (value) live out at a certain block. Do this also
* transitively, i.e. if the block is not the block of the value's
* @param def The node (value).
* @param block The block to mark the value live out of.
* @param visited A set were all visited blocks are recorded.
+ * @param is_true_out Is the node real out there or only live at the end
+ * of the block.
*/
-static void live_out_at_block(ir_node *def, ir_node *block, pset *visited)
+static void live_end_at_block(ir_node *def, ir_node *block,
+ pset *visited, int is_true_out)
{
if(pset_find_ptr(visited, block))
return;
pset_insert_ptr(visited, block);
- mark_live_out(block, def);
+ mark_live_end(block, def);
+
+ if(is_true_out)
+ mark_live_out(block, def);
/*
* If this block is not the definition block, we have to go up
mark_live_in(block, def);
for(i = 0, n = get_irn_arity(block); i < n; ++i)
- live_out_at_block(def, get_nodes_block(get_irn_n(block, i)), visited);
+ live_end_at_block(def, get_nodes_block(get_irn_n(block, i)), visited, 1);
}
}
for(i = 0, n = get_irn_arity(use); i < n; ++i) {
if(get_irn_n(use, i) == irn) {
ir_node *pred_block = get_nodes_block(get_irn_n(use_block, i));
- live_out_at_block(irn, pred_block, visited);
+ live_end_at_block(irn, pred_block, visited, 0);
}
}
}
for(i = 0, n = get_irn_arity(use_block); i < n; ++i) {
ir_node *pred_block = get_nodes_block(get_irn_n(use_block, i));
- live_out_at_block(irn, pred_block, visited);
+ live_end_at_block(irn, pred_block, visited, 1);
}
}
}
static void create_sets(ir_node *block, void *env)
{
block_live_info_t *info = get_block_live_info(block);
- info->in = pset_new_ptr(128);
- info->out = pset_new_ptr(128);
+ info->in = pset_new_ptr(DEFAULT_LIVE_SET_SIZE);
+ info->out = pset_new_ptr(DEFAULT_LIVE_SET_SIZE);
+ info->end = pset_new_ptr(DEFAULT_LIVE_SET_SIZE);
}
ir_fprintf(f, "liveness at block %n\n", block);
ir_fprintf(f, "\tlive in: %*n\n", pset_iterator, info->in);
ir_fprintf(f, "\tlive out: %*n\n", pset_iterator, info->out);
+ ir_fprintf(f, "\tlive end: %*n\n", pset_iterator, info->end);
}
void be_liveness_dump(FILE *f, ir_graph *irg)
typedef struct _block_live_info_t {
pset *in; /**< The set of all values live in at that block. */
pset *out; /**< The set of all values live out. */
+ pset *end; /**< The set of all values live at the end
+ of the block (contains all live out). */
} block_live_info_t;
typedef struct _node_live_info_t {
return pset_find_ptr(info->out, irn) != NULL;
}
+static INLINE int __is_live_end(const ir_node *block, const ir_node *irn)
+{
+ block_live_info_t *info = get_block_live_info(block);
+
+ assert(is_Block(block) && "Need a block here");
+ return pset_find_ptr(info->end, irn) != NULL;
+}
+
static INLINE pset *__get_live_in(const ir_node *block)
{
assert(is_Block(block) && "Need a block here");
return get_block_live_info(block)->out;
}
+static INLINE pset *__get_live_end(const ir_node *block)
+{
+ assert(is_Block(block) && "Need a block here");
+ return get_block_live_info(block)->end;
+}
+
#define is_phi_operand(irn) __is_phi_operand(irn)
#define is_live_in(bl,irn) __is_live_in(bl, irn)
#define is_live_out(bl,irn) __is_live_out(bl, irn)
+#define is_live_end(bl,irn) __is_live_end(bl, irn)
#define get_live_in(bl) __get_live_in(bl)
#define get_live_out(bl) __get_live_out(bl)
+#define get_live_end(bl) __get_live_end(bl)
/**
* Initialize the liveness module.