X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fcritical_edges.c;h=4717244ebba3bd4cc5713413fb6da6c8ebd5e842;hb=ce6161a7e42a48f7422b7babcc64d8ace18e2687;hp=1e2284adf557fc910b071cc6f03d3fcdc3da3d9f;hpb=86f5ed335727adaa9e6550254fb6d2726982bf33;p=libfirm diff --git a/ir/opt/critical_edges.c b/ir/opt/critical_edges.c index 1e2284adf..4717244eb 100644 --- a/ir/opt/critical_edges.c +++ b/ir/opt/critical_edges.c @@ -24,9 +24,7 @@ * Michael Beck * @version $Id$ */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #include "irop_t.h" #include "irnode_t.h" @@ -48,10 +46,11 @@ typedef struct cf_env { * @param n IR node * @param env Environment of walker. */ -static void walk_critical_cf_edges(ir_node *n, void *env) { +static void walk_critical_cf_edges(ir_node *n, void *env) +{ int arity, i; ir_node *pre, *block, *jmp; - cf_env *cenv = env; + cf_env *cenv = (cf_env*)env; ir_graph *irg = get_irn_irg(n); /* Block has multiple predecessors */ @@ -74,6 +73,12 @@ static void walk_critical_cf_edges(ir_node *n, void *env) { continue; goto insert; } + if (is_IJmp(pre)) { + /* we can't add blocks in between ijmp and its destinations + * TODO: What now, we can't split all critical edges because of this... */ + fprintf(stderr, "libfirm warning: Couldn't split all critical edges (compiler will probably fail now)\n"); + continue; + } /* we don't want place nodes in the start block, so handle it like forking */ if (is_op_forking(cfop) || cfop == op_Start) { /* Predecessor has multiple successors. Insert new control flow edge edges. */ @@ -81,7 +86,7 @@ insert: /* set predecessor of new block */ block = new_r_Block(irg, 1, &pre); /* insert new jmp node to new block */ - jmp = new_r_Jmp(irg, block); + jmp = new_r_Jmp(block); /* set successor of new block */ set_irn_n(n, i, jmp); cenv->changed = 1; @@ -90,10 +95,11 @@ insert: } /* n is a multi-entry block */ } -void remove_critical_cf_edges(ir_graph *irg) { +void remove_critical_cf_edges_ex(ir_graph *irg, int ignore_exception_edges) +{ cf_env env; - env.ignore_exc_edges = 1; + env.ignore_exc_edges = (char)ignore_exception_edges; env.changed = 0; irg_block_walk_graph(irg, NULL, walk_critical_cf_edges, &env); @@ -105,3 +111,8 @@ void remove_critical_cf_edges(ir_graph *irg) { set_irg_loopinfo_inconsistent(irg); } } + +void remove_critical_cf_edges(ir_graph *irg) +{ + remove_critical_cf_edges_ex(irg, 1); +}