2 * Author: Matthias Braun
4 * Copyright: (c) Universitaet Karlsruhe
5 * License: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
22 typedef struct be_verify_register_pressure_env_t_ {
24 const arch_env_t *arch_env;
25 const arch_register_class_t *cls;
26 int registers_available;
28 } be_verify_register_pressure_env_t;
30 static void print_living_values(pset *live_nodes)
35 foreach_pset(live_nodes, node) {
36 ir_printf("%+F ", node);
41 static void verify_liveness_walker(ir_node *bl, void *data)
43 be_verify_register_pressure_env_t *env = (be_verify_register_pressure_env_t*) data;
45 pset *live_nodes = pset_new_ptr_default();
48 // collect register pressure info
49 be_liveness_end_of_block(env->arch_env, env->cls, bl, live_nodes);
50 pressure = pset_count(live_nodes);
51 if(pressure > env->registers_available) {
52 ir_printf("Verify Warning: Register pressure too high at end of block %+F(%s) (%d/%d):\n",
53 bl, get_irg_dump_name(env->irg), pressure, env->registers_available);
54 print_living_values(live_nodes);
55 env->problem_found = 1;
57 sched_foreach_reverse(bl, irn) {
63 be_liveness_transfer(env->arch_env, env->cls, irn, live_nodes);
64 pressure = pset_count(live_nodes);
66 if(pressure > env->registers_available) {
67 ir_printf("Verify Warning: Register pressure too high before %+F (in block %+F(%s) (%d/%d).\n",
68 irn, bl, get_irg_dump_name(env->irg), pressure, env->registers_available);
69 print_living_values(live_nodes);
70 env->problem_found = 1;
76 int be_verify_register_pressure(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_graph *irg)
78 be_verify_register_pressure_env_t env;
83 env.arch_env = arch_env;
85 env.registers_available = arch_count_non_ignore_regs(arch_env, cls);
86 env.problem_found = 0;
88 return !env.problem_found;
91 typedef struct be_verify_schedule_env_t_ {
94 } be_verify_schedule_env_t;
96 static void verify_schedule_walker(ir_node *bl, void *data)
98 be_verify_schedule_env_t *env = (be_verify_schedule_env_t*) data;
100 int non_phi_found = 0;
101 int cfchange_found = 0;
102 // TODO ask ABI about delay branches
103 int delay_branches = 0;
106 * Make sure that all phi nodes are scheduled at the beginning of the block, and that there
107 * is 1 or no control flow changing node scheduled as last operation
109 sched_foreach(bl, irn) {
112 ir_printf("Verify Warning: Phi node %+F scheduled after non-Phi nodes in block %+F (%s)\n",
113 irn, bl, get_irg_dump_name(env->irg));
114 env->problem_found = 1;
120 if(is_cfop(irn) && get_irn_opcode(irn) != iro_Start) {
121 if(cfchange_found == 1) {
122 ir_printf("Verify Warning: More than 1 control flow changing node (%+F) scheduled in block %+F (%s)\n",
123 irn, bl, get_irg_dump_name(env->irg));
124 env->problem_found = 1;
127 } else if(cfchange_found) {
128 if(delay_branches == 0) {
129 ir_printf("Verify Warning: Node %+F scheduled after control flow changing node (+delay branches) in block %+F (%s)\n",
130 irn, bl, get_irg_dump_name(env->irg));
131 env->problem_found = 1;
138 if(cfchange_found && delay_branches != 0) {
139 ir_printf("Not all delay slots filled after jump (%d/%d) in block %+F (%s)\n",
140 bl, get_irg_dump_name(env->irg));
141 env->problem_found = 1;
145 int be_verify_schedule(ir_graph *irg)
147 be_verify_schedule_env_t env;
149 env.problem_found = 0;
152 irg_block_walk_graph(irg, verify_schedule_walker, NULL, &env);
154 return !env.problem_found;