X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fifconv.c;h=9d9fab30024c63fd7682c86701864e6d1cd0f878;hb=629ae37a01e0b2a044025152cde4a7668ad25f6c;hp=ce27609c2d061b49717e988f850a5bea4b53092d;hpb=c4afe568ecb5fa16f1cafa3530673fbe7ccb3f19;p=libfirm diff --git a/ir/opt/ifconv.c b/ir/opt/ifconv.c index ce27609c2..9d9fab300 100644 --- a/ir/opt/ifconv.c +++ b/ir/opt/ifconv.c @@ -11,8 +11,20 @@ #if 1 +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif + #include -#include + +#include "obst.h" +#include "irnode_t.h" #include "cdep.h" #include "ircons.h" #include "ifconv.h" @@ -22,43 +34,65 @@ #include "irgwalk.h" #include "irtools.h" #include "return.h" -#include "xmalloc.h" +#include "array.h" // debug #include "irdump.h" -#include "irprintf.h" - +#include "debug.h" -static ir_node* walk_to_projx(ir_node* start) -{ - ir_node* pred; - ir_node* cdep; - - pred = get_nodes_block(start); - cdep = get_unique_cdep(pred); - if (cdep == NULL) return NULL; - - assert(get_irn_arity(pred) == 1); - pred = get_irn_n(pred, 0); - if (get_irn_op(pred) == op_Proj) { - assert(get_irn_mode(pred) == mode_X); - return pred; - } else { - return NULL; - } -} +DEBUG_ONLY(firm_dbg_module_t *dbg); +/** + * Additional block info. + */ typedef struct block_info { - ir_node* phi; - int evil; + ir_node *phi; /**< head of the Phi list */ + int has_pinned; /**< set if the block contains instructions that cannot be moved */ } block_info; -#define get_block_blockinfo(block) ((block_info*)get_irn_link(block)) +#define get_block_blockinfo(block) ((block_info *)get_irn_link(block)) + +/** + * Returns non-zero if a Block can be emptied. + */ +static int can_empty_block(ir_node *block) +{ + return !get_block_blockinfo(block)->has_pinned; +} + -static int can_empty_block(ir_node* block) +static ir_node* walk_to_projx(ir_node* start, const ir_node* dependency) { - return !get_block_blockinfo(block)->evil; + int arity; + int i; + + /* No need to find the conditional block if this block cannot be emptied and + * therefore not moved + */ + if (!can_empty_block(start)) return NULL; + + arity = get_irn_arity(start); + for (i = 0; i < arity; ++i) { + ir_node* pred = get_irn_n(start, i); + ir_node* pred_block = get_nodes_block(pred); + + if (pred_block == dependency) { + assert(is_Proj(pred)); + assert(get_irn_mode(pred) == mode_X); + return pred; + } + + if (is_Proj(pred)) { + assert(get_irn_mode(pred) == mode_X); + return NULL; + } + + if (is_cdep_on(pred_block, dependency)) { + return walk_to_projx(pred_block, dependency); + } + } + return NULL; } @@ -79,263 +113,281 @@ static ir_node* copy_to(ir_node* node, ir_node* src_block, int i) if (get_nodes_block(node) != src_block) return node; if (get_irn_op(node) == op_Phi) return get_irn_n(node, i); - copy_irn_to_irg(node, current_ir_graph); - copy = get_irn_link(node); + copy = exact_copy(node); dst_block = get_nodes_block(get_irn_n(src_block, i)); set_nodes_block(copy, dst_block); - ir_fprintf(stderr, "Copying node %+F to block %+F, copy is %+F\n", - node, dst_block, copy - ); + DB((dbg, LEVEL_1, "Copying node %+F to block %+F, copy is %+F\n", + node, dst_block, copy)); arity = get_irn_arity(node); for (j = 0; j < arity; ++j) { set_irn_n(copy, j, copy_to(get_irn_n(node, j), src_block, i)); - ir_fprintf(stderr, "-- pred %d is %+F\n", j, get_irn_n(copy, j)); + DB((dbg, LEVEL_2, "-- pred %d is %+F\n", j, get_irn_n(copy, j))); } return copy; } /** - * Duplicate and move the contents of ith block predecessor into its - * predecessors if the block has multiple control dependencies and only one - * successor. - * Also bail out if the block contains non-movable nodes, because later - * if-conversion would be pointless. + * Remove predecessors i and j from node and add predecessor new_pred + */ +static void rewire(ir_node* node, int i, int j, ir_node* new_pred) +{ + int arity = get_irn_arity(node); + ir_node **ins; + int k; + int l; + + NEW_ARR_A(ir_node *, ins, arity - 1); + + l = 0; + for (k = 0; k < i; ++k) ins[l++] = get_irn_n(node, k); + for (++k; k < j; ++k) ins[l++] = get_irn_n(node, k); + for (++k; k < arity; ++k) ins[l++] = get_irn_n(node, k); + ins[l++] = new_pred; + assert(l == arity - 1); + set_irn_in(node, l, ins); +} + + +/** + * Remove the jth predecessors from the ith predecessor of block and add it to block */ -static int fission_block(ir_node* block, int i) +static void split_block(ir_node* block, int i, int j) { - ir_node* pred = get_irn_n(block, i); - ir_node* pred_block; - block_info* info; + ir_node* pred_block = get_nodes_block(get_irn_n(block, i)); + int arity = get_irn_arity(block); + int new_pred_arity; ir_node* phi; - int pred_arity; - int arity; - ir_node** ins; - int j; + ir_node **ins; + ir_node **pred_ins; + int k; - if (get_irn_op(pred) != op_Jmp) return 0; - pred_block = get_nodes_block(pred); + DB((dbg, LEVEL_1, "Splitting predecessor %d of predecessor %d of %+F\n", j, i, block)); - if (!has_multiple_cdep(pred_block)) return 0; - if (!can_empty_block(pred_block)) return 0; + NEW_ARR_A(ir_node*, ins, arity + 1); - ir_fprintf(stderr, "Fissioning block %+F\n", pred_block); + for (phi = get_block_blockinfo(block)->phi; phi != NULL; phi = get_irn_link(phi)) { + ir_node* copy = copy_to(get_irn_n(phi, i), pred_block, j); - pred_arity = get_irn_arity(pred_block); - arity = get_irn_arity(block); - info = get_irn_link(block); - ins = xmalloc(sizeof(*ins) * (arity + pred_arity - 1)); - for (phi = info->phi; phi != NULL; phi = get_irn_link(phi)) { - for (j = 0; j < i; ++j) ins[j] = get_irn_n(phi, j); - for (j = 0; j < pred_arity; ++j) { - ins[i + j] = copy_to(get_irn_n(phi, i), pred_block, j); - } - for (j = i + 1; j < arity; ++j) { - ins[pred_arity - 1 + j] = get_irn_n(phi, j); + for (k = 0; k < i; ++k) ins[k] = get_irn_n(phi, k); + ins[k++] = copy; + for (; k < arity; ++k) ins[k] = get_irn_n(phi, k); + ins[k] = get_irn_n(phi, i); + assert(k == arity); + set_irn_in(phi, arity + 1, ins); + } + + for (k = 0; k < i; ++k) ins[k] = get_irn_n(block, k); + ins[k++] = get_irn_n(pred_block, j); + for (; k < arity; ++k) ins[k] = get_irn_n(block, k); + ins[k] = get_irn_n(block, i); + assert(k == arity); + set_irn_in(block, arity + 1, ins); + + new_pred_arity = get_irn_arity(pred_block) - 1; + NEW_ARR_A(ir_node*, pred_ins, new_pred_arity); + + for (phi = get_block_blockinfo(pred_block)->phi; phi != NULL; phi = get_irn_link(phi)) { + for (k = 0; k < j; ++k) pred_ins[k] = get_irn_n(phi, k); + for (; k < new_pred_arity; ++k) pred_ins[k] = get_irn_n(phi, k + 1); + assert(k == new_pred_arity); + if (new_pred_arity > 1) { + set_irn_in(phi, new_pred_arity, pred_ins); + } else { + exchange(phi, pred_ins[0]); } - set_irn_in(phi, arity + pred_arity - 1, ins); } - for (j = 0; j < i; ++j) ins[j] = get_irn_n(block, j); - for (j = 0; j < pred_arity; ++j) ins[i + j] = get_irn_n(pred_block, j); - for (j = i + 1; j < arity; ++j) ins[pred_arity - 1 + j] = get_irn_n(block, j); - set_irn_in(block, arity + pred_arity - 1, ins); - xfree(ins); - - /* Kill all Phis in the fissioned block - * This is to make sure they're not kept alive - */ - info = get_irn_link(pred_block); - phi = info->phi; - while (phi != NULL) { - ir_node* next = get_irn_link(phi); - exchange(phi, new_Bad()); - phi = next; + + for (k = 0; k < j; ++k) pred_ins[k] = get_irn_n(pred_block, k); + for (; k < new_pred_arity; ++k) pred_ins[k] = get_irn_n(pred_block, k + 1); + assert(k == new_pred_arity); + if (new_pred_arity > 1) { + set_irn_in(pred_block, new_pred_arity, pred_ins); + } else { + exchange(pred_block, get_nodes_block(pred_ins[0])); + } +} + + +static void prepare_path(ir_node* block, int i, const ir_node* dependency) +{ + ir_node* pred = get_nodes_block(get_irn_n(block, i)); + int pred_arity; + int j; + + DB((dbg, LEVEL_1, "Preparing predecessor %d of %+F\n", i, block)); + + pred_arity = get_irn_arity(pred); + for (j = 0; j < pred_arity; ++j) { + ir_node* pred_pred = get_nodes_block(get_irn_n(pred, j)); + + if (is_cdep_on(pred_pred, dependency)) { + prepare_path(pred, j, dependency); + split_block(block, i, j); + break; + } } - return 1; } static void if_conv_walker(ir_node* block, void* env) { - ir_node* phi; int arity; int i; - // Bail out, if there are no Phis at all + /* Bail out, if there are no Phis at all */ if (get_block_blockinfo(block)->phi == NULL) return; restart: - arity = get_irn_arity(block); - for (i = 0; i < arity; ++i) { - if (fission_block(block, i)) goto restart; - } - //return; - arity = get_irn_arity(block); for (i = 0; i < arity; ++i) { ir_node* pred; - ir_node* cond; - ir_node* projx0; - int j; - - projx0 = walk_to_projx(get_irn_n(block, i)); - if (projx0 == NULL) return; - pred = get_Proj_pred(projx0); - if (get_irn_op(pred) != op_Cond || get_irn_mode(get_Cond_selector(pred)) != mode_b) continue; - cond = pred; - - if (!can_empty_block(get_nodes_block(get_irn_n(block, i)))) { - ir_fprintf(stderr, "Cannot empty block %+F\n", - get_nodes_block(get_irn_n(block, i)) - ); - continue; - } + cdep* cdep; - for (j = i + 1; j < arity; ++j) { - ir_node* projx1; - ir_node* psi_block; - ir_node* conds[1]; - ir_node* vals[2]; - ir_node* psi; - - projx1 = walk_to_projx(get_irn_n(block, j)); - if (projx1 == NULL) continue; - pred = get_Proj_pred(projx1); - if (get_irn_op(pred) != op_Cond || get_irn_mode(get_Cond_selector(pred)) != mode_b) continue; - if (pred != cond) continue; - ir_fprintf(stderr, "Found Cond %+F with proj %+F and %+F\n", cond, projx0, projx1); - - if (!can_empty_block(get_nodes_block(get_irn_n(block, j)))) { - ir_fprintf(stderr, "Cannot empty block %+F\n", - get_nodes_block(get_irn_n(block, j)) - ); - continue; - } + pred = get_nodes_block(get_irn_n(block, i)); + for (cdep = find_cdep(pred); cdep != NULL; cdep = cdep->next) { + const ir_node* dependency = cdep->node; + ir_node* projx0 = walk_to_projx(pred, dependency); + ir_node* cond; + int j; - conds[0] = get_Cond_selector(cond); - - psi_block = get_nodes_block(cond); - phi = get_block_blockinfo(block)->phi; - do { - // Don't generate PsiMs - if (get_irn_mode(phi) == mode_M) { - /* Something is very fishy if to predecessors of a PhiM point into the - * block but not at the same memory node - */ - assert(get_irn_n(phi, i) == get_irn_n(phi, j)); - // fake memory Psi - psi = get_irn_n(phi, i); - ir_fprintf(stderr, "Handling memory Phi %+F\n", phi); - } else { - if (get_Proj_proj(projx0) == pn_Cond_true) { - vals[0] = get_irn_n(phi, i); - vals[1] = get_irn_n(phi, j); + if (projx0 == NULL) continue; + + cond = get_Proj_pred(projx0); + if (get_irn_op(cond) != op_Cond) continue; + /* We only handle boolean decisions, no switches */ + if (get_irn_mode(get_Cond_selector(cond)) != mode_b) continue; + + for (j = i + 1; j < arity; ++j) { + ir_node* projx1; + ir_node* conds[1]; + ir_node* vals[2]; + ir_node* psi; + ir_node* psi_block; + ir_node* phi; + + pred = get_nodes_block(get_irn_n(block, j)); + + if (!is_cdep_on(pred, dependency)) continue; + + projx1 = walk_to_projx(pred, dependency); + + if (projx1 == NULL) continue; + + DB((dbg, LEVEL_1, "Found Cond %+F with proj %+F and %+F\n", + cond, projx0, projx1 + )); + + prepare_path(block, i, dependency); + prepare_path(block, j, dependency); + arity = get_irn_arity(block); + + conds[0] = get_Cond_selector(cond); + + psi_block = get_nodes_block(cond); + phi = get_block_blockinfo(block)->phi; + do { + ir_node* val_i = get_irn_n(phi, i); + ir_node* val_j = get_irn_n(phi, j); + + if (val_i == val_j) { + psi = val_i; + DB((dbg, LEVEL_2, "Generating no psi, because both values are equal\n")); } else { - vals[0] = get_irn_n(phi, j); - vals[1] = get_irn_n(phi, i); + /* Something is very fishy if two predecessors of a PhiM point into + * one block, but not at the same memory node + */ + assert(get_irn_mode(phi) != mode_M); + if (get_Proj_proj(projx0) == pn_Cond_true) { + vals[0] = val_i; + vals[1] = val_j; + } else { + vals[0] = val_j; + vals[1] = val_i; + } + psi = new_r_Psi( + current_ir_graph, psi_block, 1, conds, vals, get_irn_mode(phi) + ); + DB((dbg, LEVEL_2, "Generating %+F for %+F\n", psi, phi)); + } + + if (arity == 2) { + exchange(phi, psi); + } else { + rewire(phi, i, j, psi); } - psi = new_r_Psi( - current_ir_graph, psi_block, 1, conds, vals, get_irn_mode(phi) - ); - ir_fprintf(stderr, "Generating %+F for %+F\n", psi, phi); - } + + phi = get_irn_link(phi); + } while (phi != NULL); + + exchange(get_nodes_block(get_irn_n(block, i)), psi_block); + exchange(get_nodes_block(get_irn_n(block, j)), psi_block); if (arity == 2) { - exchange(phi, psi); +#if 1 + DB((dbg, LEVEL_1, "Welding block %+F and %+F\n", block, psi_block)); + get_block_blockinfo(block)->has_pinned |= get_block_blockinfo(psi_block)->has_pinned; + set_irn_in(block, get_irn_arity(psi_block), get_irn_in(psi_block) + 1); + exchange_cdep(psi_block, block); + exchange(psi_block, block); +#else + DB((dbg, LEVEL_1, "Welding block %+F to %+F\n", block, psi_block)); + get_block_blockinfo(psi_block)->has_pinned |= get_block_blockinfo(block)->has_pinned; + exchange(block, psi_block); +#endif + return; } else { - ir_node** ins = xmalloc(sizeof(*ins) * (arity - 1)); - int k; - int l; - - l = 0; - for (k = 0; k < i; ++k) ins[l++] = get_irn_n(phi, k); - for (++k; k < j; ++k) ins[l++] = get_irn_n(phi, k); - for (++k; k < arity; ++k) ins[l++] = get_irn_n(phi, k); - ins[l++] = psi; - assert(l == arity - 1); - set_irn_in(phi, l, ins); - - xfree(ins); + rewire(block, i, j, new_r_Jmp(current_ir_graph, psi_block)); + goto restart; } - - phi = get_irn_link(phi); - } while (phi != NULL && get_irn_op(phi) == op_Phi); - - exchange(get_nodes_block(get_irn_n(block, i)), psi_block); - exchange(get_nodes_block(get_irn_n(block, j)), psi_block); - - if (arity == 2) { - ir_fprintf(stderr, "Welding block %+F to %+F\n", block, psi_block); - get_block_blockinfo(psi_block)->evil |= get_block_blockinfo(block)->evil; - exchange(block, psi_block); - return; - } else { - ir_node** ins = xmalloc(sizeof(*ins) * (arity - 1)); - int k; - int l; - - l = 0; - for (k = 0; k < i; ++k) ins[l++] = get_irn_n(block, k); - for (++k; k < j; ++k) ins[l++] = get_irn_n(block, k); - for (++k; k < arity; ++k) ins[l++] = get_irn_n(block, k); - ins[l++] = new_r_Jmp(current_ir_graph, psi_block); - assert(l == arity - 1); - set_irn_in(block, l, ins); - - xfree(ins); - goto restart; } } } } - -static void init_block_link(ir_node* block, void* env) +/** + * Block walker: add additional data + */ +static void init_block_link(ir_node *block, void *env) { - block_info* bi = xmalloc(sizeof(*bi)); + struct obstack *obst = env; + block_info *bi = obstack_alloc(obst, sizeof(*bi)); bi->phi = NULL; - bi->evil = 0; + bi->has_pinned = 0; set_irn_link(block, bi); } -/* Daisy-chain all phis in a block - * If a non-movable node is encountered set the evil flag +/** + * Daisy-chain all phis in a block + * If a non-movable node is encountered set the has_pinned flag */ -static void collect_phis(ir_node* node, void* env) +static void collect_phis(ir_node *node, void *env) { - ir_node* block; - block_info* bi; - - if (get_irn_op(node) == op_Block) return; + if (is_Phi(node)) { + ir_node *block = get_nodes_block(node); + block_info *bi = get_block_blockinfo(block); - block = get_nodes_block(node); - bi = get_irn_link(block); - - if (get_irn_op(node) == op_Phi) { set_irn_link(node, bi->phi); bi->phi = node; - } else { -#if 1 - if (get_irn_op(node) == op_Call || - get_irn_op(node) == op_Store || - get_irn_op(node) == op_Load) { - ir_fprintf(stderr, "Node %+F in block %+F is unmovable\n", node, block); - bi->evil = 1; - } -#else - if (get_irn_op(node) != op_Jmp && - get_irn_op(node) != op_Proj && - get_irn_op(node) != op_Cond && - get_irn_op(node) != op_Cmp && - !mode_is_datab(get_irn_mode(node))) { - ir_fprintf(stderr, "Node %+F in block %+F is unmovable\n", node, block); - bi->evil = 1; + } + else { + if (is_no_Block(node) && get_irn_pinned(node) == op_pin_state_pinned) { + /* + * Ignore control flow nodes, these will be removed. + * This ignores Raise. That is surely bad. FIXME. + */ + if (! is_cfop(node)) { + ir_node *block = get_nodes_block(node); + block_info *bi = get_block_blockinfo(block); + + DB((dbg, LEVEL_2, "Node %+F in block %+F is unmovable\n", node, block)); + bi->has_pinned = 1; + } } -#endif } } @@ -370,10 +422,10 @@ static ir_node* fold_psi(ir_node* psi) } if (arity == new_arity) return psi; // no attached Psis found - ir_fprintf(stderr, "Folding %+F from %d to %d conds\n", psi, arity, new_arity); + DB((dbg, LEVEL_1, "Folding %+F from %d to %d conds\n", psi, arity, new_arity)); - conds = xmalloc(new_arity * sizeof(*conds)); - vals = xmalloc((new_arity + 1) * sizeof(*vals)); + NEW_ARR_A(ir_node *, conds, new_arity); + NEW_ARR_A(ir_node *, vals, new_arity + 1); j = 0; for (i = 0; i < arity; ++i) { ir_node* c = get_Psi_cond(psi, i); @@ -414,10 +466,8 @@ static ir_node* fold_psi(ir_node* psi) current_ir_graph, get_nodes_block(psi), new_arity, conds, vals, get_irn_mode(psi) ); - ir_fprintf(stderr, "Folded %+F into new %+F\n", psi, new_psi); + DB((dbg, LEVEL_1, "Folded %+F into new %+F\n", psi, new_psi)); exchange(psi, new_psi); - xfree(vals); - xfree(conds); return new_psi; } @@ -425,7 +475,7 @@ static ir_node* fold_psi(ir_node* psi) /* * Merge consecutive psi inputs if the data inputs are the same */ -static void meld_psi(ir_node* psi) +static ir_node* meld_psi(ir_node* psi) { int arity = get_Psi_n_conds(psi); int new_arity; @@ -439,32 +489,30 @@ static void meld_psi(ir_node* psi) new_arity = 1; val = get_Psi_val(psi, 0); - ir_fprintf(stderr, "Pred 0 of %+F is %+F\n", psi, val); + DB((dbg, LEVEL_1, "Pred 0 of %+F is %+F\n", psi, val)); for (i = 1; i < arity; ++i) { ir_node* v = get_Psi_val(psi, i); - ir_fprintf(stderr, "Pred %2d of %+F is %+F\n", i, psi, v); + DB((dbg, LEVEL_1, "Pred %2d of %+F is %+F\n", i, psi, v)); if (val != v) { val = v; ++new_arity; } } - ir_fprintf(stderr, "Default of %+F is %+F\n", psi, get_Psi_default(psi)); + DB((dbg, LEVEL_1, "Default of %+F is %+F\n", psi, get_Psi_default(psi))); if (val == get_Psi_default(psi)) --new_arity; - ir_fprintf(stderr, "Melding Psi %+F from %d conds to %d\n", - psi, arity, new_arity - ); + DB((dbg, LEVEL_1, "Melding Psi %+F from %d conds to %d\n", psi, arity, new_arity)); - if (new_arity == arity) return; + if (new_arity == arity) return psi; - // If all data inputs of the Psi are equal, exchange the Psi with that value + /* If all data inputs of the Psi are equal, exchange the Psi with that value */ if (new_arity == 0) { exchange(psi, val); - return; + return val; } - conds = xmalloc(sizeof(*conds) * new_arity); - vals = xmalloc(sizeof(*vals) * (new_arity + 1)); + NEW_ARR_A(ir_node *, conds, new_arity); + NEW_ARR_A(ir_node *, vals, new_arity + 1); cond = get_Psi_cond(psi, 0); val = get_Psi_val(psi, 0); j = 0; @@ -494,8 +542,42 @@ static void meld_psi(ir_node* psi) current_ir_graph, get_nodes_block(psi), new_arity, conds, vals, get_irn_mode(psi) ); - ir_fprintf(stderr, "Molded %+F into %+F\n", psi, new_psi); + DB((dbg, LEVEL_1, "Molded %+F into %+F\n", psi, new_psi)); exchange(psi, new_psi); + return new_psi; +} + + +/** + * Split a Psi with multiple conditions into multiple Psis with one condtition + * each + */ +static ir_node* split_psi(ir_node* psi) +{ + int arity = get_Psi_n_conds(psi); + ir_mode* mode; + ir_node* block; + ir_node* rval; + int i; + + if (arity == 1) return psi; + + mode = get_irn_mode(psi); + block = get_nodes_block(psi); + rval = get_Psi_default(psi); + for (i = arity - 1; i >= 0; --i) { + ir_node* conds[1]; + ir_node* vals[2]; + + conds[0] = get_Psi_cond(psi, i); + vals[0] = get_Psi_val(psi, i); + vals[1] = rval; + rval = new_r_Psi( + current_ir_graph, block, 1, conds, vals, mode + ); + } + exchange(psi, rval); + return rval; } @@ -506,14 +588,24 @@ static void optimise_psis(ir_node* node, void* env) node = fold_psi(node); #endif #if 1 - meld_psi(node); + node = meld_psi(node); +#endif +#if 1 + node = split_psi(node); #endif } void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params) { - ir_fprintf(stderr, "Running if-conversion on %+F\n", irg); + struct obstack obst; + + if (!get_opt_if_conversion()) + return; + + FIRM_DBG_REGISTER(dbg, "firm.opt.ifconv"); + + DB((dbg, LEVEL_1, "Running if-conversion on %+F\n", irg)); dump_ir_block_graph(irg, "_00_pre"); @@ -523,18 +615,22 @@ void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params) dump_ir_block_graph(irg, "_01_normal"); compute_cdep(irg); - compute_doms(irg); + assure_doms(irg); - irg_block_walk_graph(irg, init_block_link, NULL, NULL); + obstack_init(&obst); + irg_block_walk_graph(irg, init_block_link, NULL, &obst); irg_walk_graph(irg, collect_phis, NULL, NULL); irg_block_walk_graph(irg, NULL, if_conv_walker, NULL); dump_ir_block_graph(irg, "_02_ifconv"); - local_optimize_graph(irg); + dump_ir_block_graph(irg, "_03_postopt"); + irg_walk_graph(irg, NULL, optimise_psis, NULL); - dump_ir_block_graph(irg, "_03_postifconv"); + dump_ir_block_graph(irg, "_04_postifconv"); + + obstack_free(&obst, NULL); free_dom(irg); free_cdep(irg); @@ -562,9 +658,6 @@ void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params) #ifdef HAVE_ALLOCA_H #include #endif -#ifdef HAVE_xmalloc_H -#include -#endif #include "irgraph_t.h" #include "irnode_t.h"