X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_blocks.c;h=3d7068228ca2a6fbf6f6ddc4c02cbb6333b837bc;hb=4e0288d4c454f3cded36e0b81e97be03dca528db;hp=eddaad7bb44c577435fd0cc08d81d68acce74cf8;hpb=4b295e5bec7e358e114e2585b1d16f33a11559a0;p=libfirm diff --git a/ir/opt/opt_blocks.c b/ir/opt/opt_blocks.c index eddaad7bb..3d7068228 100644 --- a/ir/opt/opt_blocks.c +++ b/ir/opt/opt_blocks.c @@ -1,27 +1,12 @@ /* - * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. - * * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. + * Copyright (C) 2012 University of Karlsruhe. */ /** * @file * @brief Combining congruent blocks * @author Michael Beck - * @version $Id$ * * This phase find congruent blocks. * Two block are congruent, if they contains only equal calculations. @@ -40,7 +25,7 @@ #include "set.h" #include "irpass.h" #include "debug.h" -#include "irtools.h" +#include "util.h" /* define this for general block shaping: congruent blocks are found not only before the end block but anywhere in the graph */ @@ -163,8 +148,7 @@ DEBUG_ONLY(static unsigned part_nr = 0;) */ static void dump_partition(const char *msg, const partition_t *part) { - const block_t *block; - int first = 1; + int first = 1; DB((dbg, LEVEL_2, " %s part%u (%u blocks) {\n ", msg, part->nr, part->n_blocks)); list_for_each_entry(block_t, block, &part->blocks, block_list) { @@ -172,7 +156,7 @@ static void dump_partition(const char *msg, const partition_t *part) first = 0; } DB((dbg, LEVEL_2, "\n }\n")); -} /* dump_partition */ +} /** * Dumps a list. @@ -188,7 +172,7 @@ static void dump_list(const char *msg, const block_t *block) first = 0; } DB((dbg, LEVEL_3, "\n }\n")); -} /* do_dump_list */ +} #else #define dump_partition(msg, part) #define dump_list(msg, block) @@ -204,7 +188,7 @@ static int listmap_cmp_ptr(const void *elt, const void *key, size_t size) (void) size; return e1->id != e2->id; -} /* listmap_cmp_ptr */ +} /** * Initializes a listmap. @@ -215,7 +199,7 @@ static void listmap_init(listmap_t *map) { map->map = new_set(listmap_cmp_ptr, 16); map->values = NULL; -} /* listmap_init */ +} /** * Terminates a listmap. @@ -225,7 +209,7 @@ static void listmap_init(listmap_t *map) static void listmap_term(listmap_t *map) { del_set(map->map); -} /* listmap_term */ +} /** * Return the associated listmap entry for a given id. @@ -242,7 +226,7 @@ static listmap_entry_t *listmap_find(listmap_t *map, void *id) key.id = id; key.list = NULL; key.next = NULL; - entry = (listmap_entry_t*)set_insert(map->map, &key, sizeof(key), HASH_PTR(id)); + entry = set_insert(listmap_entry_t, map->map, &key, sizeof(key), hash_ptr(id)); if (entry->list == NULL) { /* a new entry, put into the list */ @@ -250,7 +234,7 @@ static listmap_entry_t *listmap_find(listmap_t *map, void *id) map->values = entry; } return entry; -} /* listmap_find */ +} /** * Calculate the hash value for an opcode map entry. @@ -262,8 +246,8 @@ static listmap_entry_t *listmap_find(listmap_t *map, void *id) static unsigned opcode_hash(const opcode_key_t *entry) { /* assume long >= int */ - return (unsigned)(PTR_TO_INT(entry->mode) * 9 + entry->code + entry->u.proj * 3 + HASH_PTR(entry->u.addr) + entry->arity); -} /* opcode_hash */ + return (unsigned)(PTR_TO_INT(entry->mode) * 9 + entry->code + entry->u.proj * 3 + hash_ptr(entry->u.addr) + entry->arity); +} /** * Compare two entries in the opcode map. @@ -277,7 +261,7 @@ static int cmp_opcode(const void *elt, const void *key, size_t size) return o1->code != o2->code || o1->mode != o2->mode || o1->arity != o2->arity || o1->u.proj != o2->u.proj || o1->u.addr != o2->u.addr; -} /* cmp_opcode */ +} /** * Creates a new empty partition and put in on the @@ -296,7 +280,7 @@ static partition_t *create_partition(ir_node *meet_block, environment_t *env) DEBUG_ONLY(part->nr = part_nr++;) list_add_tail(&part->part_list, &env->partitions); return part; -} /* create_partition */ +} /** * Allocate a new block in the given partition. @@ -330,7 +314,7 @@ static block_t *create_block(ir_node *block, int meet_input, partition_t *partit env->all_blocks = bl; return bl; -} /* create_block */ +} /** * Allocate a new node and add it to a blocks wait queue. @@ -349,7 +333,7 @@ static node_t *create_node(ir_node *irn, block_t *block, environment_t *env) list_add_tail(&node->node_list, &block->nodes); return node; -} /* create_node */ +} /** * Add an input pair to a block. @@ -369,7 +353,7 @@ static void add_pair(block_t *block, ir_node *irn, int idx, environment_t *env) pair->ins = NULL; block->input_pairs = pair; -} /* add_pair */ +} /** * Add a Phi to a block. @@ -387,7 +371,7 @@ static void add_phi(block_t *block, ir_node *phi, environment_t *env) node->ins = NULL; block->phis = node; -} /** add_phi */ +} /** * Creates an opcode from a node. @@ -423,9 +407,6 @@ static opcode_key_t *opcode(const node_t *node, environment_t *env) case iro_Const: key.u.tv = get_Const_tarval(irn); break; - case iro_Conv: - key.u.intVal = get_Conv_strict(irn); - break; case iro_Load: key.mode = get_Load_mode(irn); break; @@ -439,9 +420,9 @@ static opcode_key_t *opcode(const node_t *node, environment_t *env) break; } - entry = (opcode_key_t*)set_insert(env->opcode2id_map, &key, sizeof(key), opcode_hash(&key)); + entry = set_insert(opcode_key_t, env->opcode2id_map, &key, sizeof(key), opcode_hash(&key)); return entry; -} /* opcode */ +} /** * Split a partition by a local list. @@ -481,7 +462,7 @@ static partition_t *split(partition_t *Z, block_t *g, environment_t *env) dump_partition("Now ", Z); dump_partition("Created new ", Z_prime); return Z_prime; -} /* split */ +} /** * Return non-zero if pred should be tread as a input node. @@ -496,7 +477,7 @@ static int is_input_node(ir_node *pred, ir_node *irn, int index) if (! is_Call(irn)) return 1; return 0; -} /* is_input_node */ +} /** * Propagate nodes on all wait queues of the given partition. @@ -508,7 +489,6 @@ static void propagate_blocks(partition_t *part, environment_t *env) { block_t *ready_blocks = NULL; unsigned n_ready = 0; - block_t *bl, *next; listmap_t map; listmap_entry_t *iter; @@ -543,10 +523,9 @@ static void propagate_blocks(partition_t *part, environment_t *env) for (i = get_irn_arity(irn) - 1; i >= 0; --i) { ir_node *pred = get_irn_n(irn, i); ir_node *block = get_nodes_block(skip_Proj(pred)); - node_t *p_node; if (block != bl->block) { - p_node = create_node(pred, bl, env); + node_t *p_node = create_node(pred, bl, env); if (is_input_node(pred, irn, i)) { /* is a block live input */ p_node->is_input = 1; @@ -558,7 +537,7 @@ static void propagate_blocks(partition_t *part, environment_t *env) } } else if (! irn_visited_else_mark(pred)) { /* not yet visited, ok */ - p_node = create_node(pred, bl, env); + create_node(pred, bl, env); if (is_Phi(pred)) { /* update the Phi list */ @@ -609,7 +588,7 @@ static void propagate_blocks(partition_t *part, environment_t *env) split(part, S, env); } listmap_term(&map); -} /* propagate_blocks */ +} /** * Propagate nodes on all wait queues. @@ -618,8 +597,6 @@ static void propagate_blocks(partition_t *part, environment_t *env) */ static void propagate(environment_t *env) { - partition_t *part, *next; - list_for_each_entry_safe(partition_t, part, next, &env->partitions, part_list) { if (part->n_blocks < 2) { /* zero or one block left, kill this partition */ @@ -628,7 +605,7 @@ static void propagate(environment_t *env) } else propagate_blocks(part, env); } -} /* propagate */ +} /** * Map a block to the phi[block->input] live-trough. @@ -644,7 +621,7 @@ static void *live_throughs(const block_t *bl, const ir_node *phi) if (get_nodes_block(input) == bl->block) return NULL; return input; -} /* live_throughs */ +} /** * Split partition by live-outs and live-troughs. @@ -655,7 +632,6 @@ static void *live_throughs(const block_t *bl, const ir_node *phi) static void propagate_blocks_live_troughs(partition_t *part, environment_t *env) { const ir_node *meet_block = part->meet_block; - block_t *bl, *next; listmap_t map; listmap_entry_t *iter; const ir_node *phi; @@ -700,7 +676,7 @@ static void propagate_blocks_live_troughs(partition_t *part, environment_t *env) } listmap_term(&map); } -} /* propagate_blocks_live_troughs */ +} /** * Propagate live-troughs on all partitions on the partition list. @@ -709,12 +685,10 @@ static void propagate_blocks_live_troughs(partition_t *part, environment_t *env) */ static void propagate_live_troughs(environment_t *env) { - partition_t *part, *next; - list_for_each_entry_safe(partition_t, part, next, &env->partitions, part_list) { propagate_blocks_live_troughs(part, env); } -} /* propagate_live_troughs */ +} /** * Apply analysis results by replacing all blocks of a partition @@ -730,7 +704,6 @@ static void propagate_live_troughs(environment_t *env) static void apply(ir_graph *irg, partition_t *part) { block_t *repr = list_entry(part->blocks.next, block_t, block_list); - block_t *bl; ir_node *block, *end, *meet_block, *p, *next; ir_node **ins, **phi_ins; phi_t *repr_phi, *phi; @@ -930,7 +903,7 @@ continue_outer: /* fix inputs of the meet block */ set_irn_in(meet_block, j, ins); DEL_ARR_F(ins); -} /* apply */ +} /** * Create a partition for a the end block. @@ -981,7 +954,7 @@ static void partition_for_end_block(ir_node *end_block, environment_t *env) } dump_partition("Created", part); -} /* partition_for_end_block */ +} #ifdef GENERAL_SHAPE /** @@ -1013,7 +986,7 @@ static void partition_for_block(ir_node *block, pred_t preds[], int n_preds, env } dump_partition("Created", part); -} /* partition_for_block */ +} /** * Walker: clear the links of all block phi lists and normal @@ -1026,7 +999,7 @@ static void clear_phi_links(ir_node *irn, void *env) set_Block_phis(irn, NULL); set_irn_link(irn, NULL); } -} /* clear_phi_links */ +} /** * Walker, detect live-out nodes. @@ -1069,7 +1042,7 @@ static void find_liveouts(ir_node *irn, void *ctx) live_outs[idx] = pred_block; } } -} /* find_liveouts */ +} /** * Check if the current block is the meet block of its predecessors. @@ -1108,7 +1081,7 @@ static void check_for_cf_meet(ir_node *block, void *ctx) if (k > 1) partition_for_block(block, preds, k, env); -} /* check_for_cf_meet */ +} /** * Compare two nodes for root ordering. @@ -1140,7 +1113,7 @@ static int cmp_nodes(const void *a, const void *b) idx_b = get_irn_idx(irn_b); return (idx_a > idx_b) - (idx_a < idx_b); -} /* cmp_nodes */ +} /** * Add the roots to all blocks. @@ -1173,11 +1146,9 @@ static void add_roots(ir_graph *irg, environment_t *env) for (bl = env->all_blocks; bl != NULL; bl = bl->all_next) { size_t i, n = ARR_LEN(bl->roots); -#if 1 /* TODO: is this really needed? The roots are already in idx-order by construction, which might be good enough. */ qsort(bl->roots, n, sizeof(bl->roots[0]), cmp_nodes); -#endif DB((dbg, LEVEL_2, " Adding Roots for block %+F\n ", bl->block)); /* ok, add them sorted */ @@ -1189,14 +1160,13 @@ static void add_roots(ir_graph *irg, environment_t *env) DEL_ARR_F(bl->roots); bl->roots = NULL; } -} /* add_roots */ +} #endif /* GENERAL_SHAPE */ /* Combines congruent end blocks into one. */ -int shape_blocks(ir_graph *irg) +void shape_blocks(ir_graph *irg) { environment_t env; - partition_t *part; block_t *bl; int res, n; @@ -1215,8 +1185,7 @@ int shape_blocks(ir_graph *irg) env.opcode2id_map = new_set(cmp_opcode, iro_Last * 4); n = get_irg_last_idx(irg); - env.live_outs = NEW_ARR_F(ir_node *, n); - memset(env.live_outs, 0, sizeof(*env.live_outs) * n); + env.live_outs = NEW_ARR_FZ(ir_node*, n); env.all_blocks = NULL; @@ -1261,11 +1230,7 @@ int shape_blocks(ir_graph *irg) if (res) { /* control flow changed */ - clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE - | IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS); - - /* Calls might be removed. */ - set_trouts_inconsistent(); + clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); } for (bl = env.all_blocks; bl != NULL; bl = bl->all_next) { @@ -1275,11 +1240,9 @@ int shape_blocks(ir_graph *irg) DEL_ARR_F(env.live_outs); del_set(env.opcode2id_map); obstack_free(&env.obst, NULL); - - return res; -} /* shape_blocks */ +} ir_graph_pass_t *shape_blocks_pass(const char *name) { - return def_graph_pass_ret(name ? name : "shape_blocks", shape_blocks); -} /* shape_blocks_pass */ + return def_graph_pass(name ? name : "shape_blocks", shape_blocks); +}