* @date 05.05.2006
* @version $Id$
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
#include <limits.h>
#include "beverify.h"
#include "belive.h"
-#include "besched_t.h"
-#include "benode_t.h"
-#include "beirg_t.h"
+#include "besched.h"
+#include "benode.h"
+#include "beirg.h"
#include "beintlive_t.h"
static int my_values_interfere(const ir_node *a, const ir_node *b);
typedef struct be_verify_register_pressure_env_t_ {
ir_graph *irg; /**< the irg to verify */
be_lv_t *lv; /**< Liveness information. */
- const arch_env_t *arch_env; /**< an architecture environment */
const arch_register_class_t *cls; /**< the register class to check for */
int registers_available; /**< number of available registers */
int problem_found; /**< flag indicating if a problem was found */
/* collect register pressure info, start with end of a block */
// ir_fprintf(stderr, "liveness check %+F\n", block);
ir_nodeset_init(&live_nodes);
- be_liveness_end_of_block(env->lv, env->arch_env, env->cls, block,
+ be_liveness_end_of_block(env->lv, env->cls, block,
&live_nodes);
// print_living_values(stderr, &live_nodes);
break;
// print_living_values(stderr, &live_nodes);
- be_liveness_transfer(env->arch_env, env->cls, irn, &live_nodes);
+ be_liveness_transfer(env->cls, irn, &live_nodes);
pressure = ir_nodeset_size(&live_nodes);
ir_graph *irg) {
be_verify_register_pressure_env_t env;
- env.lv = be_liveness(birg);
+ env.lv = be_liveness(irg);
env.irg = irg;
- env.arch_env = birg->main_env->arch_env;
env.cls = cls;
env.registers_available = env.cls->n_regs - be_put_ignore_regs(birg, env.cls, NULL);
env.problem_found = 0;
int problem_found; /**< flags indicating if there was a problem */
bitset_t *scheduled; /**< bitset of scheduled nodes */
ir_graph *irg; /**< the irg to check */
- const arch_env_t *arch_env; /**< the arch_env */
} be_verify_schedule_env_t;
/**
env->problem_found = 1;
}
- if(be_is_Keep(node)) {
+ if(be_is_Keep(node) || be_is_CopyKeep(node)) {
/* at least 1 of the keep arguments has to be it schedule
* predecessor */
int arity = get_irn_arity(node);
int problem = 1;
ir_node *prev = sched_prev(node);
- while(be_is_Keep(prev))
+ while(be_is_Keep(prev) || be_is_CopyKeep(prev))
prev = sched_prev(prev);
for(i = 0; i < arity; ++i) {
static int should_be_scheduled(ir_node *node)
{
- if(is_Block(node))
- return -1;
-
- if(is_Proj(node))
- return 0;
-
- if(get_irn_mode(node) == mode_M) {
- if(is_Phi(node) || is_Sync(node) || is_Pin(node))
- return 0;
- }
- if(be_is_Keep(node) && get_irn_opcode(get_nodes_block(node)) == iro_Bad)
- return 0;
-
switch(get_irn_opcode(node)) {
+ case iro_Bad:
+ case iro_Block:
case iro_End:
case iro_NoMem:
- case iro_Bad:
+ case iro_Pin:
+ case iro_Proj:
+ case iro_Sync:
case iro_Unknown:
return 0;
+ case iro_Phi:
+ if (get_irn_mode(node) == mode_M)
+ return 0;
+ break;
+ case iro_Start:
+ case iro_Jmp:
+ case beo_Return:
+ return 1;
default:
break;
}
- if (arch_irn_get_flags(node) & arch_irn_flags_ignore)
- return -1;
+ if (get_irn_mode(node) != mode_T) {
+ if (arch_irn_is_ignore(node))
+ return -1;
+ }
return 1;
}
env.problem_found = 0;
env.irg = be_get_birg_irg(birg);
env.scheduled = bitset_alloca(get_irg_last_idx(env.irg));
- env.arch_env = birg->main_env->arch_env;
irg_block_walk_graph(env.irg, verify_schedule_walker, NULL, &env);
/* check if all nodes are scheduled */
} spill_t;
typedef struct {
- const arch_env_t *arch_env;
- ir_graph *irg;
- set *spills;
- ir_node **reloads;
- int problem_found;
+ ir_graph *irg;
+ set *spills;
+ ir_node **reloads;
+ int problem_found;
} be_verify_spillslots_env_t;
static int cmp_spill(const void* d1, const void* d2, size_t size) {
}
}
-static void check_spillslot_interference(be_verify_spillslots_env_t *env) {
- int spillcount = set_count(env->spills);
- spill_t **spills = alloca(spillcount * sizeof(spills[0]));
- spill_t *spill;
- int i;
+static void check_spillslot_interference(be_verify_spillslots_env_t *env)
+{
+ int spillcount = set_count(env->spills);
+ spill_t **spills = ALLOCAN(spill_t*, spillcount);
+ spill_t *spill;
+ int i;
for(spill = set_first(env->spills), i = 0; spill != NULL; spill = set_next(env->spills), ++i) {
spills[i] = spill;
}
}
-int be_verify_spillslots(const arch_env_t *arch_env, ir_graph *irg)
+int be_verify_spillslots(ir_graph *irg)
{
be_verify_spillslots_env_t env;
- env.arch_env = arch_env;
env.irg = irg;
env.spills = new_set(cmp_spill, 10);
env.reloads = NEW_ARR_F(ir_node*, 0);
static const arch_register_class_t *regclass;
static ir_node **registers;
-static void check_register_constraints(ir_node *node)
+static void check_output_constraints(ir_node *node)
{
- const arch_register_t *reg;
- int i, arity;
-
/* verify output register */
- if (arch_get_irn_reg_class(node, -1) != NULL) {
- reg = arch_get_irn_register(node);
+ if (arch_get_irn_reg_class_out(node) == regclass) {
+ const arch_register_t *reg = arch_get_irn_register(node);
if (reg == NULL) {
ir_fprintf(stderr, "Verify warning: Node %+F in block %+F(%s) should have a register assigned\n",
node, get_nodes_block(node), get_irg_dump_name(irg));
problem_found = 1;
- } else if (!arch_register_type_is(reg, joker) && !arch_reg_is_allocatable(node, -1, reg)) {
+ } else if (!arch_register_type_is(reg, joker) && !arch_reg_out_is_allocatable(node, reg)) {
ir_fprintf(stderr, "Verify warning: Register %s assigned as output of %+F not allowed (register constraint) in block %+F(%s)\n",
reg->name, node, get_nodes_block(node), get_irg_dump_name(irg));
problem_found = 1;
}
}
+}
+
+static void check_input_constraints(ir_node *node)
+{
+ const arch_register_t *reg;
+ int i, arity;
/* verify input register */
arity = get_irn_arity(node);
}
}
-static void value_used(ir_node *node) {
+static void value_used(ir_node *block, ir_node *node) {
const arch_register_t *reg;
ir_node *reg_node;
- if (arch_get_irn_reg_class(node, -1) != regclass)
+ if (arch_get_irn_reg_class_out(node) != regclass)
return;
reg = arch_get_irn_register(node);
- if (reg->type & arch_register_type_virtual)
+ if (reg == NULL || reg->type & arch_register_type_virtual)
return;
reg_node = registers[reg->index];
if (reg_node != NULL && reg_node != node) {
ir_fprintf(stderr, "Verify warning: Register %s assigned more than once in block %+F(%s) (nodes %+F %+F)\n",
- reg->name, get_nodes_block(node), get_irg_dump_name(irg),
+ reg->name, block, get_irg_dump_name(irg),
node, reg_node);
problem_found = 1;
}
const arch_register_t *reg;
ir_node *reg_node;
- if (arch_get_irn_reg_class(node, -1) != regclass)
+ if (arch_get_irn_reg_class_out(node) != regclass)
return;
reg = arch_get_irn_register(node);
- if (reg->type & arch_register_type_virtual)
+ if (reg == NULL || reg->type & arch_register_type_virtual)
return;
reg_node = registers[reg->index];
nregclasses = arch_env_get_n_reg_class(arch_env);
for (i = 0; i < nregclasses; ++i) {
- ir_node *node;
- int idx, i2, n_regs;
+ ir_node *node;
+ int idx, i2, n_regs;
regclass = arch_env_get_reg_class(arch_env, i);
assert(lv->nodes && "live sets must be computed");
n_regs = arch_register_class_n_regs(regclass);
- registers = alloca(n_regs * sizeof(registers[0]));
- memset(registers, 0, n_regs * sizeof(registers[0]));
+ registers = ALLOCANZ(ir_node*, n_regs);
be_lv_foreach(lv, block, be_lv_state_end, idx) {
ir_node *node = be_lv_get_irn(lv, block, idx);
- value_used(node);
+ value_used(block, node);
}
sched_foreach_reverse(block, node) {
foreach_out_edge(node, edge) {
ir_node *def = get_edge_src_irn(edge);
value_def(def);
+ check_output_constraints(def);
}
} else {
value_def(node);
+ check_output_constraints(node);
}
- check_register_constraints(node);
- if (is_Phi(node))
- continue;
+ check_input_constraints(node);
- arity = get_irn_arity(node);
- for (i2 = 0; i2 < arity; ++i2) {
- ir_node *use = get_irn_n(node, i2);
- value_used(use);
+ /* process uses. (Phi inputs are no real uses) */
+ if (!is_Phi(node)) {
+ arity = get_irn_arity(node);
+ for (i2 = 0; i2 < arity; ++i2) {
+ ir_node *use = get_irn_n(node, i2);
+ value_used(block, use);
+ }
}
}
int be_verify_register_allocation(const be_irg_t *birg) {
arch_env = be_get_birg_arch_env(birg);
irg = be_get_birg_irg(birg);
- lv = be_liveness(birg);
+ lv = be_liveness(irg);
problem_found = 0;
be_liveness_assure_sets(lv);
int be_verify_out_edges(ir_graph *irg) {
verify_out_dead_nodes_env env;
+return 1;
env.irg = irg;
env.reachable = bitset_alloca(get_irg_last_idx(irg));
env.problem_found = edges_verify(irg);