+
+struct _elr_closure_t {
+ struct obstack obst;
+ const be_chordal_env_t *cenv;
+};
+
+static void elr_split_walker(ir_node *bl, void *data)
+{
+ struct _elr_closure_t *c = data;
+ const be_chordal_env_t *cenv = c->cenv;
+ const arch_env_t *aenv = cenv->birg->main_env->arch_env;
+ be_lv_t *lv = cenv->birg->lv;
+ be_dom_front_info_t *dom_front = cenv->birg->dom_front;
+ be_insn_t *insn;
+ be_insn_env_t ie;
+
+ be_insn_env_init(&ie, cenv->birg, cenv->cls, &c->obst);
+
+ for(insn = be_scan_insn(&ie, sched_first(bl)); !is_Block(insn->irn); insn = be_scan_insn(&ie, insn->next_insn)) {
+ ir_node *pred = sched_prev(insn->irn);
+ if(!is_Block(pred) && !is_Phi(insn->irn))
+ insert_Perm_after(aenv, lv, cenv->cls, dom_front, insn->irn);
+ }
+}
+
+void extreme_liverange_splitting(struct _be_chordal_env_t *cenv)
+{
+ struct _elr_closure_t c;
+ be_lv_t *lv = cenv->birg->lv;
+
+ c.cenv = cenv;
+ obstack_init(&c.obst);
+ be_liveness_recompute(lv);
+ irg_block_walk_graph(cenv->irg, elr_split_walker, NULL, &c);
+ be_liveness_recompute(lv);
+ obstack_free(&c.obst, NULL);
+}
+
+/**
+ * Post-block-walker: Find blocks containing only one jump and
+ * remove them.
+ */
+static void remove_empty_block(ir_node *block, void *data) {
+ const ir_edge_t *edge, *next;
+ ir_node *node;
+ int *changed = data;
+ ir_node *jump = NULL;
+
+ assert(is_Block(block));
+
+ if (get_Block_n_cfgpreds(block) != 1)
+ return;
+
+ sched_foreach(block, node) {
+ if (! is_Jmp(node))
+ return;
+ if (jump != NULL) {
+ /* we should never have 2 jumps in a block */
+ assert(0 && "We should never have 2 jumps in a block");
+ return;
+ }
+ jump = node;
+ }
+
+ if (jump == NULL)
+ return;
+
+ node = get_Block_cfgpred(block, 0);
+ foreach_out_edge_safe(jump, edge, next) {
+ ir_node *block = get_edge_src_irn(edge);
+ int pos = get_edge_src_pos(edge);
+
+ set_irn_n(block, pos, node);
+ }
+
+ set_Block_cfgpred(block, 0, new_Bad());
+ sched_remove(jump);
+ *changed = 1;
+}
+
+/* removes basic blocks that just contain a jump instruction */
+int be_remove_empty_blocks(ir_graph *irg) {
+ int changed = 0;
+
+ irg_block_walk_graph(irg, remove_empty_block, NULL, &changed);
+ if (changed) {
+ /* invalidate analysis info */
+ set_irg_doms_inconsistent(irg);
+ set_irg_extblk_inconsistent(irg);
+ set_irg_outs_inconsistent(irg);
+ }
+ return changed;
+}
+
+void be_init_irgmod(void)
+{
+ FIRM_DBG_REGISTER(dbg, "firm.be.irgmod");
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_irgmod);