Commit 8786fa72 authored by Sebastian Hack's avatar Sebastian Hack
Browse files

Renamed be_introduce_copies*

Added some stuff to bearch.h
parent 539322bc
......@@ -105,6 +105,16 @@ int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn, int pos
return req->cls->n_regs;
}
void arch_put_non_ignore_regs(const arch_env_t *env, const arch_register_class_t *cls, bitset_t *bs)
{
int i;
for(i = 0; i < cls->n_regs; ++i) {
if(!arch_register_type_is(&cls->regs[i], ignore))
bitset_set(bs, i);
}
}
int arch_is_register_operand(const arch_env_t *env,
const ir_node *irn, int pos)
{
......
......@@ -10,6 +10,8 @@
#include <libcore/lc_opts.h>
#endif
#include "type.h"
#include "irnode.h"
#include "irmode.h"
......@@ -21,6 +23,7 @@
#include "ident.h"
#include "belistsched.h"
#include "beabi_t.h"
typedef struct _arch_register_class_t arch_register_class_t;
typedef struct _arch_register_t arch_register_t;
......@@ -37,12 +40,15 @@ struct _be_node_factory_t;
typedef enum _arch_register_type_t {
arch_register_type_none = 0,
arch_register_type_caller_saved, /**< The register must be saved by the caller
upon a function call. It thus can be overwritten
in the called function. */
arch_register_type_callee_saved, /**< The register must be saved by the called function,
it thus survives a function call. */
arch_register_type_ignore /**< Do not consider this register when allocating. */
arch_register_type_caller_save = 1, /**< The register must be saved by the caller
upon a function call. It thus can be overwritten
in the called function. */
arch_register_type_callee_save = 2, /**< The register must be saved by the caller
upon a function call. It thus can be overwritten
in the called function. */
arch_register_type_ignore = 4, /**< Do not consider this register when allocating. */
arch_register_type_sp = 8, /**< This register is the stack pointer of the architecture. */
arch_register_type_bp = 16, /**< The register is the base pointer of the architecture. */
} arch_register_type_t;
/**
......@@ -87,6 +93,7 @@ static INLINE int _arch_register_get_index(const arch_register_t *reg)
struct _arch_register_class_t {
const char *name; /**< The name of the register class. */
int n_regs; /**< Number of registers in this class. */
ir_mode *mode; /**< The mode of the register class. */
const arch_register_t *regs; /**< The array of registers. */
};
......@@ -163,12 +170,13 @@ typedef struct _arch_register_req_t {
return the number of registers
in the bitset. */
void *limited_env; /**< This is passed to limited. */
void *limited_env; /**< This must passed to limited. */
ir_node *other_same; /**< The other which shall have the same reg
as this one. (for case should_be_same). */
ir_node *other; /**< In case of "should be equal"
or should be different, this gives
the node to whose register this
one's should be the same/different. */
ir_node *other_different; /**< The other node from which this one's register
must be different (case must_be_different). */
} arch_register_req_t;
/**
......@@ -291,6 +299,15 @@ extern int arch_is_register_operand(const arch_env_t *env,
*/
extern int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn, int pos, bitset_t *bs);
/**
* Put all registers which shall not be ignored by the register
* allocator in a bit set.
* @param env The arch env.
* @param cls The register class to consider.
* @param bs The bit set to put the registers to.
*/
extern void arch_put_non_ignore_regs(const arch_env_t *env, const arch_register_class_t *cls, bitset_t *bs);
/**
* Check, if a register is assignable to an operand of a node.
* @param env The architecture environment.
......@@ -348,8 +365,7 @@ extern arch_irn_class_t arch_irn_classify(const arch_env_t *env, const ir_node *
*/
extern arch_irn_flags_t arch_irn_get_flags(const arch_env_t *env, const ir_node *irn);
#define arch_irn_is_ignore(env, irn) 0
// ((arch_irn_get_flags(env, irn) & arch_irn_flags_ignore) != 0)
#define arch_irn_is_ignore(env, irn) ((arch_irn_get_flags(env, irn) & arch_irn_flags_ignore) != 0)
#define arch_irn_has_reg_class(env, irn, pos, cls) \
((cls) == arch_get_irn_reg_class(env, irn, pos))
......@@ -458,8 +474,15 @@ struct _arch_code_generator_t {
*/
struct _arch_isa_t {
const arch_isa_if_t *impl;
const arch_register_t *sp; /** The stack pointer register. */
const arch_register_t *bp; /** The base pointer register. */
const int stack_dir; /** -1 for decreasing, 1 for increasing. */
};
#define arch_isa_stack_dir(isa) ((isa)->stack_dir)
#define arch_isa_sp(isa) ((isa)->sp)
#define arch_isa_bp(isa) ((isa)->bp)
/**
* Architecture interface.
*/
......@@ -492,6 +515,22 @@ struct _arch_isa_if_t {
*/
const arch_register_class_t *(*get_reg_class)(const void *self, int i);
/**
* Get the register class which shall be used to store a value of a given mode.
* @param self The this pointer.
* @param mode The mode in question.
* @return A register class which can hold values of the given mode.
*/
const arch_register_class_t *(*get_reg_class_for_mode)(const void *self, const ir_mode *mode);
/**
* Get the ABI restrictions for procedure calls.
* @param self The this pointer.
* @param method_type The type of the method (procedure) in question.
* @param p The array of parameter locations to be filled.
*/
void (*get_call_abi)(const void *self, ir_type *method_type, be_abi_call_t *abi);
/**
* The irn handler for this architecture.
* The irn handler is registered by the Firm back end
......@@ -524,10 +563,12 @@ struct _arch_isa_if_t {
long (*handle_call_proj)(const void *self, ir_node *proj, int is_keep);
};
#define arch_isa_get_n_reg_class(isa) ((isa)->impl->get_n_reg_class(isa))
#define arch_isa_get_reg_class(isa,i) ((isa)->impl->get_reg_class(isa, i))
#define arch_isa_get_irn_handler(isa) ((isa)->impl->get_irn_handler(isa))
#define arch_isa_make_code_generator(isa,irg) ((isa)->impl->make_code_generator(isa, irg))
#define arch_isa_get_n_reg_class(isa) ((isa)->impl->get_n_reg_class(isa))
#define arch_isa_get_reg_class(isa,i) ((isa)->impl->get_reg_class(isa, i))
#define arch_isa_get_irn_handler(isa) ((isa)->impl->get_irn_handler(isa))
#define arch_isa_get_call_abi(isa,tp,abi) ((isa)->impl->get_call_abi((isa), (tp), (abi)))
#define arch_isa_get_reg_class_for_mode(isa,mode) ((isa)->impl->get_reg_class_for_mode((isa), (mode)))
#define arch_isa_make_code_generator(isa,irg) ((isa)->impl->make_code_generator(isa, irg))
#define ARCH_MAX_HANDLERS 8
......@@ -566,7 +607,6 @@ extern arch_env_t *arch_env_init(arch_env_t *env, const arch_isa_if_t *isa);
* @param handler A node handler.
* @return The environment itself.
*/
extern arch_env_t *arch_env_add_irn_handler(arch_env_t *env,
const arch_irn_handler_t *handler);
extern arch_env_t *arch_env_add_irn_handler(arch_env_t *env, const arch_irn_handler_t *handler);
#endif /* _FIRM_BEARCH_H */
......@@ -62,7 +62,8 @@ typedef struct _be_chordal_alloc_env_t {
pset *pre_colored; /**< Set of precolored nodes. */
bitset_t *live; /**< A liveness bitset. */
bitset_t *colors; /**< The color mask. */
bitset_t *ignore_colors; /**< A mask of colors which shall be not used in allocation (ignored). */
bitset_t *valid_colors; /**< A mask of colors which shall be considered during allocation.
Registers with the ignore bit on, must not be considered. */
bitset_t *in_colors; /**< Colors used by live in values. */
int colors_n; /**< The number of colors. */
} be_chordal_alloc_env_t;
......@@ -257,7 +258,7 @@ static operand_t *find_unpaired_use(insn_t *insn, const operand_t *op, int can_b
int has_constraint = arch_register_req_is(&op->req, limited);
if(!values_interfere(op->carrier, op->irn) && !op->partner && (!has_constraint || can_be_constrained)) {
if(arch_register_req_is(&op->req, should_be_same) && op->req.other == op->carrier)
if(arch_register_req_is(&op->req, should_be_same) && op->req.other_same == op->carrier)
return op;
else
res = op;
......@@ -338,7 +339,9 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
bitset_clear_all(bs);
op->req.limited(op->req.limited_env, bs);
bitset_andnot(bs, alloc_env->ignore_colors);
bitset_and(bs, alloc_env->valid_colors);
DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, bs));
bitset_foreach(bs, col)
bipartite_add(bp, n_alloc, col);
......@@ -360,7 +363,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
bitset_clear_all(bs);
arch_get_allocatable_regs(aenv, proj, -1, bs);
bitset_andnot(bs, alloc_env->ignore_colors);
bitset_and(bs, alloc_env->valid_colors);
bitset_foreach(bs, col)
bipartite_add(bp, n_alloc, col);
......@@ -371,10 +374,14 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
bipartite_matching(bp, assignment);
for(i = 0; i < n_alloc; ++i) {
int j;
ir_node *nodes[2];
const arch_register_t *reg = arch_register_for_index(env->cls, assignment[i]);
const arch_register_t *reg;
assert(assignment[i] >= 0 && "there must have been a register assigned");
reg = arch_register_for_index(env->cls, assignment[i]);
nodes[0] = alloc_nodes[i];
nodes[1] = pmap_get(partners, alloc_nodes[i]);
......@@ -571,9 +578,11 @@ static void assign(ir_node *block, void *env_ptr)
pset *live_in = put_live_in(block, pset_new_ptr_default());
bitset_clear_all(live);
bitset_clear_all(colors);
bitset_clear_all(in_colors);
bitset_copy(colors, alloc_env->valid_colors);
bitset_flip_all(colors);
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) {
......@@ -660,15 +669,14 @@ static void assign(ir_node *block, void *env_ptr)
del_pset(live_in);
}
void be_ra_chordal_color(be_chordal_env_t *chordal_env)
{
int i;
be_chordal_alloc_env_t env;
char buf[256];
int colors_n = arch_register_class_n_regs(chordal_env->cls);
ir_graph *irg = chordal_env->irg;
be_chordal_alloc_env_t env;
if(get_irg_dom_state(irg) != dom_consistent)
compute_doms(irg);
......@@ -676,24 +684,16 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
env.chordal_env = chordal_env;
env.colors_n = colors_n;
env.colors = bitset_malloc(colors_n);
env.ignore_colors = bitset_malloc(colors_n);
env.valid_colors = bitset_malloc(colors_n);
env.in_colors = bitset_malloc(colors_n);
env.pre_colored = pset_new_ptr_default();
bitset_clear_all(env.ignore_colors);
#if 0
for(i = 0; i < chordal_env->cls->n_regs; ++i) {
const arch_register_t *reg = &chordal_env->cls->regs[i];
if(arch_register_type_is(reg, ignore))
bitset_set(env.ignore_colors, reg->index);
}
#endif
arch_put_non_ignore_regs(chordal_env->main_env->arch_env, chordal_env->cls, env.valid_colors);
/* Handle register targeting constraints */
dom_tree_walk_irg(irg, constraints, NULL, &env);
{
char buf[128];
if(chordal_env->opts->dump_flags & BE_CH_DUMP_CONSTR) {
snprintf(buf, sizeof(buf), "-%s-constr", chordal_env->cls->name);
dump_ir_block_graph_sched(chordal_env->irg, buf);
}
......@@ -709,23 +709,19 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env)
be_numbering_done(irg);
#ifdef DUMP_INTERVALS
{
char buf[128];
if(chordal_env->opts->dump_flags & BE_CH_DUMP_TREE_INTV) {
plotter_t *plotter;
ir_snprintf(buf, sizeof(buf), "ifg_%s_%F.eps", chordal_env->cls->name, irg);
plotter = new_plotter_ps(buf);
draw_interval_tree(&draw_chordal_def_opts, chordal_env, plotter);
plotter_free(plotter);
}
#endif
free(env.live);
free(env.colors);
free(env.in_colors);
free(env.ignore_colors);
free(env.valid_colors);
del_pset(env.pre_colored);
}
......@@ -71,6 +71,16 @@ typedef struct {
FILE *f;
} ps_plotter_t;
/*
____ ____ ____ _ _ _
| _ \/ ___| | _ \| | ___ | |_| |_ ___ _ __
| |_) \___ \ | |_) | |/ _ \| __| __/ _ \ '__|
| __/ ___) | | __/| | (_) | |_| || __/ |
|_| |____/ |_| |_|\___/ \__|\__\___|_|
*/
static void ps_begin(plotter_t *_self, const rect_t *vis)
{
FILE *f;
......@@ -148,6 +158,63 @@ plotter_t *new_plotter_ps(const char *filename)
return p;
}
/*
_____ _ _ _____ ____ _ _ _
|_ _(_) | __|__ / | _ \| | ___ | |_| |_ ___ _ __
| | | | |/ / / / | |_) | |/ _ \| __| __/ _ \ '__|
| | | | < / /_ | __/| | (_) | |_| || __/ |
|_| |_|_|\_\/____| |_| |_|\___/ \__|\__\___|_|
*/
typedef struct {
base_plotter_t inh;
const char *filename;
FILE *f;
} tikz_plotter_t;
static void tikz_begin(plotter_t *_self, const rect_t *vis)
{
FILE *f;
decl_self(tikz_plotter_t, _self);
f = self->f = fopen(self->filename, "wt");
fprintf(f, "\\begin{tikzpicture}\n");
}
static void tikz_setcolor(plotter_t *_self, const color_t *color)
{
decl_self(tikz_plotter_t, _self);
set_color(_self, color);
}
static void tikz_line(plotter_t *_self, int x1, int y1, int x2, int y2)
{
decl_self(tikz_plotter_t, _self);
fprintf(self->f, "\t\\draw (%d,%d) -- (%d,%d);\n", x1, y1, x2, y2);
}
static void tikz_box(plotter_t *_self, const rect_t *rect)
{
decl_self(tikz_plotter_t, _self);
fprintf(self->f, "\t\\draw (%d,%d) rectangle (%d, %d)\n",
rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
}
void tikz_text(plotter_t *_self, int x, int y, const char *str)
{
decl_self(tikz_plotter_t, _self);
fprintf(self->f, "\t\\draw (%d,%d) node {%s};\n", x, y, str);
}
static void tikz_finish(plotter_t *_self)
{
decl_self(tikz_plotter_t, _self);
fclose(self->f);
}
extern void plotter_free(plotter_t *self)
{
self->vtab->free(self);
......
......@@ -154,7 +154,7 @@ int nodes_interfere(const be_chordal_env_t *env, const ir_node *a, const ir_node
static be_ra_chordal_opts_t options = {
BE_CH_DUMP_ALL,
BE_CH_DUMP_NONE,
BE_CH_SPILL_BELADY,
BE_CH_COPYMIN_HEUR,
BE_CH_IFG_STD,
......@@ -186,6 +186,18 @@ static const lc_opt_enum_int_items_t lower_perm_items[] = {
{ NULL, 0 }
};
static const lc_opt_enum_int_items_t dump_items[] = {
{ "spill", BE_CH_DUMP_SPILL },
{ "live", BE_CH_DUMP_LIVE },
{ "color", BE_CH_DUMP_COLOR },
{ "copymin", BE_CH_DUMP_COPYMIN },
{ "ssadestr", BE_CH_DUMP_SSADESTR },
{ "tree", BE_CH_DUMP_TREE_INTV },
{ "constr", BE_CH_DUMP_CONSTR },
{ "lower", BE_CH_DUMP_LOWER },
{ NULL, 0 }
};
static lc_opt_enum_int_var_t spill_var = {
&options.spill_method, spill_items
};
......@@ -202,6 +214,10 @@ static lc_opt_enum_int_var_t lower_perm_var = {
&options.lower_perm_method, lower_perm_items
};
static lc_opt_enum_int_var_t dump_var = {
&options.dump_flags, dump_items
};
static void be_ra_chordal_register_options(lc_opt_entry_t *grp)
{
grp = lc_opt_get_grp(grp, "chordal");
......@@ -244,7 +260,6 @@ static void be_ra_chordal_main(const be_main_env_t *main_env, ir_graph *irg)
for(j = 0, m = arch_isa_get_n_reg_class(isa); j < m; ++j) {
chordal_env.cls = arch_isa_get_reg_class(isa, j);
chordal_env.border_heads = pmap_create();
chordal_env.constr_irn = pset_new_ptr(32);
be_liveness(irg);
dump(BE_CH_DUMP_LIVE, irg, chordal_env.cls, "-live", dump_ir_block_graph_sched);
......@@ -265,12 +280,6 @@ static void be_ra_chordal_main(const be_main_env_t *main_env, ir_graph *irg)
be_liveness(irg);
be_check_pressure(&chordal_env);
#if 0
/* Insert perms before reg-constrained instructions */
be_insert_constr_perms(&chordal_env);
dump(BE_CH_DUMP_CONSTR, irg, chordal_env.cls, "-constr", dump_ir_block_graph_sched);
#endif
be_liveness(irg);
be_check_pressure(&chordal_env);
......@@ -299,7 +308,6 @@ static void be_ra_chordal_main(const be_main_env_t *main_env, ir_graph *irg)
be_ifg_free(chordal_env.ifg);
pmap_destroy(chordal_env.border_heads);
del_pset(chordal_env.constr_irn);
}
be_compute_spill_offsets(&chordal_env);
......
......@@ -27,6 +27,8 @@
#include "bechordal.h"
#include "beirgmod.h"
typedef struct _be_ra_chordal_opts_t be_ra_chordal_opts_t;
/** Defines an invalid register index. */
#define NO_COLOR (-1)
......@@ -50,17 +52,16 @@ typedef struct _border_t {
* Environment for each of the chordal register allocator phases
*/
struct _be_chordal_env_t {
struct obstack obst; /**< An obstack for temporary storage. */
firm_dbg_module_t *dbg; /**< Debug module for the chordal register allocator. */
const be_main_env_t *main_env; /**< Environment with back-end data. */
dom_front_info_t *dom_front; /**< Dominance frontiers. */
ir_graph *irg; /**< The graph under examination. */
const arch_register_class_t *cls; /**< The current register class. */
pmap *border_heads; /**< Maps blocks to border heads. */
pset *constr_irn; /**< Nodes which deserve special constraint handling. */
be_ifg_t *ifg; /**< The interference graph. */
void *data; /**< Some pointer, to which different
phases can attach data to. */
struct obstack obst; /**< An obstack for temporary storage. */
be_ra_chordal_opts_t *opts; /**< A pointer to the chordal ra options. */
firm_dbg_module_t *dbg; /**< Debug module for the chordal register allocator. */
const be_main_env_t *main_env; /**< Environment with back-end data. */
dom_front_info_t *dom_front; /**< Dominance frontiers. */
ir_graph *irg; /**< The graph under examination. */
const arch_register_class_t *cls; /**< The current register class. */
pmap *border_heads; /**< Maps blocks to border heads. */
be_ifg_t *ifg; /**< The interference graph. */
void *data; /**< Some pointer, to which different phases can attach data to. */
};
static INLINE struct list_head *_get_block_border_head(const be_chordal_env_t *inf, ir_node *bl) {
......@@ -110,7 +111,7 @@ enum {
BE_CH_LOWER_PERM_COPY = 2
};
typedef struct {
struct _be_ra_chordal_opts_t {
unsigned dump_flags;
int spill_method;
int copymin_method;
......@@ -119,7 +120,7 @@ typedef struct {
char ilp_server[128];
char ilp_solver[128];
} be_ra_chordal_opts_t;
};
#endif /* _BECHORDAL_T_H */
......@@ -198,7 +198,7 @@ static void co_collect_units(ir_node *irn, void *env) {
/* Src == Tgt of a 2-addr-code instruction */
if (is_2addr_code(get_arch_env(co), irn, &req)) {
ir_node *other = req.other;
ir_node *other = req.other_same;
if (!nodes_interfere(co->chordal_env, irn, other)) {
unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
unit->costs = xmalloc(2 * sizeof(*unit->costs));
......@@ -284,7 +284,7 @@ int is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
if(is_Reg_Phi(n) ||
is_Perm(aenv, n) ||
(arch_register_req_is(&req, should_be_same) && req.other == irn)
(arch_register_req_is(&req, should_be_same) && req.other_same == irn)
)
return 1;
}
......
......@@ -119,52 +119,48 @@ pset *be_get_dominance_frontier(dom_front_info_t *info, ir_node *block)
return pmap_get(info->df_map, block);
}
static void determine_phi_blocks(ir_node *orig, pset *copies,
pset *copy_blocks, pset *phi_blocks, dom_front_info_t *df_info)
static void determine_phi_blocks(pset *copies, pset *copy_blocks, pset *phi_blocks, dom_front_info_t *df_info)
{
ir_node *bl;
ir_node *orig_block = get_nodes_block(orig);
pdeq *worklist = new_pdeq();
firm_dbg_module_t *dbg = DBG_MODULE;
/*
* Fill the worklist queue and the rest of the orig blocks array.
*/
for(bl = pset_first(copy_blocks); bl; bl = pset_next(copy_blocks)) {
assert(block_dominates(orig_block, bl)
&& "The block of the copy must be dominated by the block of the value");
pdeq *worklist = new_pdeq();
firm_dbg_module_t *dbg = DBG_MODULE;
/*
* Fill the worklist queue and the rest of the orig blocks array.
*/
for(bl = pset_first(copy_blocks); bl; bl = pset_next(copy_blocks)) {
pdeq_putr(worklist, bl);
}
pdeq_putr(worklist, bl);
}
while(!pdeq_empty(worklist)) {
ir_node *bl = pdeq_getl(worklist);
pset *df = be_get_dominance_frontier(df_info, bl);
while(!pdeq_empty(worklist)) {
ir_node *bl = pdeq_getl(worklist);
ir_node *y;
pset *df = be_get_dominance_frontier(df_info, bl);
ir_node *y;
DBG((dbg, LEVEL_3, "dom front of %+F\n", bl));
for(y = pset_first(df); y; y = pset_next(df))
DBG((dbg, LEVEL_3, "\t%+F\n", y));
DBG((dbg, LEVEL_3, "dom front of %+F\n", bl));
for(y = pset_first(df); y; y = pset_next(df))
DBG((dbg, LEVEL_3, "\t%+F\n", y));
for(y = pset_first(df); y; y = pset_next(df)) {
if(!pset_find_ptr(phi_blocks, y)) {
pset_insert_ptr(phi_blocks, y);
for(y = pset_first(df); y; y = pset_next(df)) {
if(!pset_find_ptr(phi_blocks, y)) {
pset_insert_ptr(phi_blocks, y);
/*
* Clear the link field of a possible phi block, since
* the possibly created phi will be stored there. See,
* search_def()
*/
* Clear the link field of a possible phi block, since
* the possibly created phi will be stored there. See,
* search_def()
*/
set_irn_link(y, NULL);
if(!pset_find_ptr(copy_blocks, y))
pdeq_putr(worklist, y);
}
}
}
}
}
}
del_pdeq(worklist);
del_pdeq(worklist);
}
/**
......@@ -187,49 +183,47 @@ static void determine_phi_blocks(ir_node *orig, pset *copies,
* original node.
* @return The valid copy for usage.
*/
static ir_node *search_def(ir_node *usage, int pos, pset *copies,
pset *copy_blocks, pset *phi_blocks, ir_mode *mode)
static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks, pset *phi_blocks, ir_mode *mode)
{
ir_node *curr_bl;
ir_node *start_irn;
firm_dbg_module_t *dbg = DBG_MODULE;
curr_bl = get_nodes_block(usage);
DBG((dbg, LEVEL_1, "Searching valid def for use %+F at pos %d\n", usage, pos));
/*
* If the usage is in a phi node, search the copy in the
* predecessor denoted by pos.
*/
if(is_Phi(usage)) {