}
}
- be_verify_register_allocation(main_env->arch_env, irg);
-
+ be_verify_register_allocation(birg);
BE_TIMER_PUSH(ra_timer.t_epilog);
lower_nodes_after_ra(birg, options.lower_perm_opt & BE_CH_LOWER_PERM_COPY ? 1 : 0);
#include "execfreq.h"
#include "beirg_t.h"
+#include "absgraph.h"
be_lv_t *be_assure_liveness(be_irg_t *birg)
{
if (birg->lv != NULL)
return birg->lv;
- return birg->lv = be_liveness(birg->irg);
+ return birg->lv = be_liveness(birg);
}
void be_assure_dom_front(be_irg_t *birg)
#include "irdump_t.h"
#include "irnodeset.h"
+#include "dfs_t.h"
+#include "absgraph.h"
+
#include "beutil.h"
#include "belive_t.h"
#include "beirg_t.h"
#define LV_USE_BINARY_SEARCH
#undef LV_INTESIVE_CHECKS
+void be_live_chk_compare(be_lv_t *lv, lv_chk_t *lvc);
+
static INLINE int is_liveness_node(const ir_node *irn)
{
switch(get_irn_opcode(irn)) {
ir_node *use = edge->src;
ir_node *use_block;
+ DBG((dbg, LEVEL_4, "%+F: use at %+F, pos %d in %+F\n", irn, use, edge->pos, get_block(use)));
+ assert(get_irn_n(use, edge->pos) == irn);
+
/*
* If the usage is no data node, skip this use, since it does not
* affect the liveness of the node.
lv->nodes = bitset_malloc(2 * get_irg_last_idx(lv->irg));
phase_init(&lv->ph, "liveness", lv->irg, PHASE_DEFAULT_GROWTH, lv_phase_data_init, NULL);
compute_liveness(lv);
+ /* be_live_chk_compare(lv, lv->lvc); */
}
}
}
/* Compute the inter block liveness for a graph. */
-be_lv_t *be_liveness(ir_graph *irg)
+be_lv_t *be_liveness(const be_irg_t *birg)
{
be_lv_t *lv = xmalloc(sizeof(lv[0]));
memset(lv, 0, sizeof(lv[0]));
- lv->irg = irg;
+ lv->irg = be_get_birg_irg(birg);
+ lv->birg = birg;
#ifdef USE_LIVE_CHK
- lv->lvc = lv_chk_new(irg);
+ lv->dfs = dfs_new(&absgraph_irg_cfg_succ, lv->irg);
+ lv->lvc = lv_chk_new(lv->irg, lv->dfs);
#endif
lv->hook_info.context = lv;
lv->hook_info.hook._hook_node_info = lv_dump_block;
void be_liveness_check(be_lv_t *lv)
{
struct _lv_walker_t w;
- be_lv_t *fresh = be_liveness(lv->irg);
+ be_lv_t *fresh = be_liveness(lv->birg);
w.lv = lv;
w.data = fresh;
#include "bearch.h"
#include "irnodeset.h"
+struct be_irg_t;
+
typedef enum {
be_lv_state_in = 1,
be_lv_state_end = 2,
* Compute the inter block liveness for a graph.
* @param irg The graph.
*/
-be_lv_t *be_liveness(ir_graph *irg);
+be_lv_t *be_liveness(const struct be_irg_t *birg);
/**
* Check the given liveness information against a freshly computed one.
#include "irgraph_t.h"
#include "irphase_t.h"
#include "irhooks.h"
+#include "dfs.h"
#include "pset.h"
#include "bitset.h"
#include "irlivechk.h"
#endif
+struct be_irg_t;
+
struct _be_lv_t {
ir_phase ph;
ir_graph *irg;
+ dfs_t *dfs;
+ const struct be_irg_t *birg;
bitset_t *nodes;
hook_entry_t hook_info;
#ifdef USE_LIVE_CHK
/* reset the phi handler. */
be_phi_handler_reset(env.phi_handler);
-#ifdef FIRM_STATISTICS
- stat_ev_ctx_push_fobj("irg", irg);
-#endif
+ stat_ev_ctx_push_fobj("bemain_irg", irg);
/* stop and reset timers */
BE_TIMER_ONLY(
}
/* generate code */
+ stat_ev_ctx_push("bemain_phase", "prepare");
BE_TIMER_PUSH(t_codegen);
arch_code_generator_prepare_graph(birg->cg);
BE_TIMER_POP(t_codegen);
+ stat_ev_ctx_pop();
/* reset the phi handler. */
be_phi_handler_reset(env.phi_handler);
/* be_live_chk_compare(birg); */
/* let backend prepare scheduling */
+ stat_ev_ctx_push("bemain_phase", "before_sched");
BE_TIMER_PUSH(t_codegen);
arch_code_generator_before_sched(birg->cg);
BE_TIMER_POP(t_codegen);
+ stat_ev_ctx_pop();
/* schedule the irg */
BE_TIMER_PUSH(t_sched);
be_check_dominance(irg);
be_verify_out_edges(irg);
be_verify_schedule(birg);
- be_verify_register_allocation(env.arch_env, irg);
+ be_verify_register_allocation(birg);
} else if (be_options.vrfy_option == BE_VRFY_ASSERT) {
assert(irg_verify(irg, VRFY_ENFORCE_SSA) && "irg verification failed");
assert(be_verify_out_edges(irg) && "out edge verification failed");
assert(be_check_dominance(irg) && "Dominance verification failed");
assert(be_verify_schedule(birg) && "Schedule verification failed");
- assert(be_verify_register_allocation(env.arch_env, irg)
+ assert(be_verify_register_allocation(birg)
&& "register allocation verification failed");
}
const char *pos = dot ? dot : cup_name + strlen(cup_name);
char *buf = alloca(pos - cup_name + 1);
strncpy(buf, cup_name, pos - cup_name);
+ buf[pos - cup_name] = '\0';
stat_ev_begin(buf);
}
struct a_pressure_walker w;
w.birg = birg;
- w.lv = be_liveness(irg);
+ w.lv = be_liveness(birg);
/* Collect register pressure information for each block */
irg_block_walk_graph(irg, stat_reg_pressure_block, NULL, &w);
be_liveness_free(w.lv);
int pressure;
/* 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,
&live_nodes);
+ // print_living_values(stderr, &live_nodes);
pressure = ir_nodeset_size(&live_nodes);
if(pressure > env->registers_available) {
ir_fprintf(stderr, "Verify Warning: Register pressure too high at end of block %+F(%s) (%d/%d):\n",
if (is_Phi(irn))
break;
+ // print_living_values(stderr, &live_nodes);
be_liveness_transfer(env->arch_env, env->cls, irn, &live_nodes);
pressure = ir_nodeset_size(&live_nodes);
irn, block, get_irg_dump_name(env->irg), pressure, env->registers_available);
print_living_values(stderr, &live_nodes);
env->problem_found = 1;
+ assert(0);
}
}
ir_nodeset_destroy(&live_nodes);
ir_graph *irg) {
be_verify_register_pressure_env_t env;
- env.lv = be_liveness(irg);
+ env.lv = be_liveness(birg);
env.irg = irg;
env.arch_env = birg->main_env->arch_env;
env.cls = cls;
}
}
-int be_verify_register_allocation(const arch_env_t *arch_env, ir_graph *irg) {
+int be_verify_register_allocation(const be_irg_t *birg) {
be_verify_register_allocation_env_t env;
- env.arch_env = arch_env;
- env.irg = irg;
- env.lv = be_liveness(irg);
+ env.arch_env = be_get_birg_arch_env(birg);
+ env.irg = be_get_birg_irg(birg);
+ env.lv = be_liveness(birg);
env.problem_found = 0;
be_liveness_assure_sets(env.lv);
- irg_block_walk_graph(irg, verify_block_register_allocation, NULL, &env);
+ irg_block_walk_graph(env.irg, verify_block_register_allocation, NULL, &env);
be_liveness_free(env.lv);
* register assigned, also checks that each scheduled node has a register
* assigned.
*
- * @param irg The irg to check
- * @return 1 if verify succeeded, 0 otherwise
+ * @param birg The birg to check
+ * @return 1 if verify succeeded, 0 otherwise
*/
-int be_verify_register_allocation(const arch_env_t *arch_env, ir_graph *irg);
+int be_verify_register_allocation(const be_irg_t *birg);
/**
* Verify that out edges are valid