/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* Two block are congruent, if they contains only equal calculations.
*/
#include "config.h"
-#include "ircons.h"
+
#include "iroptimize.h"
+#include "ircons.h"
#include "irgmod.h"
#include "irgraph_t.h"
#include "irnode_t.h"
#include "set.h"
#include "irpass.h"
#include "debug.h"
+#include "irtools.h"
/* define this for general block shaping: congruent blocks
are found not only before the end block but anywhere in the graph */
/** An opcode map key. */
struct opcode_key_t {
- ir_opcode code; /**< The Firm opcode. */
+ unsigned code; /**< The Firm opcode. */
ir_mode *mode; /**< The mode of all nodes in the partition. */
int arity; /**< The arity of this opcode (needed for Phi etc. */
union {
long proj; /**< For Proj nodes, its proj number */
ir_entity *ent; /**< For Sel nodes, its entity */
- tarval *tv; /**< For Const nodes, its tarval */
+ ir_tarval *tv; /**< For Const nodes, its tarval */
symconst_symbol sym; /**< For SymConst nodes, its symbol .*/
void *addr; /**< Alias all addresses. */
int intVal; /**< For Conv/Div nodes: strict/remainderless. */
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
/** Next partition number. */
-DEBUG_ONLY(static unsigned part_nr = 0);
+DEBUG_ONLY(static unsigned part_nr = 0;)
#ifdef DEBUG_libfirm
/**
*/
static int listmap_cmp_ptr(const void *elt, const void *key, size_t size)
{
- const listmap_entry_t *e1 = elt;
- const listmap_entry_t *e2 = key;
+ const listmap_entry_t *e1 = (const listmap_entry_t*)elt;
+ const listmap_entry_t *e2 = (const listmap_entry_t*)key;
(void) size;
return e1->id != e2->id;
key.id = id;
key.list = NULL;
key.next = NULL;
- entry = set_insert(map->map, &key, sizeof(key), HASH_PTR(id));
+ entry = (listmap_entry_t*)set_insert(map->map, &key, sizeof(key), HASH_PTR(id));
if (entry->list == NULL) {
/* a new entry, put into the list */
static unsigned opcode_hash(const opcode_key_t *entry)
{
/* assume long >= int */
- return (entry->mode - (ir_mode *)0) * 9 + entry->code + entry->u.proj * 3 + HASH_PTR(entry->u.addr) + entry->arity;
+ return (unsigned)(PTR_TO_INT(entry->mode) * 9 + entry->code + entry->u.proj * 3 + HASH_PTR(entry->u.addr) + entry->arity);
} /* opcode_hash */
/**
*/
static int cmp_opcode(const void *elt, const void *key, size_t size)
{
- const opcode_key_t *o1 = elt;
- const opcode_key_t *o2 = key;
+ const opcode_key_t *o1 = (opcode_key_t*)elt;
+ const opcode_key_t *o2 = (opcode_key_t*)key;
(void) size;
return o1->code != o2->code || o1->mode != o2->mode ||
INIT_LIST_HEAD(&part->blocks);
part->meet_block = meet_block;
part->n_blocks = 0;
- DEBUG_ONLY(part->nr = part_nr++);
+ DEBUG_ONLY(part->nr = part_nr++;)
list_add_tail(&part->part_list, &env->partitions);
return part;
} /* create_partition */
break;
}
- entry = set_insert(env->opcode2id_map, &key, sizeof(key), opcode_hash(&key));
+ entry = (opcode_key_t*)set_insert(env->opcode2id_map, &key, sizeof(key), opcode_hash(&key));
return entry;
} /* opcode */
* @param part the partition
* @param env the environment
*/
-void propagate_blocks_live_troughs(partition_t *part, environment_t *env)
+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_entry_t *entry;
/* Add bl to map[live_trough(bl)]. */
- id = live_throughs(bl, phi);
+ id = (opcode_key_t*)live_throughs(bl, phi);
entry = listmap_find(&map, id);
bl->next = entry->list;
entry->list = bl;
*
* @param env the environment
*/
-void propagate_live_troughs(environment_t *env)
+static void propagate_live_troughs(environment_t *env)
{
partition_t *part, *next;
ir_node **ins, **phi_ins;
phi_t *repr_phi, *phi;
pair_t *repr_pair, *pair;
- int i, j, k, n, block_nr, n_phis;
+ int i, j, k, n, n_phis;
list_del(&repr->block_list);
/* collect new in arrays */
end = get_irg_end(irg);
- block_nr = 0;
list_for_each_entry(block_t, bl, &part->blocks, block_list) {
block = bl->block;
- ++block_nr;
DB((dbg, LEVEL_1, "%+F, ", block));
}
/* collect all no-return blocks */
- end = get_irg_end(current_ir_graph);
+ end = get_irg_end(get_irn_irg(end_block));
for (i = get_End_n_keepalives(end) - 1; i >= 0; --i) {
ir_node *ka = get_End_keepalive(end, i);
ir_node *block;
*/
static void find_liveouts(ir_node *irn, void *ctx)
{
- environment_t *env = ctx;
+ environment_t *env = (environment_t*)ctx;
ir_node **live_outs = env->live_outs;
ir_node *this_block;
int i;
} /* find_liveouts */
/**
- * Check if the current block is the meet block of a its predecessors.
+ * Check if the current block is the meet block of its predecessors.
*/
static void check_for_cf_meet(ir_node *block, void *ctx)
{
- environment_t *env = ctx;
+ environment_t *env = (environment_t*)ctx;
int i, k, n;
pred_t *preds;
- if (block == get_irg_end_block(current_ir_graph)) {
+ if (block == get_irg_end_block(get_irn_irg(block))) {
/* always create a partition for the end block */
partition_for_end_block(block, env);
return;
k = 0;
for (i = n - 1; i >= 0; --i) {
ir_node *pred = get_Block_cfgpred(block, i);
- ir_node *pred_block;
/* pred must be a direct jump to us */
if (! is_Jmp(pred) && ! is_Raise(pred) && !is_Bad(pred))
continue;
- pred_block = get_nodes_block(skip_Proj(pred));
-
preds[k].pred = pred;
preds[k].index = i;
+ ++k;
}
if (k > 1)
*/
static int cmp_nodes(const void *a, const void *b)
{
- const ir_node *const *pa = a;
- const ir_node *const *pb = b;
+ const ir_node *const *pa = (const ir_node*const*)a;
+ const ir_node *const *pb = (const ir_node*const*)b;
const ir_node *irn_a = *pa;
const ir_node *irn_b = *pb;
- ir_opcode code_a = get_irn_opcode(irn_a);
- ir_opcode code_b = get_irn_opcode(irn_b);
+ unsigned code_a = get_irn_opcode(irn_a);
+ unsigned code_b = get_irn_opcode(irn_b);
ir_mode *mode_a, *mode_b;
unsigned idx_a, idx_b;
* Else, we will split identical blocks if we start which different roots.
*/
for (bl = env->all_blocks; bl != NULL; bl = bl->all_next) {
- int i, n = ARR_LEN(bl->roots);
+ size_t i, n = ARR_LEN(bl->roots);
#if 1
/* TODO: is this really needed? The roots are already in
/* Combines congruent end blocks into one. */
int shape_blocks(ir_graph *irg)
{
- ir_graph *rem;
environment_t env;
partition_t *part;
block_t *bl;
int res, n;
- rem = current_ir_graph;
- current_ir_graph = irg;
-
/* register a debug mask */
FIRM_DBG_REGISTER(dbg, "firm.opt.blocks");
- DEBUG_ONLY(part_nr = 0);
+ DEBUG_ONLY(part_nr = 0;)
DB((dbg, LEVEL_1, "Shaping blocks for %+F\n", irg));
/* works better, when returns are placed at the end of the blocks */
if (res) {
/* control flow changed */
- set_irg_outs_inconsistent(irg);
- set_irg_extblk_inconsistent(irg);
- set_irg_doms_inconsistent(irg);
- set_irg_loopinfo_inconsistent(irg);
-
- /* Calls might be removed. */
- set_trouts_inconsistent();
-
- // dump_ir_block_graph(irg, "-after");
+ clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE
+ | IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS);
}
for (bl = env.all_blocks; bl != NULL; bl = bl->all_next) {
DEL_ARR_F(env.live_outs);
del_set(env.opcode2id_map);
obstack_free(&env.obst, NULL);
- current_ir_graph = rem;
return res;
} /* shape_blocks */