return a->op->ops.node_cmp_attr(a, b);
return 0;
-} /* cmp_irn_opcode */
+}
#ifdef CHECK_PARTITIONS
/**
assert(node->flagged == 0);
assert(node->part == T);
}
-} /* check_partition */
+}
/**
* check that all leader nodes in the partition have the same opcode.
assert(cmp_irn_opcode(repr, irn) == 0);
}
}
-} /* check_opcode */
+}
static void check_all_partitions(environment_t *env)
{
(void) ofs;
(void) Z;
#endif
-} /* ido_check_list */
+}
/**
* Check a local list.
static void check_list(const node_t *list, const partition_t *Z)
{
do_check_list(list, offsetof(node_t, next), Z);
-} /* check_list */
+}
#else
#define check_partition(T)
}
}
DB((dbg, LEVEL_2, "\n}\n"));
-} /* dump_partition */
+}
/**
* Dumps a list.
DB((dbg, LEVEL_3, "\n}\n"));
#undef GET_LINK
-} /* do_dump_list */
+}
/**
* Dumps a race list.
static void dump_race_list(const char *msg, const node_t *list)
{
do_dump_list(msg, list, offsetof(node_t, race_next));
-} /* dump_race_list */
+}
/**
* Dumps a local list.
static void dump_list(const char *msg, const node_t *list)
{
do_dump_list(msg, list, offsetof(node_t, next));
-} /* dump_list */
+}
/**
* Dump all partitions.
DB((dbg, LEVEL_2, "All partitions\n===============\n"));
for (P = env->dbg_list; P != NULL; P = P->dbg_next)
dump_partition("", P);
-} /* dump_all_partitions */
+}
/**
* Sump a split list.
split = ',';
}
DB((dbg, LEVEL_2, "\n}\n"));
-} /* dump_split_list */
+}
/**
* Dump partition and type for a node.
ir_fprintf(F, "info2 : \"partition %u type %+F\"\n", node->part->nr, node->type);
return 1;
-} /* dump_partition_hook */
+}
#else
#define dump_partition(msg, part)
return;
}
panic("wrong translation from %+F to %+F on node %+F", old_type, node->type, node->node);
-} /* verify_type */
+}
#else
#define verify_type(old_type, node)
(void) size;
return e1->id != e2->id;
-} /* listmap_cmp_ptr */
+}
/**
* Initializes a listmap.
{
map->map = new_set(listmap_cmp_ptr, 16);
map->values = NULL;
-} /* listmap_init */
+}
/**
* Terminates a listmap.
static void listmap_term(listmap_t *map)
{
del_set(map->map);
-} /* listmap_term */
+}
/**
* Return the associated listmap entry for a given id.
map->values = entry;
}
return entry;
-} /* listmap_find */
+}
/**
* Calculate the hash value for an opcode map entry.
else if (code == iro_Proj)
hash += (unsigned)get_Proj_proj(n);
return hash;
-} /* opcode_hash */
+}
/**
* Compare two entries in the opcode map.
(void) size;
return cmp_irn_opcode(o1->irn, o2->irn);
-} /* cmp_opcode */
+}
/**
* Compare two Def-Use edges for input position.
/* no overrun, because range is [-1, MAXINT] */
return ea->pos - eb->pos;
-} /* cmp_def_use_edge */
+}
/**
* We need the Def-Use edges sorted.
qsort(irn->o.out->edges, n_outs, sizeof(irn->o.out->edges[0]),
cmp_def_use_edge);
node->max_user_input = n_outs > 0 ? irn->o.out->edges[n_outs-1].pos : -1;
-} /* sort_irn_outs */
+}
/**
* Return the type of a node.
static inline lattice_elem_t get_node_type(const ir_node *irn)
{
return get_irn_node(irn)->type;
-} /* get_node_type */
+}
/**
* Return the tarval of a node.
if (is_tarval(type.tv))
return type.tv;
return tarval_bottom;
-} /* get_node_type */
+}
/**
* Add a partition to the worklist.
X->wl_next = env->worklist;
X->on_worklist = 1;
env->worklist = X;
-} /* add_to_worklist */
+}
/**
* Create a new empty partition.
#endif
return part;
-} /* new_partition */
+}
/**
* Get the first node from a partition.
static inline node_t *get_first_node(const partition_t *X)
{
return list_entry(X->Leader.next, node_t, node_list);
-} /* get_first_node */
+}
/**
* Return the type of a partition (assuming partition is non-empty and
{
const node_t *first = get_first_node(X);
return first->type;
-} /* get_partition_type */
+}
/**
* Creates a partition node for the given IR-node and place it
++part->n_leader;
return node;
-} /* create_partition_node */
+}
/**
* Pre-Walker, initialize all Nodes' type to U or top and place
if (is_Block(irn)) {
set_Block_phis(irn, NULL);
}
-} /* create_initial_partitions */
+}
/**
* Post-Walker, collect all Block-Phi lists, set Cond.
ir_node *block = get_nodes_block(irn);
add_Block_phi(block, irn);
}
-} /* init_block_phis */
+}
/**
* Add a node to the entry.partition.touched set and
check_list(part->touched, part);
}
-} /* add_to_touched */
+}
/**
* Place a node on the cprop list.
add_to_cprop(p, env);
}
}
-} /* add_to_cprop */
+}
/**
* Update the worklist: If Z is on worklist then add Z' to worklist.
} else {
add_to_worklist(Z, env);
}
-} /* update_worklist */
+}
/**
* Make all inputs to x no longer be F.def_use edges.
}
}
}
-} /* move_edges_to_leader */
+}
/**
* Split a partition that has NO followers by a local list.
update_worklist(Z, Z_prime, env);
return Z_prime;
-} /* split_no_followers */
+}
/**
* Make the Follower -> Leader transition for a node.
list_del(&n->node_list);
list_add_tail(&n->node_list, &n->part->Leader);
++n->part->n_leader;
-} /* follower_to_leader */
+}
/**
* The environment for one race step.
break;
}
return 1;
-} /* is_real_follower */
+}
/**
* Do one step in the race.
env->index = 0;
}
return 1;
-} /* step */
+}
/**
* Clear the flags from a list and check for
n->flagged = 0;
}
return res;
-} /* clear_flags */
+}
/**
* Split a partition by a local list using the race.
}
return X_prime;
-} /* split */
+}
/**
* Returns non-zero if the i'th input of a Phi node is live.
}
/* else it's the control input, always live */
return 1;
-} /* is_live_input */
+}
/**
* Return non-zero if a type is a constant.
if (type.tv != tarval_bottom && type.tv != tarval_top)
return 1;
return 0;
-} /* is_constant_type */
+}
/**
* Check whether a type is neither Top or a constant.
return 0;
}
return 1;
-} /* type_is_neither_top_nor_const */
+}
/**
* Collect nodes to the touched list.
}
}
}
-} /* collect_touched */
+}
/**
* Collect commutative nodes to the touched list.
}
}
}
-} /* collect_commutative_touched */
+}
/**
* Split the partitions if caused by the first entry on the worklist.
assert(n_touched <= Z->n_leader);
}
}
-} /* cause_splits */
+}
/**
* Implements split_by_what(): Split a partition by characteristics given
listmap_term(&map);
return *P;
-} /* split_by_what */
+}
/** lambda n.(n.type) */
static void *lambda_type(const node_t *node, environment_t *env)
{
(void)env;
return node->type.tv;
-} /* lambda_type */
+}
/** lambda n.(n.opcode) */
static void *lambda_opcode(const node_t *node, environment_t *env)
entry = set_insert(opcode_key_t, env->opcode2id_map, &key, sizeof(key), opcode_hash(&key));
return entry;
-} /* lambda_opcode */
+}
/** lambda n.(n[i].partition) */
static void *lambda_partition(const node_t *node, environment_t *env)
pred = i == -1 ? get_irn_n(skipped, i) : get_irn_n(node->node, i);
p = get_irn_node(pred);
return p->part;
-} /* lambda_partition */
+}
/** lambda n.(n[i].partition) for commutative nodes */
static void *lambda_commutative_partition(const node_t *node, environment_t *env)
return p->part;
}
-} /* lambda_commutative_partition */
+}
/**
* Returns true if a type is a constant (and NOT Top
if (is_tarval(type.tv))
return tarval_is_constant(type.tv);
return is_entity(type.sym.entity_p);
-} /* is_con */
+}
/**
* Implements split_by().
}
}
} while (P != NULL);
-} /* split_by */
+}
/**
* (Re-)compute the type for a given node.
node->type.tv = tarval_reachable;
else
node->type.tv = computed_value(irn);
-} /* default_compute */
+}
/**
* (Re-)compute the type for a Block node.
}
}
node->type.tv = tarval_top;
-} /* compute_Block */
+}
/**
* (Re-)compute the type for a Bad node.
{
/* Bad nodes ALWAYS compute Top */
node->type.tv = tarval_top;
-} /* compute_Bad */
+}
/**
* (Re-)compute the type for an Unknown node.
* (jump threading for instance) might replace them by Phib's...
*/
node->type.tv = tarval_UNKNOWN;
-} /* compute_Unknown */
+}
/**
* (Re-)compute the type for a Jmp node.
node_t *block = get_irn_node(get_nodes_block(node->node));
node->type = block->type;
-} /* compute_Jmp */
+}
/**
* (Re-)compute the type for the Return node.
* This is already checked in compute(). so we can return
* Reachable here. */
node->type.tv = tarval_reachable;
-} /* compute_Return */
+}
/**
* (Re-)compute the type for the End node.
{
/* the End node is NOT dead of course */
node->type.tv = tarval_reachable;
-} /* compute_End */
+}
/**
* (Re-)compute the type for a Call.
* predecessors.
*/
node->type.tv = tarval_bottom;
-} /* compute_Call */
+}
/**
* (Re-)compute the type for a SymConst node.
default:
node->type.tv = computed_value(irn);
}
-} /* compute_SymConst */
+}
/**
* (Re-)compute the type for a Phi node.
/* else nothing, constants are the same */
}
node->type = type;
-} /* compute_Phi */
+}
/**
* (Re-)compute the type for an Add. Special case: one nodes is a Zero Const.
}
node->type.tv = tarval_bottom;
}
-} /* compute_Add */
+}
/**
* (Re-)compute the type for a Sub. Special case: both nodes are congruent.
} else {
node->type.tv = tarval_bottom;
}
-} /* compute_Sub */
+}
/**
* (Re-)compute the type for an Eor. Special case: both nodes are congruent.
} else {
node->type.tv = tarval_bottom;
}
-} /* compute_Eor */
+}
/**
* (Re-)compute the type for Cmp.
}
}
}
-} /* compute_Proj_Cond */
+}
static void compute_Proj_Switch(node_t *node, ir_node *switchn)
{
}
default_compute(node);
-} /* compute_Proj */
+}
/**
* (Re-)compute the type for a Confirm.
}
/* a Confirm is a copy OR a Const */
node->type = pred->type;
-} /* compute_Confirm */
+}
/**
* (Re-)compute the type for a given node.
func = (compute_func)node->node->op->ops.generic;
if (func != NULL)
func(node);
-} /* compute */
+}
/*
* Identity functions: Note that one might think that identity() is just a
* tarval_top, is in the TOP partition and should NOT being split! */
assert(n_part != NULL);
return n_part;
-} /* identity_Phi */
+}
/**
* Calculates the Identity for commutative 0 neutral nodes.
if (b->type.tv == zero)
return a;
return node;
-} /* identity_comm_zero_binop */
+}
/**
* Calculates the Identity for Shift nodes.
if (b->type.tv == zero)
return get_irn_node(get_binop_left(op));
return node;
-} /* identity_shift */
+}
/**
* Calculates the Identity for Mul nodes.
if (b->type.tv == one)
return a;
return node;
-} /* identity_Mul */
+}
/**
* Calculates the Identity for Sub nodes.
if (b->type.tv == get_mode_null(mode))
return get_irn_node(get_Sub_left(sub));
return node;
-} /* identity_Sub */
+}
/**
* Calculates the Identity for And nodes.
if (b->type.tv == neutral)
return a;
return node;
-} /* identity_And */
+}
/**
* Calculates the Identity for Confirm nodes.
/* a Confirm is always a Copy */
return get_irn_node(get_Confirm_value(confirm));
-} /* identity_Confirm */
+}
/**
* Calculates the Identity for Mux nodes.
return f;
#endif
return node;
-} /* identity_Mux */
+}
/**
* Calculates the Identity for nodes.
default:
return node;
}
-} /* identity */
+}
/**
* Node follower is a (new) follower of leader, segregate Leader
break;
}
}
-} /* segregate_def_use_chain_1 */
+}
/**
* Node follower is a (new) follower segregate its Leader
segregate_def_use_chain_1(follower, pred);
}
-} /* segregate_def_use_chain */
+}
/**
* Propagate constant evaluation.
}
split_by(Y, env);
}
-} /* propagate */
+}
/**
* Get the leader for a given node from its congruence class.
return get_first_node(part)->node;
}
return node->node;
-} /* get_leader */
+}
/**
* Returns non-zero if a mode_T node has only one reachable output.
}
}
return 1;
-} /* only_one_reachable_proj */
+}
/**
* Return non-zero if the control flow predecessor node pred
return only_one_reachable_proj(pred);
}
return 0;
-} /* can_exchange */
+}
/**
* Block Post-Walker, apply the analysis results on control flow by
}
set_irn_in(block, k, in_X);
env->modified = 1;
-} /* apply_cf */
+}
/**
* Exchange a node by its leader.
}
}
exchange(irn, leader);
-} /* exchange_leader */
+}
/**
* Check, if all users of a mode_M node are dead. Use
}
/* all users are unreachable */
return 1;
-} /* all_user_are_dead */
+}
/**
* Walker: Find reachable mode_M nodes that have only
DB((dbg, LEVEL_1, "%+F must be kept\n", irn));
ARR_APP1(ir_node *, env->kept_memory, irn);
}
-} /* find_kept_memory */
+}
/**
* Post-Walker, apply the analysis results;
}
}
}
-} /* apply_result */
+}
/**
* Fix the keep-alives by deleting unreachable ones.
set_End_keepalives(end, j, in);
env->modified = 1;
}
-} /* apply_end */
+}
#define SET(code) op_##code->ops.generic = (op_func)compute_##code
SET(Return);
SET(End);
SET(Call);
-} /* set_compute_functions */
+}
/**
* Add memory keeps.
}
}
ir_nodeset_destroy(&set);
-} /* add_memory_keeps */
+}
void combo(ir_graph *irg)
{
current_ir_graph = rem;
confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE);
-} /* combo */
+}
/* Creates an ir_graph pass for combo. */
ir_graph_pass_t *combo_pass(const char *name)
{
return def_graph_pass(name ? name : "combo", combo);
-} /* combo_pass */
+}
++i;
}
DB((dbg, LEVEL_2, "\n}\n"));
-} /* dump_value_set */
+}
/**
* Dump all exp_gen value sets.
info->next = env->list;
env->list = info;
-} /* alloc_block_info */
+}
static void free_block_info(block_info *block_info)
{
if (updated)
dump_value_set(curr_info->avail_out, "Updated [Avail_out]", block);
#endif
-} /* update_new_set */
+}
/**
* Checks if hoisting irn is greedy.
}
}
}
-} /* eliminate */
+}
/**
* Do all the recorded changes and optimize
foreach_ir_nodeset(keeps, m_phi, iter) {
remove_End_keepalive(end, m_phi);
}
-} /* eliminate_nodes */
+}
/* --------------------------------------------------------
ir_graph_pass_t *opt_jumpthreading_pass(const char *name)
{
return def_graph_pass(name ? name : "jumpthreading", opt_jumpthreading);
-} /* opt_jumpthreading_pass */
+}
set_irn_link(node, info);
}
return info;
-} /* get_ldst_info */
+}
/**
* get the Block info of a node
set_irn_link(node, info);
}
return info;
-} /* get_block_info */
+}
/**
* update the projection info for a Load/Store
info->projs[nr] = proj;
return 0;
}
-} /* update_projs */
+}
/**
* update the exception block info for a Load/Store node.
info->exc_block = block;
info->exc_idx = pos;
return 0;
-} /* update_exc */
+}
/**
* walker, collects all Load/Store/Proj nodes
}
}
}
-} /* collect_nodes */
+}
/**
* Returns an entity if the address ptr points to a constant one.
} else
return NULL;
}
-} /* find_constant_entity */
+}
/**
* Return the Selection index of a Sel node from dimension n
ir_node *index = get_Sel_index(n, dim);
assert(is_Const(index));
return get_tarval_long(get_Const_tarval(index));
-} /* get_Sel_array_index_long */
+}
typedef struct path_entry {
ir_entity *ent;
kill_node(load);
reduce_adr_usage(ptr);
}
-} /* handle_load_update */
+}
/**
* A use of an address node has vanished. Check if this was a Proj
/* this node lost its result proj, handle that */
handle_load_update(pred);
}
-} /* reduce_adr_usage */
+}
/**
* Check, if an already existing value of mode old_mode can be converted
}
}
return (prop & (mtp_property_const|mtp_property_pure)) != 0;
-} /* is_Call_pure */
+}
static ir_node *get_base_and_offset(ir_node *ptr, long *pOffset)
{
}
return res;
-} /* follow_Mem_chain */
+}
ir_node *can_replace_load_by_const(const ir_node *load, ir_node *c)
{
INC_MASTER();
res = follow_Mem_chain(load, skip_Proj(mem));
return res;
-} /* optimize_load */
+}
/**
* Check whether a value of mode new_mode would completely overwrite a value
static int is_completely_overwritten(ir_mode *old_mode, ir_mode *new_mode)
{
return get_mode_size_bits(new_mode) >= get_mode_size_bits(old_mode);
-} /* is_completely_overwritten */
+}
/**
* Check whether small is a part of large (starting at same address).
&& get_mode_size_bytes(sm) < get_mode_size_bytes(lm)
&& get_mode_arithmetic(sm) == irma_twos_complement
&& get_mode_arithmetic(lm) == irma_twos_complement;
-} /* is_partially_same */
+}
/**
* follow the memory chain as long as there are only Loads and alias free Stores.
}
}
return res;
-} /* follow_Mem_chain_for_Store */
+}
/** find entity used as base for an address calculation */
static ir_entity *find_entity(ir_node *ptr)
INC_MASTER();
return follow_Mem_chain_for_Store(store, skip_Proj(mem));
-} /* optimize_store */
+}
/* check if a node has more than one real user. Keepalive edges do not count as
* real users */
exchange(phi, projM);
return res | DF_CHANGED;
-} /* optimize_phi */
+}
static int optimize_conv_load(ir_node *conv)
{
default:
break;
}
-} /* do_load_store_optimize */
+}
/** A scc. */
typedef struct scc {
ir_nodehashmap_insert(&env->map, irn, e);
}
return e;
-} /* get_irn_ne */
+}
/**
* Push a node onto the stack.
env->stack[env->tos++] = n;
e = get_irn_ne(n, env);
e->in_stack = 1;
-} /* push */
+}
/**
* pop a node from the stack
e->in_stack = 0;
return n;
-} /* pop */
+}
/**
* Check if irn is a region constant.
ir_node *block = get_nodes_block(irn);
return (block != header_block) && block_dominates(block, header_block);
-} /* is_rc */
+}
typedef struct phi_entry phi_entry;
struct phi_entry {
(void) size;
return a->ptr != b->ptr || a->mode != b->mode;
-} /* cmp_avail_entry */
+}
/**
* Calculate the hash value of an avail entry.
static unsigned hash_cache_entry(const avail_entry_t *entry)
{
return get_irn_idx(entry->ptr) * 9 + hash_ptr(entry->mode);
-} /* hash_cache_entry */
+}
/**
* Move loops out of loops if possible.
}
}
del_set(avail);
-} /* move_loads_out_of_loops */
+}
/**
* Process a loop SCC.
fail:
;
-} /* process_loop */
+}
/**
* Process a SCC.
/* this SCC has more than one member */
process_loop(pscc, env);
}
-} /* process_scc */
+}
/**
* Do Tarjan's SCC algorithm and drive load/store optimization.
process_scc(pscc, env);
}
-} /* dfs */
+}
/**
* Do the DFS on the memory edges a graph.
if (is_Phi(ka) && !irn_visited(ka))
dfs(ka, env);
}
-} /* do_dfs */
+}
/**
* Optimize Loads/Stores in loops.
ir_nodehashmap_destroy(&env.map);
return env.changes;
-} /* optimize_loops */
+}
void optimize_load_store(ir_graph *irg)
{
ir_graph_pass_t *optimize_load_store_pass(const char *name)
{
return def_graph_pass(name ? name : "ldst", optimize_load_store);
-} /* optimize_load_store_pass */
+}
first = 0;
}
DB((dbg, LEVEL_2, "\n }\n"));
-} /* dump_partition */
+}
/**
* Dumps a list.
first = 0;
}
DB((dbg, LEVEL_3, "\n }\n"));
-} /* do_dump_list */
+}
#else
#define dump_partition(msg, part)
#define dump_list(msg, block)
(void) size;
return e1->id != e2->id;
-} /* listmap_cmp_ptr */
+}
/**
* Initializes a listmap.
{
map->map = new_set(listmap_cmp_ptr, 16);
map->values = NULL;
-} /* listmap_init */
+}
/**
* Terminates a listmap.
static void listmap_term(listmap_t *map)
{
del_set(map->map);
-} /* listmap_term */
+}
/**
* Return the associated listmap entry for a given id.
map->values = entry;
}
return entry;
-} /* listmap_find */
+}
/**
* Calculate the hash value for an opcode map 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 */
+}
/**
* Compare two entries in the opcode map.
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
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.
env->all_blocks = bl;
return bl;
-} /* create_block */
+}
/**
* Allocate a new node and add it to a blocks wait queue.
list_add_tail(&node->node_list, &block->nodes);
return node;
-} /* create_node */
+}
/**
* Add an input pair to a block.
pair->ins = NULL;
block->input_pairs = pair;
-} /* add_pair */
+}
/**
* Add a Phi to a block.
node->ins = NULL;
block->phis = node;
-} /** add_phi */
+}
/**
* Creates an opcode from a node.
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.
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.
if (! is_Call(irn))
return 1;
return 0;
-} /* is_input_node */
+}
/**
* Propagate nodes on all wait queues of the given partition.
split(part, S, env);
}
listmap_term(&map);
-} /* propagate_blocks */
+}
/**
* Propagate nodes on all wait queues.
} else
propagate_blocks(part, env);
}
-} /* propagate */
+}
/**
* Map a block to the phi[block->input] live-trough.
if (get_nodes_block(input) == bl->block)
return NULL;
return input;
-} /* live_throughs */
+}
/**
* Split partition by live-outs and live-troughs.
}
listmap_term(&map);
}
-} /* propagate_blocks_live_troughs */
+}
/**
* Propagate live-troughs on all partitions on the partition list.
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
/* 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.
}
dump_partition("Created", part);
-} /* partition_for_end_block */
+}
#ifdef GENERAL_SHAPE
/**
}
dump_partition("Created", part);
-} /* partition_for_block */
+}
/**
* Walker: clear the links of all block phi lists and normal
set_Block_phis(irn, NULL);
set_irn_link(irn, NULL);
}
-} /* clear_phi_links */
+}
/**
* Walker, detect live-out nodes.
live_outs[idx] = pred_block;
}
}
-} /* find_liveouts */
+}
/**
* Check if the current block is the meet block of its predecessors.
if (k > 1)
partition_for_block(block, preds, k, env);
-} /* check_for_cf_meet */
+}
/**
* Compare two nodes for root ordering.
idx_b = get_irn_idx(irn_b);
return (idx_a > idx_b) - (idx_a < idx_b);
-} /* cmp_nodes */
+}
/**
* Add the roots to all blocks.
DEL_ARR_F(bl->roots);
bl->roots = NULL;
}
-} /* add_roots */
+}
#endif /* GENERAL_SHAPE */
/* Combines congruent end blocks into one. */
DEL_ARR_F(env.live_outs);
del_set(env.opcode2id_map);
obstack_free(&env.obst, NULL);
-} /* shape_blocks */
+}
ir_graph_pass_t *shape_blocks_pass(const char *name)
{
return def_graph_pass(name ? name : "shape_blocks", shape_blocks);
-} /* shape_blocks_pass */
+}
return (relation != ir_relation_equal) && (relation != ir_relation_unordered);
#undef RET_ON
-} /* value_not_zero */
+}
/*
* Check, if the value of a node cannot represent a NULL pointer.
}
}
return 0;
-} /* value_not_null */
+}
#ifdef __cplusplus
extern "C++" {
default:
return value_classified_unknown;
}
-} /* classify_value_sign */
+}
/**
* construct an interval from a value
iv->flags = MIN_INCLUDED | MAX_INCLUDED;
return iv;
-} /* get_interval_from_tv */
+}
/**
* construct an interval from a Confirm
if (iv->min != tarval_bad && iv->max != tarval_bad)
return iv;
return NULL;
-} /* get_interval */
+}
/**
* Try to evaluate l_iv relation r_iv.
return tarval_bad;
}
return tarval_bad;
-} /* compare_iv */
+}
/**
* Returns non-zero, if a given relation is transitive.
static int is_transitive(ir_relation relation)
{
return (ir_relation_false < relation && relation < ir_relation_less_greater);
-} /* is_transitive */
+}
/**
* Return the value of a Cmp if one or both predecessors
DBG_EVAL_CONFIRM(cmp);
return tv;
-} /* computed_value_Cmp_Confirm */
+}
#ifdef DEBUG_CONFIRM
/**
return snprintf(buf, len, "%s", smin);
}
return snprintf(buf, len, "<UNKNOWN>");
-} /* iv_snprintf */
+}
/**
* For debugging. Prints an interval compare.
iv_snprintf(sr, sizeof(sr), r_iv);
ir_printf("%s %= %s", sl, relation, sr);
-} /* print_iv_cmp */
+}
/**
* For debugging. call *compare_iv() and prints inputs and result.
print_iv_cmp(l_iv, r_iv, relation);
ir_printf(" = %T\n", tv);
return tv;
-} /* compare_iv_dbg */
+}
#endif /* DEBUG_CONFIRM */
}
DB((dbg, LEVEL_2, "\n}\n\n"));
}
-} /* dump_block_list */
+}
/**
* Dumps the current set.
i = (i + 1) & 3;
}
DB((dbg, LEVEL_2, "\n}\n"));
-} /* dump_curr */
+}
#else
static void dump_block_list(ldst_env *env)
assert(is_Block(block));
return (block_t*)get_irn_link(block);
-} /* get_block_entry */
+}
/** Get the memop entry for a memory operation node */
static memop_t *get_irn_memop(const ir_node *irn)
{
assert(! is_Block(irn));
return (memop_t*)get_irn_link(irn);
-} /* get_irn_memop */
+}
/**
* Walk over the memory edges from definition to users.
}
if (post)
post(irn, ctx);
-} /* walk_memory */
+}
/**
* Walks over all memory nodes of a graph.
walk_memory(get_irg_initial_mem(irg), pre, post, ctx);
ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
-} /* walk_memory_irg */
+}
/**
* Register an address and allocate a (sparse, 0..n) ID for it.
#endif
}
return entry->id;
-} /* register_address */
+}
/**
if (is_Phi(address) && get_nodes_block(address) == block)
address = get_Phi_pred(address, pos);
return address;
-} /* phi_translate */
+}
/**
* Walker: allocate an block entry for every block
(void)register_address(irn);
}
}
-} /* prepare_blocks */
+}
/**
* Post-Walker, link in all Phi's
ir_node *block = get_nodes_block(irn);
add_Block_phi(block, irn);
}
-} /* link_phis */
+}
/**
* Block walker: creates the inverse post-order list for the CFG.
/* remember the first visited (last in list) entry, needed for later */
if (env.backward == NULL)
env.backward = entry;
-} /* inverse_post_order */
+}
/**
* Block walker: create backward links for the memops of a block.
last = op;
}
entry->memop_backward = last;
-} /* collect_backward */
+}
/**
* Allocate a memop.
if (irn != NULL)
set_irn_link(irn, m);
return m;
-} /* alloc_memop */
+}
/**
* Create a memop for a Phi-replacement.
set_irn_link(phi, m);
return m;
-} /* clone_memop_phi */
+}
/**
* Return the memory properties of a call node.
}
}
return prop & (mtp_property_const|mtp_property_pure);
-} /* get_Call_memory_properties */
+}
/**
* Returns an entity if the address ptr points to a constant one.
} else
return NULL;
}
-} /* find_constant_entity */
+}
/**
* Return the Selection index of a Sel node from dimension n
ir_node *index = get_Sel_index(n, dim);
assert(is_Const(index));
return get_tarval_long(get_Const_tarval(index));
-} /* get_Sel_array_index_long */
+}
typedef struct path_entry {
ir_entity *ent;
goto ptr_arith;
}
return NULL;
-} /* rec_find_compound_ent_value */
+}
static ir_node *find_compound_ent_value(ir_node *ptr)
{
return rec_find_compound_ent_value(ptr, NULL);
-} /* find_compound_ent_value */
+}
/**
* Mark a Load memop to be replace by a definition
op->replace = def;
op->flags |= FLAG_KILLED_NODE;
env.changed = 1;
-} /* mark_replace_load */
+}
/**
* Mark a Store memop to be removed.
{
op->flags |= FLAG_KILLED_NODE;
env.changed = 1;
-} /* mark_remove_store */
+}
/**
* Update a memop for a Load.
/* no user, KILL it */
mark_replace_load(m, NULL);
}
-} /* update_Load_memop */
+}
/**
* Update a memop for a Store.
}
m->value.value = get_Store_value(store);
m->value.mode = get_irn_mode(m->value.value);
-} /* update_Store_memop */
+}
/**
* Update a memop for a Call.
break;
}
}
-} /* update_Call_memop */
+}
/**
* Update a memop for a Div/Mod.
{
/* the Phi is its own mem */
m->mem = m->node;
-} /* update_Phi_memop */
+}
/**
* Memory walker: collect all memory ops and build topological lists.
entry->memop_backward = op;
}
}
-} /* collect_memops */
+}
/**
* Find an address in the current set.
return res;
}
return NULL;
-} /* find_address */
+}
/**
* Find an address in the avail_out set.
return res;
}
return NULL;
-} /* find_address_avail */
+}
/**
* Kill all addresses from the current set.
/* set sentinel */
rbitset_set(env.curr_set, env.rbs_size - 1);
-} /* kill_all */
+}
/**
* Kill memops that are not alias free due to a Store value from the current set.
DB((dbg, LEVEL_2, "KILLING %+F because of possible alias address %+F\n", op->node, value->address));
}
}
-} /* kill_memops */
+}
/**
* Add the value of a memop to the current set.
{
rbitset_set(env.curr_set, op->value.id);
env.curr_id_2_memop[op->value.id] = op;
-} /* add_memop */
+}
/**
* Add the value of a memop to the avail_out set.
{
rbitset_set(bl->avail_out, op->value.id);
bl->id_2_memop_avail[op->value.id] = op;
-} /* add_memop_avail */
+}
/**
* Check, if we can convert a value of one mode to another mode
get_mode_size_bits(from) == get_mode_size_bits(to))
return 1;
return 0;
-} /* can_convert_to */
+}
/**
* Add a Conv to the requested mode if needed.
return NULL;
}
return irn;
-} /* conv_to */
+}
/**
* Update the address of an value if this address was a load result
value->address = op->replace;
}
}
-} /* update_address */
+}
/**
* Do forward dataflow analysis on the given block and calculate the
kill_all();
}
}
-} /* calc_gen_kill_avail */
+}
#define BYTE_SIZE(x) (((x) + 7) >> 3)
calc_gen_kill_avail(bl);
dump_curr(bl, "Avail_out");
-} /* forward_avail */
+}
/**
* Do backward dataflow analysis on a given block to calculate the antic set
}
dump_curr(bl, "AnticL_in");
return 0;
-} /* backward_antic */
+}
/**
* Replace a Load memop by a already known value.
if (proj != NULL) {
exchange(proj, new_r_Jmp(get_nodes_block(load)));
}
-} /* replace_load */
+}
/**
* Remove a Store memop.
if (proj != NULL) {
exchange(proj, new_r_Jmp(get_nodes_block(store)));
}
-} /* remove_store */
+}
/**
}
}
}
-} /* do_replacements */
+}
/**
* Calculate the Avail_out sets for all basic blocks.
/* restore the current sets */
env.curr_id_2_memop = tmp_memop;
env.curr_set = tmp_set;
-} /* calcAvail */
+}
/**
* Calculate the Antic_in sets for all basic blocks.
++i;
} while (need_iter);
DB((dbg, LEVEL_2, "Get anticipated Load set after %d iterations\n", i));
-} /* calcAntic */
+}
/**
* Return the node representing the last memory in a block.
/* if there is NO memory in this block, go to the dominator */
bl = get_block_entry(get_Block_idom(bl->block));
}
-} /* find_last_memory */
+}
/**
* Reroute all memory users of old memory
/* all edges previously point to omem now point to nmem */
nmem->o.out = omem->o.out;
-} /* reroute_all_mem_users */
+}
/**
* Reroute memory users of old memory that are dominated by a given block
edges at the end either. */
/* first entry is used for the length */
nmem->o.out = new_out;
-} /* reroute_mem_through */
+}
/**
* insert Loads, making partly redundant Loads fully redundant
}
dump_curr(bl, "Avail_out");
return 0;
-} /* insert_Load */
+}
/**
* Insert Loads upwards.
} while (need_iter);
DB((dbg, LEVEL_2, "Finished Load inserting after %d iterations\n", i));
-} /* insert_Loads_upwards */
+}
void opt_ldst(ir_graph *irg)
{
#ifdef DEBUG_libfirm
DEL_ARR_F(env.id_2_address);
#endif
-} /* opt_ldst */
+}
ir_graph_pass_t *opt_ldst_pass(const char *name)
{
return def_graph_pass(name ? name : "ldst_df", opt_ldst);
-} /* opt_ldst_pass */
+}
(void) size;
return l1->src != l2->src;
-} /* LFTR_cmp */
+}
/**
* Find a LFTR edge.
key.src = src;
return set_find(LFTR_edge, env->lftr_edges, &key, sizeof(key), hash_ptr(src));
-} /* LFTR_find */
+}
/**
* Add a LFTR edge.
* because we currently store only one.
*/
(void)set_insert(LFTR_edge, env->lftr_edges, &key, sizeof(key), hash_ptr(src));
-} /* LFTR_add */
+}
/**
* Gets the node_entry of a node.
set_irn_link(irn, e);
}
return e;
-} /* get_irn_ne */
+}
/**
* Gets the scc from an induction variable.
{
node_entry *e = get_irn_ne(iv, env);
return e->pscc;
-} /* get_iv_scc */
+}
/**
* Check if irn is an IV.
static ir_node *is_iv(ir_node *irn, iv_env *env)
{
return get_irn_ne(irn, env)->header;
-} /* is_iv */
+}
/**
* Check if irn is a region constant.
ir_node *block = get_nodes_block(irn);
return (block != header_block) && block_dominates(block, header_block);
-} /* is_rc */
+}
/**
* Set compare function for the quad set.
(void) size;
return c1->code != c2->code || c1->op1 != c2->op1 || c1->op2 != c2->op2;
-} /* quad_cmp */
+}
/**
* Check if an reduced operation was already calculated.
if (entry)
return entry->res;
return NULL;
-} /* search */
+}
/**
* Add an reduced operation.
key.res = result;
(void)set_insert(quadruple_t, env->quad_map, &key, sizeof(key), (code * 9) ^ hash_ptr(op1) ^ hash_ptr(op2));
-} /* add */
+}
/**
* Find a location where to place a bin-op whose operands are in
return block2;
assert(block_dominates(block2, block1));
return block1;
-} /* find_location */
+}
/**
* Create a node that executes an op1 code op1 operation.
panic("Unsupported opcode");
}
return result;
-} /* do_apply */
+}
/**
* The Apply operation.
}
}
return result;
-} /* apply */
+}
/**
* The Reduce operation.
get_irn_opname(orig), rc));
}
return result;
-} /* reduce */
+}
/**
* Update the scc for a newly created IV.
} while (! waitq_empty(wq));
del_waitq(wq);
DB((dbg, LEVEL_2, "\n"));
-} /* update_scc */
+}
/**
* The Replace operation. We found a node representing iv (+,-,*) rc
return 1;
}
return 0;
-} /* replace */
+}
#if 0
/**
}
}
return 0;
-} /* is_x86_shift_const */
+}
#endif
/**
pscc->incr = get_Const_tarval(have_incr);
pscc->code = code;
return code != iro_Bad;
-} /* is_counter_iv */
+}
/**
* Check the users of an induction variable for register pressure.
* to do a linear function test replacement, so go on.
*/
return 1;
-} /* check_users_for_reg_pressure */
+}
/**
* Check if a node can be replaced (+, -, *).
break;
}
return 0;
-} /* check_replace */
+}
/**
* Check which SCC's are induction variables.
next = e->next;
e->header = NULL;
}
-} /* classify_iv */
+}
/**
* Process an SCC for the operator strength reduction.
} else {
classify_iv(pscc, env);
}
-} /* process_scc */
+}
/**
* If an SCC is a Phi only cycle, remove it.
exchange(irn, out_rc);
}
++env->replaced;
-} /* remove_phi_cycle */
+}
/**
* Process a SCC for the Phi cycle remove.
if (e->next != NULL)
remove_phi_cycle(pscc, env);
-} /* process_phi_only_scc */
+}
/**
env->stack[env->tos++] = n;
e = get_irn_ne(n, env);
e->in_stack = 1;
-} /* push */
+}
/**
* Pop a node from the stack.
e->in_stack = 0;
return n;
-} /* pop */
+}
/**
* Do Tarjan's SCC algorithm and drive OSR.
env->process_scc(pscc, env);
}
}
-} /* dfs */
+}
/**
* Do the DFS by starting at the End node of a graph.
}
ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
-} /* do_dfs */
+}
/**
* Post-block-walker: assign the post-order number.
node_entry *e = get_irn_ne(block, env);
e->POnum = env->POnum++;
-} /* assign_po */
+}
/**
* Apply one LFTR edge operation.
return new_r_Const(irg, tv);
}
return do_apply(e->code, NULL, rc, e->rc, get_irn_mode(e->dst));
-} /* applyOneEdge */
+}
/**
* Applies the operations represented by the LFTR edges to a
DB((dbg, LEVEL_3, "\n"));
*pIV = iv;
return rc;
-} /* applyEdges */
+}
/**
* Walker, finds Cmp(iv, rc) or Cmp(rc, iv)
set_Cmp_right(cmp, nright);
++env->lftr_replaced;
}
-} /* do_lftr */
+}
/**
* do linear function test replacement.
static void lftr(ir_graph *irg, iv_env *env)
{
irg_walk_graph(irg, NULL, do_lftr, env);
-} /* lftr */
+}
/* Remove any Phi cycles with only one real input. */
void remove_phi_cycles(ir_graph *irg)
ir_graph_pass_t *remove_phi_cycles_pass(const char *name)
{
return def_graph_pass(name ? name : "remove_phi_cycles", remove_phi_cycles);
-} /* remove_phi_cycles_pass */
+}
/**
* Post-walker: fix Add and Sub nodes that where results of I<->P conversions.
}
}
}
-} /* fix_adds_and_subs */
+}
/* Performs Operator Strength Reduction for the passed graph. */
void opt_osr(ir_graph *irg, unsigned flags)
pass_t *pass = (pass_t*)context;
opt_osr(irg, pass->flags);
return 0;
-} /* pass_wrapper */
+}
ir_graph_pass_t *opt_osr_pass(const char *name, unsigned flags)
{
pass->flags = flags;
return def_graph_pass_constructor(
&pass->pass, name ? name : "osr", pass_wrapper);
-} /* opt_osr_pass */
+}
return REGION_CONST;
return NO_CONSTANT;
-} /* get_const_class */
+}
/**
* returns the operands of a commutative bin-op, if one operand is
*c = op_b;
break;
}
-} /* get_comm_Binop_ops */
+}
/**
* reassociate a Sub: x - c = x + (-c)
return 1;
}
return 0;
-} /* reassoc_Sub */
+}
/** Retrieve a mode from the operands. We need this, because
* Add and Sub are allowed to operate on (P, Is)
assert(m1 == m2);
return m1;
-} /* get_mode_from_ops */
+}
/**
* reassociate a commutative Binop
}
}
return 0;
-} /* reassoc_commutative */
+}
#define reassoc_Add reassoc_commutative
#define reassoc_And reassoc_commutative
}
}
return 0;
-} /* reassoc_Mul */
+}
/**
* Reassociate Shl. We transform Shl(x, const) into Mul's if possible.
return 1;
}
return 0;
-} /* reassoc_Shl */
+}
/**
* The walker for the reassociation.
waitq_put(wq, n);
set_irn_link(n, wq);
}
-} /* wq_walker */
+}
/**
* The walker for the reassociation.
}
}
}
-} /* do_reassociation */
+}
/**
* Returns the earliest were a,b are available.
if (res == get_irg_start_block(get_irn_irg(curr_blk)))
return curr_blk;
return res;
-} /* earliest_block */
+}
/**
* Checks whether a node is a Constant expression.
default:
return 0;
}
-} /* is_constant_expr */
+}
/**
* Apply distributive Law for Mul and Add/Sub
exchange(n, irn);
*node = irn;
return 1;
-} /* reverse_rule_distributive */
+}
/**
* Move Constants towards the root.
exchange(n, irn);
*node = irn;
return 1;
-} /* move_consts_up */
+}
/**
* Apply the rules in reverse order, removing code that was not collapsed
del_waitq(wq);
confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW);
-} /* optimize_reassociation */
+}
/* create a pass for the reassociation */
ir_graph_pass_t *optimize_reassociation_pass(const char *name)
{
return def_graph_pass(name ? name : "reassoc", optimize_reassociation);
-} /* optimize_reassociation_pass */
+}
static void register_node_reassoc_func(ir_op *op, reassociate_func func)
{
void firm_init_reassociation(void)
{
FIRM_DBG_REGISTER(dbg, "firm.opt.reassoc");
-} /* firm_init_reassociation */
+}
/* hacky cast to ir_node* */
set_irn_link((ir_node*)n, p);
}
- } /* if */
+ }
return p;
-} /* get_irn_dag_entry */
+}
#define set_irn_dag_entry(n, e) set_irn_link(n, e)
node = get_Proj_pred(node);
return is_Start(node);
-} /* is_arg */
+}
/**
* Allocate a new DAG entry.
set_irn_dag_entry(node, entry);
return entry;
-} /* new_dag_entry */
+}
/**
* Post-walker to detect DAG roots that are referenced form other blocks
if (dag_env->options & FIRMSTAT_COPY_CONSTANTS) {
if (is_irn_constlike(prev))
continue;
- } /* if */
+ }
entry = get_irn_dag_entry(prev);
/* found an unassigned node, a new root */
entry = new_dag_entry(dag_env, node);
entry->is_ext_ref = 1;
- } /* if */
- } /* for */
- } /* if */
+ }
+ }
+ }
} else {
for (i = 0, arity = get_irn_arity(node); i < arity; ++i) {
if (dag_env->options & FIRMSTAT_COPY_CONSTANTS) {
if (is_irn_constlike(prev))
continue;
- } /* if */
+ }
if (get_nodes_block(prev) != block) {
/* The predecessor is from another block. It forms
/* found an unassigned node, a new root */
entry = new_dag_entry(dag_env, node);
entry->is_ext_ref = 1;
- } /* if */
- } /* if */
- } /* for */
- } /* if */
-} /* find_dag_roots */
+ }
+ }
+ }
+ }
+}
/**
* Pre-walker for connecting DAGs and counting.
if (mode == mode_X || mode == mode_M) {
/* do NOT count mode_X and mode_M nodes */
return;
- } /* if */
+ }
/* if this option is set, Loads are always leaves */
if (dag_env->options & FIRMSTAT_LOAD_IS_LEAVE && is_Load(node))
if (! entry) {
/* found an unassigned node, maybe a new root */
entry = new_dag_entry(dag_env, node);
- } /* if */
+ }
/* put the predecessors into the same DAG as the current */
for (i = 0, arity = get_irn_arity(node); i < arity; ++i) {
if (is_irn_constlike(prev)) {
++entry->num_nodes;
++entry->num_inner_nodes;
- } /* if */
- } /* if */
+ }
+ }
/* only nodes from the same block goes into the DAG */
if (get_nodes_block(prev) == block) {
prev_entry->is_dead = 1;
prev_entry->link = entry;
- } /* if */
- } /* if */
- } /* if */
- } /* for */
-} /* connect_dags */
+ }
+ }
+ }
+ }
+}
#define DEFAULT_RET 1
#define COLOR_RET 1
if (mark_options & FIRMSTAT_CALL_IS_LEAVE && is_Call(n))
return DEFAULT_RET;
- } /* if */
+ }
entry = get_irn_dag_entry(n);
if (! entry)
/* I know the color! */
return COLOR_RET;
-} /* stat_dag_mark_hook */
+}
/**
* count the DAG's size of a graph
entry->num_inner_nodes,
(unsigned)entry->is_tree,
get_irn_node_nr(entry->root));
- } /* for */
+ }
#if 1
/* dump for test */
assert(id == root_env.num_of_dags);
obstack_free(&root_env.obst, NULL);
-} /* count_dags_in_graph */
+}
const node_entry_t *e2 = (const node_entry_t*)key;
return e1->op->code - e2->op->code;
-} /* opcode_cmp */
+}
/**
* Compare two elements of the graph hash.
const graph_entry_t *e2 = (const graph_entry_t*)key;
return e1->irg != e2->irg;
-} /* graph_cmp */
+}
/**
* Compare two elements of the optimization hash.
const opt_entry_t *e2 = (const opt_entry_t*)key;
return e1->op->code != e2->op->code;
-} /* opt_cmp */
+}
/**
* Compare two elements of the block hash.
/* it's enough to compare the block number */
return e1->block_nr != e2->block_nr;
-} /* block_cmp */
+}
/**
* Compare two elements of the be_block hash.
const be_block_entry_t *e2 = (const be_block_entry_t*)key;
return e1->block_nr != e2->block_nr;
-} /* be_block_cmp */
+}
/**
* Compare two elements of reg pressure hash.
const reg_pressure_entry_t *e2 = (const reg_pressure_entry_t*)key;
return e1->class_name != e2->class_name;
-} /* reg_pressure_cmp */
+}
/**
* Compare two elements of the perm_stat hash.
const perm_stat_entry_t *e2 = (const perm_stat_entry_t*)key;
return e1->perm != e2->perm;
-} /* perm_stat_cmp */
+}
/**
* Compare two elements of the perm_class hash.
const perm_class_entry_t *e2 = (const perm_class_entry_t*)key;
return e1->class_name != e2->class_name;
-} /* perm_class_cmp */
+}
/**
* Compare two elements of the ir_op hash.
const ir_op *e2 = (const ir_op*)key;
return e1->code != e2->code;
-} /* opcode_cmp_2 */
+}
/**
* Compare two elements of the address_mark set.
/* compare only the nodes, the rest is used as data container */
return e1->node != e2->node;
-} /* address_mark_cmp */
+}
/**
* Clear all counter in a node_entry_t.
cnt_clr(&elem->new_node);
cnt_clr(&elem->into_Id);
cnt_clr(&elem->normalized);
-} /* opcode_clear_entry */
+}
/**
* Returns the associates node_entry_t for an ir_op (and allocates
elem->op = op;
return (node_entry_t*)pset_insert(hmap, elem, op->code);
-} /* opcode_get_entry */
+}
/**
* Returns the associates ir_op for an opcode
key.code = code;
return (ir_op*)pset_find(hmap, &key, code);
-} /* opcode_find_entry */
+}
/**
* Clears all counter in a graph_entry_t.
/* clear accumulated / non-accumulated counter */
for (i = all ? 0 : _gcnt_non_acc; i < _gcnt_last; ++i) {
cnt_clr(&elem->cnt[i]);
- } /* for */
+ }
if (elem->block_hash) {
del_pset(elem->block_hash);
elem->block_hash = NULL;
- } /* if */
+ }
obstack_free(&elem->recalc_cnts, NULL);
obstack_init(&elem->recalc_cnts);
-} /* graph_clear_entry */
+}
/**
* Returns the associated graph_entry_t for an IR graph.
elem->be_block_hash = new_pset(be_block_cmp, 5);
return elem;
- } /* if */
+ }
/* allocate a new one */
elem = OALLOCZ(&status->cnts, graph_entry_t);
elem->opt_hash[i] = new_pset(opt_cmp, 4);
return (graph_entry_t*)pset_insert(hmap, elem, hash_ptr(irg));
-} /* graph_get_entry */
+}
/**
* Clear all counter in an opt_entry_t.
static void opt_clear_entry(opt_entry_t *elem)
{
cnt_clr(&elem->count);
-} /* opt_clear_entry */
+}
/**
* Returns the associated opt_entry_t for an IR operation.
elem->op = op;
return (opt_entry_t*)pset_insert(hmap, elem, op->code);
-} /* opt_get_entry */
+}
/**
* clears all counter in a block_entry_t
for (i = 0; i < _bcnt_last; ++i)
cnt_clr(&elem->cnt[i]);
-} /* block_clear_entry */
+}
/**
* Returns the associated block_entry_t for an block.
elem->block_nr = block_nr;
return (block_entry_t*)pset_insert(hmap, elem, block_nr);
-} /* block_get_entry */
+}
/**
* Clear all sets in be_block_entry_t.
elem->reg_pressure = new_pset(reg_pressure_cmp, 5);
elem->sched_ready = stat_new_int_distrib_tbl();
elem->perm_class_stat = new_pset(perm_class_cmp, 5);
-} /* be_block_clear_entry */
+}
/**
* Returns the associated be_block_entry_t for an block.
elem->block_nr = block_nr;
return (be_block_entry_t*)pset_insert(hmap, elem, block_nr);
-} /* be_block_get_entry */
+}
/**
* clears all sets in perm_class_entry_t
del_pset(elem->perm_stat);
elem->perm_stat = new_pset(perm_stat_cmp, 5);
-} /* perm_class_clear_entry */
+}
/**
* Returns the associated perm_class entry for a register class.
elem->class_name = class_name;
return (perm_class_entry_t*)pset_insert(hmap, elem, hash_ptr(class_name));
-} /* perm_class_get_entry */
+}
/**
* clears all sets in perm_stat_entry_t
elem->chains = stat_new_int_distrib_tbl();
elem->cycles = stat_new_int_distrib_tbl();
-} /* perm_stat_clear_entry */
+}
/**
* Returns the associated perm_stat entry for a perm.
elem->perm = perm;
return (perm_stat_entry_t*)pset_insert(hmap, elem, hash_ptr(perm));
-} /* perm_stat_get_entry */
+}
/**
* Clear optimizations counter,
} else if (get_irn_mode(node) == mode_M) {
/* special case, a Memory Phi node, count on extra counter */
op = status->op_PhiM ? status->op_PhiM : op;
- } /* if */
+ }
break;
case iro_Proj:
if (get_irn_mode(node) == mode_M) {
/* special case, a Memory Proj node, count on extra counter */
op = status->op_ProjM ? status->op_ProjM : op;
- } /* if */
+ }
break;
case iro_Mul:
if (is_Const(get_Mul_left(node)) || is_Const(get_Mul_right(node))) {
/* special case, a Multiply by a const, count on extra counter */
op = status->op_MulC ? status->op_MulC : op;
- } /* if */
+ }
break;
case iro_Div:
if (is_Const(get_Div_right(node))) {
/* special case, a division by a const, count on extra counter */
op = status->op_DivC ? status->op_DivC : op;
- } /* if */
+ }
break;
case iro_Mod:
if (is_Const(get_Mod_right(node))) {
/* special case, a module by a const, count on extra counter */
op = status->op_ModC ? status->op_ModC : op;
- } /* if */
+ }
break;
case iro_Sel:
if (is_Sel(get_Sel_ptr(node))) {
if (is_Sel(get_Sel_ptr(get_Sel_ptr(node)))) {
/* special case, a Sel of a Sel of a Sel, count on extra counter */
op = status->op_SelSelSel ? status->op_SelSelSel : op;
- } /* if */
- } /* if */
+ }
+ }
break;
default:
break;
- } /* switch */
+ }
return op;
-} /* stat_get_irn_op */
+}
/**
* update the block counter
cnt_inc(&b_entry->cnt[bcnt_in_edges]); /* an edge coming from another block */
cnt_inc(&b_entry_other->cnt[bcnt_out_edges]);
- } /* for */
+ }
return;
- } /* if */
+ }
block = get_nodes_block(node);
b_entry = block_get_entry(&graph->recalc_cnts, get_irn_node_nr(block), graph->block_hash);
if (is_Phi(node) && mode_is_datab(get_irn_mode(node))) {
/* count data Phi per block */
cnt_inc(&b_entry->cnt[bcnt_phi_data]);
- } /* if */
+ }
/* we have a new node in our block */
cnt_inc(&b_entry->cnt[bcnt_nodes]);
cnt_inc(&b_entry->cnt[bcnt_in_edges]); /* an edge coming from another block */
cnt_inc(&b_entry_other->cnt[bcnt_out_edges]);
- } /* if */
- } /* for */
-} /* undate_block_info */
+ }
+ }
+}
/**
* Calculates how many arguments of the call are const, updates
++num_local_adr;
}
- } /* for */
+ }
if (num_const_args > 0)
cnt_inc(&graph->cnt[gcnt_call_with_cnst_arg]);
cnt_inc(&graph->cnt[gcnt_call_with_local_adr]);
stat_inc_int_distrib_tbl(status->dist_param_cnt, n);
-} /* analyse_params_of_Call */
+}
/**
* Update info on calls.
graph->is_recursive = 1;
if (callee == NULL)
cnt_inc(&graph->cnt[gcnt_external_calls]);
- } /* if */
+ }
} else {
/* indirect call, be could not predict */
cnt_inc(&graph->cnt[gcnt_indirect_calls]);
/* NOT a leaf call */
graph->is_leaf_call = LCS_NON_LEAF_CALL;
- } /* if */
+ }
/* check, if it's a chain-call: Then, the call-block
* must dominate the end block. */
if (! curr || !is_Block(curr))
break;
- } /* for */
+ }
if (curr != block)
graph->is_chain_call = 0;
if (called->is_analyzed) {
if (! called->is_leaf)
graph->is_leaf_call = LCS_NON_LEAF_CALL;
- } /* if */
- } /* if */
+ }
+ }
analyse_params_of_Call(graph, call);
-} /* stat_update_call */
+}
/**
* Update info on calls for graphs on the wait queue.
/* ok, we seems to know the entity */
ent = get_SymConst_entity(ptr);
callee = get_entity_irg(ent);
- } /* if */
- } /* if */
+ }
+ }
/* check, if the callee is a leaf */
if (callee) {
graph->is_leaf_call = LCS_NON_LEAF_CALL;
} else
graph->is_leaf_call = LCS_NON_LEAF_CALL;
-} /* stat_update_call_2 */
+}
/**
* Find the base address and entity of an Sel node.
ptr = get_Sel_ptr(sel);
}
return ptr;
-} /* find_base_adr */
+}
/**
* Update info on Load/Store address statistics.
/* THIS pointer */
cnt_inc(&graph->cnt[gcnt_this_adr]);
goto end_parameter;
- } /* if */
- } /* if */
- } /* if */
+ }
+ }
+ }
/* other parameter */
cnt_inc(&graph->cnt[gcnt_param_adr]);
end_parameter: ;
} else {
/* unknown Pointer access */
cnt_inc(&graph->cnt[gcnt_other_adr]);
- } /* if */
- } /* if */
+ }
+ }
default:
break;
- } /* switch */
-} /* stat_update_address */
+ }
+}
/**
* Walker for reachable nodes count.
}
default:
break;
- } /* switch */
+ }
/* we want to count the constant IN nodes, not the CSE'ed constant's itself */
if (status->stat_options & FIRMSTAT_COUNT_CONSTS) {
if (is_Const(pred)) {
/* check properties of constants */
stat_update_const(status, pred, graph);
- } /* if */
- } /* for */
- } /* if */
-} /* update_node_stat */
+ }
+ }
+ }
+}
/**
* Walker for reachable nodes count for graphs on the wait_q.
/* check for properties that depends on calls like recursion/leaf/indirect call */
if (is_Call(node))
stat_update_call_2(node, graph);
-} /* update_node_stat_2 */
+}
/**
* Get the current address mark.
address_mark_entry_t *value = set_find(address_mark_entry_t, graph->address_mark, &val, sizeof(val), hash_ptr(node));
return value ? value->mark : 0;
-} /* get_adr_mark */
+}
/**
* Set the current address mark.
{
address_mark_entry_t const value = { node, val };
(void)set_insert(address_mark_entry_t, graph->address_mark, &value, sizeof(value), hash_ptr(node));
-} /* set_adr_mark */
+}
#undef DUMP_ADR_MODE
/* I know the color! */
return 1;
-} /* stat_adr_mark_hook */
+}
#endif /* DUMP_ADR_MODE */
/**
/* Cmp is no address calculation, or is it? */
default:
return get_irn_mode(node);
- } /* switch */
-} /* get_irn_op_mode */
+ }
+}
/**
* Post-walker that marks every node that is an address calculation.
* referenced by address calculations
*/
mark_preds = MARK_REF_ADR;
- } /* if */
- } /* if */
+ }
+ }
/* mark all predecessors */
for (i = 0, n = get_irn_arity(node); i < n; ++i) {
continue;
set_adr_mark(graph, pred, get_adr_mark(graph, pred) | mark_preds);
- } /* for */
-} /* mark_address_calc */
+ }
+}
/**
* Post-walker that marks every node that is an address calculation.
cnt_inc(&graph->cnt[gcnt_pure_adr_ops]);
else if ((mark & (MARK_REF_ADR | MARK_REF_NON_ADR)) == (MARK_REF_ADR|MARK_REF_NON_ADR))
cnt_inc(&graph->cnt[gcnt_all_adr_ops]);
-} /* count_adr_ops */
+}
/**
* Called for every graph when the graph is either deleted or stat_dump_snapshot()
/* clear first the alive counter in the graph */
foreach_pset(graph->opcode_hash, node_entry_t, entry) {
cnt_clr(&entry->cnt_alive);
- } /* foreach_pset */
+ }
/* set pessimistic values */
graph->is_leaf = 1;
/* we need dominator info */
if (graph->irg != get_const_code_irg()) {
assure_doms(graph->irg);
- } /* if */
+ }
/* count the nodes in the graph */
irg_walk_graph(graph->irg, update_node_stat, NULL, graph);
/* update the node counter */
cnt_add(&g_entry->cnt_alive, &entry->cnt_alive);
- } /* foreach_pset */
+ }
/* count the number of address calculation */
if (graph->irg != get_const_code_irg()) {
#endif /* DUMP_ADR_MODE */
irg_walk_graph(graph->irg, NULL, count_adr_ops, graph);
- } /* if */
+ }
/* count the DAG's */
if (status->stat_options & FIRMSTAT_COUNT_DAG)
else if (graph->is_leaf_call == LCS_UNKNOWN) {
/* we still don't know if this graph calls leaf-functions, so enqueue */
pdeq_putl(status->wait_q, graph);
- } /* if */
+ }
/* we have analyzed this graph */
graph->is_analyzed = 1;
/* accumulate all counter's */
for (i = 0; i < _gcnt_last; ++i)
cnt_add(&global->cnt[i], &graph->cnt[i]);
-} /* update_graph_stat */
+}
/**
* Called for every graph that was on the wait_q in stat_dump_snapshot()
if (graph->is_leaf_call == LCS_UNKNOWN)
graph->is_leaf_call = LCS_LEAF_CALL;
- } /* if */
-} /* update_graph_stat_2 */
+ }
+}
/**
* Register a dumper.
status->dumper = p;
/* FIXME: memory leak */
-} /* stat_register_dumper */
+}
/**
* Dumps the statistics of an IR graph.
for (dumper = status->dumper; dumper; dumper = dumper->next) {
if (dumper->dump_graph)
dumper->dump_graph(dumper, entry);
- } /* for */
-} /* stat_dump_graph */
+ }
+}
/**
* Calls all registered dumper functions.
if (dumper->func_map) {
foreach_pset(dumper->func_map, dump_graph_FUNC, func)
func(dumper, entry);
- } /* if */
- } /* for */
-} /* stat_dump_registered */
+ }
+ }
+}
/**
* Dumps a constant table.
for (dumper = status->dumper; dumper; dumper = dumper->next) {
if (dumper->dump_const_tbl)
dumper->dump_const_tbl(dumper, tbl);
- } /* for */
-} /* stat_dump_consts */
+ }
+}
/**
* Dumps the parameter distribution
for (dumper = status->dumper; dumper; dumper = dumper->next) {
if (dumper->dump_param_tbl)
dumper->dump_param_tbl(dumper, tbl, global);
- } /* for */
-} /* stat_dump_param_tbl */
+ }
+}
/**
* Dumps the optimization counter
for (dumper = status->dumper; dumper; dumper = dumper->next) {
if (dumper->dump_opt_cnt)
dumper->dump_opt_cnt(dumper, tbl, len);
- } /* for */
-} /* stat_dump_opt_cnt */
+ }
+}
/**
* Initialize the dumper.
for (dumper = status->dumper; dumper; dumper = dumper->next) {
if (dumper->init)
dumper->init(dumper, name);
- } /* for */
-} /* stat_dump_init */
+ }
+}
/**
* Finish the dumper.
for (dumper = status->dumper; dumper; dumper = dumper->next) {
if (dumper->finish)
dumper->finish(dumper);
- } /* for */
-} /* stat_dump_finish */
+ }
+}
/**
* Register an additional function for all dumper.
if (! dumper->func_map)
dumper->func_map = pset_new_ptr(3);
pset_insert_ptr(dumper->func_map, (void*)func);
- } /* for */
-} /* stat_register_dumper_func */
+ }
+}
/* ---------------------------------------------------------------------- */
ir_op *stat_get_op_from_opcode(unsigned code)
{
return opcode_find_entry((ir_opcode)code, status->ir_op_hash);
-} /* stat_get_op_from_opcode */
+}
/**
* Hook: A new IR op is registered.
pset_insert(status->ir_op_hash, op, op->code);
}
STAT_LEAVE;
-} /* stat_new_ir_op */
+}
/**
* Hook: An IR op is freed.
{
}
STAT_LEAVE;
-} /* stat_free_ir_op */
+}
/**
* Hook: A new node is created.
cnt_inc(&entry->new_node);
}
STAT_LEAVE;
-} /* stat_new_node */
+}
/**
* Hook: A node is changed into a Id node
cnt_inc(&entry->into_Id);
}
STAT_LEAVE;
-} /* stat_turn_into_id */
+}
/**
* Hook: A node is normalized
cnt_inc(&entry->normalized);
}
STAT_LEAVE;
-} /* stat_normalize */
+}
/**
* Hook: A new graph was created
graph->is_analyzed = 0;
}
STAT_LEAVE;
-} /* stat_new_graph */
+}
/**
* Hook: A graph will be deleted
if (status->stat_options & FIRMSTAT_COUNT_DELETED) {
/* count the nodes of the graph yet, it will be destroyed later */
update_graph_stat(global, graph);
- } /* if */
+ }
}
STAT_LEAVE;
-} /* stat_free_graph */
+}
/**
* Hook: A walk over a graph is initiated. Do not count walks from statistic code.
cnt_inc(&graph->cnt[gcnt_acc_walked]);
}
STAT_LEAVE;
-} /* stat_irg_walk */
+}
/**
* Hook: A walk over a graph in block-wise order is initiated. Do not count walks from statistic code.
{
/* for now, do NOT differentiate between blockwise and normal */
stat_irg_walk(ctx, irg, pre, post);
-} /* stat_irg_walk_blkwise */
+}
/**
* Hook: A walk over the graph's blocks is initiated. Do not count walks from statistic code.
cnt_inc(&graph->cnt[gcnt_acc_walked_blocks]);
}
STAT_LEAVE;
-} /* stat_irg_block_walk */
+}
/**
* Called for every node that is removed due to an optimization.
/* increase global value */
entry = opt_get_entry(op, hmap);
cnt_inc(&entry->count);
-} /* removed_due_opt */
+}
/**
* Hook: Some nodes were optimized into some others due to an optimization.
for (j = 0; j < new_num_entries; ++j) {
if (old_node_array[i] == new_node_array[j])
break;
- } /* for */
+ }
if (j >= new_num_entries) {
int xopt = opt;
ir_node *const irn = new_node_array[0];
if (is_Const(irn) || is_SymConst(irn))
xopt = HOOK_OPT_CONFIRM_C;
- } /* if */
+ }
removed_due_opt(old_node_array[i], graph->opt_hash[xopt], (hook_opt_kind)xopt);
- } /* if */
- } /* for */
+ }
+ }
}
STAT_LEAVE;
-} /* stat_merge_nodes */
+}
/**
* Hook: Reassociation is started/stopped.
status->reassoc_run = flag;
}
STAT_LEAVE;
-} /* stat_reassociate */
+}
/**
* Hook: A node was lowered into other nodes
removed_due_opt(node, graph->opt_hash[HOOK_LOWERED], HOOK_LOWERED);
}
STAT_LEAVE;
-} /* stat_lower */
+}
/**
* Hook: A graph was inlined.
cnt_inc(&i_graph->cnt[gcnt_acc_was_inlined]);
}
STAT_LEAVE;
-} /* stat_inline */
+}
/**
* Hook: A graph with tail-recursions was optimized.
graph->num_tail_recursion += n_calls;
}
STAT_LEAVE;
-} /* stat_tail_rec */
+}
/**
* Strength reduction was performed on an iteration variable.
removed_due_opt(strong, graph->opt_hash[HOOK_OPT_STRENGTH_RED], HOOK_OPT_STRENGTH_RED);
}
STAT_LEAVE;
-} /* stat_strength_red */
+}
/**
* Hook: Start/Stop the dead node elimination.
return;
status->in_dead_node_elim = (start != 0);
-} /* stat_dead_node_elim */
+}
/**
* Hook: if-conversion was tried.
cnt_inc(&graph->cnt[gcnt_if_conv + reason]);
}
STAT_LEAVE;
-} /* stat_if_conversion */
+}
/**
* Hook: real function call was optimized.
cnt_inc(&graph->cnt[gcnt_acc_real_func_call]);
}
STAT_LEAVE;
-} /* stat_func_call */
+}
/**
* Hook: A multiply was replaced by a series of Shifts/Adds/Subs.
removed_due_opt(mul, graph->opt_hash[HOOK_OPT_ARCH_DEP], HOOK_OPT_ARCH_DEP);
}
STAT_LEAVE;
-} /* stat_arch_dep_replace_mul_with_shifts */
+}
/**
* Hook: A division by const was replaced.
removed_due_opt(node, graph->opt_hash[HOOK_OPT_ARCH_DEP], HOOK_OPT_ARCH_DEP);
}
STAT_LEAVE;
-} /* stat_arch_dep_replace_division_by_const */
+}
/*
* Update the register pressure of a block.
pset_insert(block_ent->reg_pressure, rp_ent, hash_ptr(class_name));
}
STAT_LEAVE;
-} /* stat_be_block_regpressure */
+}
/**
* Update the distribution of ready nodes of a block
stat_inc_int_distrib_tbl(block_ent->sched_ready, num_ready);
}
STAT_LEAVE;
-} /* stat_be_block_sched_ready */
+}
/**
* Update the permutation statistic of a block.
ps_ent->real_size = real_size;
}
STAT_LEAVE;
-} /* stat_be_block_stat_perm */
+}
/**
* Update the permutation statistic of a single perm.
} else {
ps_ent->n_exchg += n_ops;
stat_inc_int_distrib_tbl(ps_ent->cycles, size);
- } /* if */
+ }
}
STAT_LEAVE;
-} /* stat_be_block_stat_permcycle */
+}
/* Dumps a statistics snapshot. */
void stat_dump_snapshot(const char *name, const char *phase)
} else {
fname[0] = '\0';
p = name;
- } /* if */
+ }
strncat(fname, "firmstat-", sizeof(fname)-strlen(fname)-1);
strncat(fname, phase, sizeof(fname)-strlen(fname)-1);
strncat(fname, "-", sizeof(fname)-strlen(fname)-1);
if (entry->irg == NULL) {
/* special entry for the global count */
continue;
- } /* if */
+ }
if (! entry->is_deleted) {
/* the graph is still alive, count the nodes on it */
update_graph_stat(global, entry);
- } /* if */
- } /* for */
+ }
+ }
/* some calculations are dependent, we pushed them on the wait_q */
while (! pdeq_empty(status->wait_q)) {
graph_entry_t *const entry = (graph_entry_t*)pdeq_getr(status->wait_q);
update_graph_stat_2(global, entry);
- } /* while */
+ }
/* dump per graph */
foreach_pset(status->irg_hash, graph_entry_t, entry) {
if (entry->irg == NULL) {
/* special entry for the global count */
continue;
- } /* if */
+ }
if (! entry->is_deleted || status->stat_options & FIRMSTAT_COUNT_DELETED) {
stat_dump_graph(entry);
stat_dump_registered(entry);
- } /* if */
+ }
if (! entry->is_deleted) {
/* clear the counter that are not accumulated */
graph_clear_entry(entry, 0);
- } /* if */
- } /* for */
+ }
+ }
/* dump global */
stat_dump_graph(global);
/* clear the global counters here */
foreach_pset(global->opcode_hash, node_entry_t, entry) {
opcode_clear_entry(entry);
- } /* for */
+ }
/* clear all global counter */
graph_clear_entry(global, /*all=*/1);
}
STAT_LEAVE;
-} /* stat_dump_snapshot */
+}
typedef struct pass_t {
ir_prog_pass_t pass;
(void)irp;
stat_dump_snapshot(pass->fname, pass->phase);
return 0;
-} /* stat_dump_snapshot_wrapper */
+}
/**
* Ensure that no verifier is run from the wrapper.
pass->pass.verify_irprog = no_verify;
return &pass->pass;
-} /* stat_dump_snapshot_pass */
+}
/** the hook entries for the Firm statistics module */
static hook_entry_t stat_hooks[hook_last];
status->op_MulC = NULL;
status->op_DivC = NULL;
status->op_ModC = NULL;
- } /* if */
+ }
/* for Florian: count the Sel depth */
if (stat_options & FIRMSTAT_COUNT_SELS) {
} else {
status->op_SelSel = NULL;
status->op_SelSelSel = NULL;
- } /* if */
+ }
/* register the dumper */
stat_register_dumper(&simple_dumper);
#undef HOOK
#undef X
-} /* firm_init_stat */
+}
/**
* Frees all dumper structures.
next_dumper = dumper->next;
free(dumper);
dumper = next_dumper;
- } /* for */
-} /* stat_term_dumper */
+ }
+}
/* Terminates the statistics module, frees all memory. */
xfree(status);
status = (stat_info_t *)&status_disable;
}
-} /* stat_term */
+}
/* returns 1 if statistics were initialized, 0 otherwise */
int stat_is_active(void)
{
return status != (stat_info_t *)&status_disable;
-} /* stat_is_active */
+}
void init_stat(void)
{
cmp = cnt_cmp(&(*e2)->count, &(*e1)->count);
return cmp;
-} /* pattern_count_cmp */
+}
/**
* Compare two pattern for its pattern hash.
return memcmp(e1->buf, e2->buf, e1->len);
return e1->len < e2->len ? -1 : +1;
-} /* pattern_cmp */
+}
/**
* Initialize a code buffer.
buf->end = data + len;
buf->hash = 0x2BAD4; /* An arbitrary seed. */
buf->overrun = 0;
-} /* init_buf */
+}
/**
* Put a byte into the buffer.
} else {
buf->overrun = 1;
}
-} /* put_byte */
+}
/**
* Returns the current length of a buffer.
static size_t buf_lenght(const CODE_BUFFER *buf)
{
return buf->next - buf->start;
-} /* buf_lenght */
+}
/**
* Returns the current content of a buffer.
static const BYTE *buf_content(const CODE_BUFFER *buf)
{
return buf->start;
-} /* buf_content */
+}
/**
* Returns the hash value of a buffer.
static unsigned buf_hash(const CODE_BUFFER *buf)
{
return buf->hash;
-} /* buf_hash */
+}
/**
* Returns non-zero if a buffer overrun has occurred.
static unsigned buf_overrun(const CODE_BUFFER *buf)
{
return buf->overrun;
-} /* buf_overrun */
+}
/**
* Returns the next byte from the buffer WITHOUT dropping.
if (buf->next < buf->end)
return *buf->next;
return VLC_TAG_END;
-} /* look_byte */
+}
/**
* Returns the next byte from the buffer WITH dropping.
if (buf->next < buf->end)
return *buf->next++;
return VLC_TAG_END;
-} /* get_byte */
+}
#define BITS(n) (1 << (n))
put_byte(buf, code >> 16);
put_byte(buf, code >> 8);
put_byte(buf, code);
- } /* if */
-} /* put_code */
+ }
+}
#define BIT_MASK(n) ((1 << (n)) - 1)
code = ((code & BIT_MASK(5)) << 16) | (get_byte(buf) << 8);
code |= get_byte(buf);
return code;
- } /* if */
+ }
if (code < VLC_32BIT) {
code = ((code & BIT_MASK(4)) << 24) | (get_byte(buf) << 16);
code |= get_byte(buf) << 8;
code |= get_byte(buf);
return code;
- } /* if */
+ }
if (code == VLC_32BIT) {
code = get_byte(buf) << 24;
code |= get_byte(buf) << 16;
code |= get_byte(buf) << 8;
code |= get_byte(buf);
return code;
- } /* if */
+ }
/* should not happen */
panic("Wrong code in buffer");
-} /* get_code */
+}
/**
* Put a tag into the buffer.
assert(tag >= VLC_TAG_FIRST && "invalid tag");
put_byte(buf, tag);
-} /* put_tag */
+}
/**
* Returns the next tag or zero if the next code isn't a tag.
if (b >= VLC_TAG_FIRST)
return get_byte(buf);
return 0;
-} /* next_tag */
+}
/**
* An Environment for the pattern encoder.
(void) size;
return e1->addr != e2->addr;
-} /* addr_cmp */
+}
/**
* Return the index of a (existing) mode.
} else {
/* a new entry, proceed */
++env->curr_id;
- } /* if */
+ }
put_code(env->buf, (unsigned)code);
put_code(env->buf, find_mode_index(mode));
else
put_tag(env->buf, VLC_TAG_EMPTY);
- } /* if */
+ }
/* do we need integer constants */
if (env->options & OPT_WITH_ICONST) {
put_tag(env->buf, VLC_TAG_ICONST);
put_code(env->buf, v);
- } /* if */
- } /* if */
- } /* if */
+ }
+ }
+ }
--max_depth;
if (max_depth <= 0) {
put_code(env->buf, 0);
return max_depth;
- } /* if */
+ }
preds = get_irn_arity(node);
put_code(env->buf, preds);
} else if (opcode_diff == 0 && l != r) {
/* Both nodes have the same opcode, but are different.
Need a better method here to decide which goes to the left side. */
- } /* if */
+ }
/* special handling for commutative operators */
depth = _encode_node(l, max_depth, env);
depth = _encode_node(n, max_depth, env);
if (depth < res)
res = depth;
- } /* for */
- } /* if */
+ }
+ }
return res;
-} /* _encode_node */
+}
/**
* Encode a DAG starting by the IR-node node.
if (env.options) {
put_tag(buf, VLC_TAG_OPTION);
put_code(buf, env.options);
- } /* if */
+ }
res = _encode_node(node, max_depth, &env);
del_set(env.id_set);
return max_depth - res;
-} /* encode_node */
+}
/**
* Decode an IR-node, recursive walker.
* we don't know the target here, it's a ref.
*/
pattern_dump_edge(env->dmp, code, parent, position, edge_mode);
- } /* if */
+ }
/* dump the node ref */
pattern_dump_ref(env->dmp, code);
return;
- } /* if */
+ }
/* get the opcode */
op_code = get_code(env->buf);
if (env->options & OPT_WITH_MODE) {
if (next_tag(env->buf) != VLC_TAG_EMPTY) {
mode_code = get_code(env->buf);
- } /* if */
- } /* if */
+ }
+ }
/* check, if a ICONST attribute is given */
if (next_tag(env->buf) == VLC_TAG_ICONST) {
iconst = get_code(env->buf);
attr = &iconst;
- } /* if */
+ }
/* dump the edge */
if (parent) {
* we need it anyway for ref's.
*/
pattern_dump_edge(env->dmp, env->curr_id, parent, position, edge_mode);
- } /* if */
+ }
/* dump the node */
parent = env->curr_id;
pattern_start_children(env->dmp, parent);
for (i = 0; i < preds; ++i) {
_decode_node(parent, i, env);
- } /* for */
+ }
pattern_finish_children(env->dmp, parent);
- } /* if */
- } /* if */
-} /* _decode_node */
+ }
+ }
+}
/**
* Decode an IR-node.
code = next_tag(&buf);
if (code == VLC_TAG_OPTION) {
options = get_code(&buf);
- } /* if */
+ }
env.options = options;
_decode_node(0, 0, &env);
-} /* decode_node */
+}
/**
* The environment for the pattern calculation.
if (elem != NULL) {
obstack_free(&status->obst, key);
return elem;
- } /* if */
+ }
cnt_clr(&key->count);
return (pattern_entry_t*)pset_insert(set, key, hash);
-} /* pattern_get_entry */
+}
/**
* Increase the count for a pattern.
/* increase count */
cnt_inc(&entry->count);
- } /* if */
-} /* count_pattern */
+ }
+}
/**
* Pre-walker for nodes pattern calculation.
lc_fprintf(stderr, "Pattern store: buffer overrun at size %zu. Pattern ignored.\n", sizeof(buffer));
} else
count_pattern(&buf, depth);
-} /* calc_nodes_pattern */
+}
/**
* Store all collected patterns.
if (! f) {
perror(fname);
return;
- } /* if */
+ }
fwrite("FPS1", 4, 1, f);
fwrite(&count, sizeof(count), 1, f);
foreach_pset(status->pattern_hash, pattern_entry_t, entry) {
fwrite(entry, offsetof(pattern_entry_t, buf) + entry->len, 1, f);
- } /* for */
+ }
fclose(f);
-} /* store_pattern */
+}
/**
* Read collected patterns from a file.
if (! f) {
perror(fname);
return NULL;
- } /* if */
+ }
res = fread(magic, 4, 1, f);
if (res != 1)
put_byte(&buf, fgetc(f));
entry = pattern_get_entry(&buf, pattern_hash);
entry->count = tmp.count;
- } /* for */
+ }
fclose(f);
lc_printf("Read %zu pattern from %s\n", count, fname);
fprintf(stderr, "Error: %s is not a Firm pattern store. Ignored.\n", fname);
fclose(f);
return NULL;
-} /* read_pattern */
+}
/**
* Write the collected patterns to a VCG file for inspection.
i = 0;
foreach_pset(status->pattern_hash, pattern_entry_t, entry) {
pattern_arr[i++] = entry;
- } /* for */
+ }
assert(count == i);
count = i;
pattern_dump_new_pattern(dump, &entry->count);
decode_node(entry->buf, entry->len, dump);
pattern_dump_finish_pattern(dump);
- } /* for */
+ }
/* destroy it */
pattern_end(dump);
-} /* pattern_output */
+}
/*
* Calculates the pattern history.
for (i = status->min_depth; i <= status->max_depth; ++i) {
env.max_depth = i;
irg_walk_graph(irg, calc_nodes_pattern, NULL, &env);
- } /* for */
-} /* stat_calc_pattern_history */
+ }
+}
/*
* Initializes the pattern history.
if (pattern_hash == NULL)
pattern_hash = new_pset(pattern_cmp, 8);
status->pattern_hash = pattern_hash;
-} /* stat_init_pattern_history */
+}
/*
* Finish the pattern history.
obstack_free(&status->obst, NULL);
status->enable = 0;
-} /* stat_finish_pattern_history */
+}
" port_sharing: no\n"
" orientation: bottom_to_top\n"
);
-} /* vcg_dump_start */
+}
/**
* Ends a new VCG graph.
fprintf(priv->f, "}\n");
fclose(priv->f);
-} /* vcg_dump_end */
+}
/**
* Starts a new pattern.
" node: {title: \"c%u\" label: \"cnt: %u\" color:red }\n",
++nr, cnt_to_uint(cnt)
);
-} /* vcg_dump_new_pattern */
+}
/**
* Finish the current pattern.
priv->pattern_id - 1);
++priv->pattern_id;
-} /* vcg_dump_finish_pattern */
+}
/**
* Dumps a node.
} else {
fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s n%u\" }\n",
priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", id);
- } /* if */
-} /* vcg_dump_node */
+ }
+}
/**
* Dumps an edge.
priv->pattern_id, tgt,
pos
);
-} /* vcg_dump_edge */
+}
/**
* The VCG dumper.
FILE *f = (FILE*)self->data;
fprintf(f, "%8u ", cnt_to_uint(cnt));
-} /* stdout_dump_new_pattern */
+}
/**
FILE *f = (FILE*)self->data;
fprintf(f, "\n");
-} /* stdout_dump_finish_pattern */
+}
/**
* Dumps a node.
if (mode)
fprintf(f, "%s", get_mode_name(mode));
-} /* stdout_dump_node */
+}
/**
* Dump a ref
FILE *f = (FILE*)self->data;
fprintf(f, "REF:%u", id);
-} /* stdout_dump_ref */
+}
/**
* Dump an edge.
if (pos > 0)
fprintf(f, ", ");
-} /* stdout_dump_edge */
+}
/**
* Start the children dumper.
(void) id;
fprintf(f, "(");
-} /* stdout_start_children */
+}
/**
* Finish the children dumper.
(void) id;
fprintf(f, ")");
-} /* stdout_finish_children */
+}
/**
* The stdout dumper.
{
if (self->dump_new_pattern)
self->dump_new_pattern(self, cnt);
-} /* pattern_dump_new_pattern */
+}
/*
{
if (self->dump_finish_pattern)
self->dump_finish_pattern(self);
-} /* pattern_dump_finish_pattern */
+}
/*
{
if (self->dump_node)
self->dump_node(self, id, op_code, mode_code, attr);
-} /* pattern_dump_node */
+}
/*
* Dump a ref.
{
if (self->dump_ref)
self->dump_ref(self, id);
-} /* pattern_dump_ref */
+}
/*
* Dump an edge.
{
if (self->dump_edge)
self->dump_edge(self, tgt, src, pos, mode_code);
-} /* pattern_dump_edge */
+}
/*
* Start the children dumper.
{
if (self->dump_start_children)
self->dump_start_children(self, id);
-} /* pattern_start_children */
+}
/*
* Finish the the children dumper.
{
if (self->dump_finish_children)
self->dump_finish_children(self, id);
-} /* pattern_finish_children */
+}
/*
* Finish the the dumper.
self->dump_end(self);
free(self);
-} /* pattern_end */
+}
/**
* pattern dumper factory for text dumper
if (res->dump_start)
res->dump_start(res);
return res;
-} /* new_text_dumper */
+}
/**
* pattern dumper factory for vcg dumper
if (res->dump_start)
res->dump_start(res);
- } /* if */
+ }
return res;
-} /* new_vcg_dumper */
+}
cnt_add(&f_new_node, &entry->new_node);
cnt_add(&f_Id, &entry->into_Id);
cnt_add(&f_normlized, &entry->normalized);
- } /* foreach_pset */
+ }
fprintf(dmp->f, "-------------------------------------------\n");
fprintf(dmp->f, "%-16s %8u %8u %8u %8u\n", "Sum",
cnt_to_uint(&f_alive),
cnt_to_uint(&f_Id),
cnt_to_uint(&f_normlized)
);
-} /* simple_dump_opcode_hash */
+}
/**
* Return the name of an optimization.
assert(index < (int) ARRAY_SIZE(opt_names) && "index out of range");
assert((int) opt_names[index].kind == index && "opt_names broken");
return opt_names[index].name;
-} /* get_opt_name */
+}
/**
* dumps an optimization hash into human readable form
foreach_pset(set, opt_entry_t, entry) {
fprintf(dmp->f, "%-16s %8u\n",
get_id_str(entry->op->name), cnt_to_uint(&entry->count));
- } /* foreach_pset */
- } /* if */
-} /* simple_dump_opt_hash */
+ }
+ }
+}
/**
* dumps the register pressure for each block and for each register class
foreach_pset(b_entry->reg_pressure, reg_pressure_entry_t, rp_entry)
fprintf(dmp->f, "%15d", rp_entry->pressure);
fprintf(dmp->f, "\n");
- } /* for */
-} /* simple_dump_be_block_reg_pressure */
+ }
+}
/** prints a distribution entry */
static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env)
{
dumper_t *dmp = (dumper_t*)env;
fprintf(dmp->f, "%12u", cnt_to_uint(&entry->cnt));
-} /* simple_dump_distrib_entry */
+}
/**
* dumps the distribution of the amount of ready nodes for each block
stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
fprintf(dmp->f, "\n");
- } /* foreach_pset */
- } /* if */
-} /* simple_dump_be_block_sched_ready */
+ }
+ }
+}
/**
* Adds the counter for given entry to another distribution table.
distrib_tbl_t *sum_tbl = (distrib_tbl_t*)env;
stat_add_int_distrib_tbl(sum_tbl, (int)PTR_TO_INT(entry->object), &entry->cnt);
-} /* add_distrib_entry */
+}
/**
* dumps permutation statistics for one and block and one class
/* sum up distribution table for cycles */
stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
- } /* foreach_pset */
+ }
/* print chain distribution for all perms of this class in this block */
fprintf(dmp->f, "chain distribution:\n");
snprintf(buf, sizeof(buf), "length %d", i);
fprintf(dmp->f, "%12s", buf);
stat_insert_int_distrib_tbl(sum_chains, i);
- } /* for */
+ }
fprintf(dmp->f, "\n");
stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
fprintf(dmp->f, "\n");
snprintf(buf, sizeof(buf), "length %d", i);
fprintf(dmp->f, "%12s", buf);
stat_insert_int_distrib_tbl(sum_cycles, i);
- } /* for */
+ }
fprintf(dmp->f, "\n");
stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
fprintf(dmp->f, "\n");
stat_delete_distrib_tbl(sum_chains);
stat_delete_distrib_tbl(sum_cycles);
-} /* simple_dump_be_block_permstat_class */
+}
/**
* dumps statistics about perms
foreach_pset(b_entry->perm_class_stat, perm_class_entry_t, pc_ent) {
fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
simple_dump_be_block_permstat_class(dmp, pc_ent);
- } /* foreach_pset */
- } /* if */
- } /* foreach_pset */
+ }
+ }
+ }
fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
- } /* if */
-} /* simple_dump_be_block_permstat */
+ }
+}
/**
* dumps the number of real_function_call optimization
if (! cnt_eq(cnt, 0)) {
fprintf(dmp->f, "\nReal Function Calls optimized:\n");
fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
- } /* if */
-} /* simple_dump_real_func_calls */
+ }
+}
/**
* dumps the number of tail_recursion optimization
if (num_tail_recursion > 0) {
fprintf(dmp->f, "\nTail recursion optimized:\n");
fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
- } /* if */
-} /* simple_dump_tail_recursion */
+ }
+}
/**
* dumps the edges count
return;
fprintf(dmp->f, "%-16s %8u\n", "Edges", cnt_to_uint(cnt));
-} /* simple_dump_edges */
+}
/**
* dumps the IRG
fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
else
fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
- } /* if */
+ }
fprintf(dmp->f, " %swalked %u over blocks %u:\n"
" was inlined : %u\n"
for (i = 0; i < IF_RESULT_LAST; ++i) {
fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
- } /* for */
+ }
} else {
fprintf(dmp->f, "\nGlobals counts:\n");
fprintf(dmp->f, "--------------\n");
dump_opts = 0;
- } /* if */
+ }
/* address ops */
fprintf(dmp->f,
for (i = 0; i != ARRAY_SIZE(entry->opt_hash); ++i) {
simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
- } /* for */
+ }
/* dump block info */
fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes]),
b_entry->is_start ? "START" : (b_entry->is_end ? "END" : "")
);
- } /* foreach_pset */
+ }
/* dump block reg pressure */
simple_dump_be_block_reg_pressure(dmp, entry);
/* dump block permutation statistics */
simple_dump_be_block_permstat(dmp, entry);
}
-} /* simple_dump_graph */
+}
/**
* dumps the constant table
for (i = 0; i < ARRAY_SIZE(tbl->int_bits_count); ++i) {
fprintf(dmp->f, "%5u %12u\n", (unsigned) (i + 1), cnt_to_uint(&tbl->int_bits_count[i]));
cnt_add(&sum, &tbl->int_bits_count[i]);
- } /* for */
+ }
fprintf(dmp->f, "-------------------------------\n");
fprintf(dmp->f, "\nFloating point constants classification\n");
for (i = 0; i < ARRAY_SIZE(tbl->floats); ++i) {
fprintf(dmp->f, "%-10s %12u\n", stat_fc_name((float_classify_t)i), cnt_to_uint(&tbl->floats[i]));
cnt_add(&sum, &tbl->floats[i]);
- } /* for */
+ }
fprintf(dmp->f, "--------------------------------------\n");
fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
fprintf(dmp->f, "-------------------------------\n");
fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
-} /* simple_dump_const_tbl */
+}
/**
* Dumps a line of the parameter table
fprintf(dmp->f, "%ld : %u\n", (long int)PTR_TO_INT(entry->object),
cnt_to_uint(&entry->cnt));
-} /* dump_tbl_line */
+}
/**
* dumps the parameter distribution table
fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
-} /* simple_dump_param_tbl */
+}
/**
* dumps the optimization counter table
fprintf(dmp->f, "%8u %s\n", cnt, get_opt_name(i));
}
}
-} /* simple_dump_opt_cnt */
+}
/**
* initialize the simple dumper
dmp->f = fopen(fname, "w");
if (! dmp->f) {
perror(fname);
- } /* if */
-} /* simple_init */
+ }
+}
/**
* finishes the simple dumper
if (dmp->f)
fclose(dmp->f);
dmp->f = NULL;
-} /* simple_finish */
+}
/**
* the simple human readable dumper
} else {
/* all other nodes */
cnt_add(&cnt[0], &entry->cnt_alive);
- } /* if */
- } /* foreach_pset */
-} /* csv_count_nodes */
+ }
+ }
+}
/**
* dumps the IRG
name = get_entity_name(entry->ent);
else
name = "<UNKNOWN IRG>";
- } /* if */
+ }
csv_count_nodes(dmp, entry, cnt);
cnt_to_uint(&cnt[2]),
cnt_to_uint(&cnt[3])
);
- } /* if */
-} /* csv_dump_graph */
+ }
+}
/**
* dumps the IRG
(void) dmp;
(void) tbl;
/* FIXME: NYI */
-} /* csv_dump_const_tbl */
+}
/**
* dumps the parameter distribution table
(void) tbl;
(void) global;
/* FIXME: NYI */
-} /* csv_dump_param_tbl */
+}
/**
* dumps the optimization counter
(void) tbl;
(void) len;
/* FIXME: NYI */
-} /* csv_dump_opt_cnt */
+}
/**
* initialize the simple dumper
dmp->f = fopen(fname, "a");
if (! dmp->f)
perror(fname);
-} /* csv_init */
+}
/**
* finishes the simple dumper
if (dmp->f)
fclose(dmp->f);
dmp->f = NULL;
-} /* csv_finish */
+}
/**
* the simple human readable dumper
OutputDebugString(buf);
va_end(ap);
-} /* debug */
+}
/**
* return the size of a firm object
default:
return 0;
}
-} /* get_firm_object_size */
+}
/**
* returns the string length of a string in debuggee space
return i;
}
return i;
-} /* strlen_debuggee */
+}
/**
* Format an ident
_tcsncpy(pResult, (const char *)data->dptr, max);
return S_OK;
-} /* format_ident */
+}
/**
* Format a tp_op
}
#undef X
#undef Y
-} /* format_tp_op */
+}
/**
* Checks whether a type is the global type
*flag = tp.flags & tf_global_type;
return S_OK;
-} /* is_global_type */
+}
/**
* format an entity
_tcsncat(pResult, name, max);
return S_OK;
-} /* format_entity */
+}
/**
* format an ir_mode
if (format_ident(pHelper, mode.name, pResult, max) != S_OK)
return E_FAIL;
return S_OK;
-} /* format_mode */
+}
/**
* format a type
_tcsncat(pResult, name, max);
return S_OK;
-} /* format_type */
+}
/**
* format an irg
}
_tcsncat(pResult, name, max);
return S_OK;
-} /* format_irg */
+}
/**
* format an ir_op
if (format_ident(pHelper, op.name, pResult, max) != S_OK)
return E_FAIL;
return S_OK;
-} /* format_op */
+}
/** get a temporary string */
#define get_string(str) \
}
}
return S_OK;
-} /* format_tarval */
+}
/**
* format an ir_node
_tcsncat(pResult, name, max);
return S_OK;
-} /* format_node */
+}
/**
* format a loop
if (copy_from_debuggee(addr, pHelper, &loop, sizeof(loop)) != S_OK)
return E_FAIL;
return E_FAIL;
-} /* format_loop */
+}
/**
* Get an array descriptor
return E_FAIL;
return S_OK;
-} /* get_array_desc */
+}
/**
* format a ir_prog
_tcsncpy(pResult, name, max);
return S_OK;
-} /* format_prog */
+}
/*
* Format an array descriptor
_tcsncat(pResult, name, max);
return S_OK;
-} /* format_arr_descr */
+}
/*
* format a firm object
default:
return E_FAIL;
}
-} /* FormatFirmObject */
+}
#define SEGMENT_SIZE_SHIFT 8
#define SEGMENT_SIZE (1 << SEGMENT_SIZE_SHIFT)
*lenght = max_len;
*size = dyns;
return S_OK;
-} /* find_longest_pset_chain */
+}
/**
* Find the longest chain of a set
*lenght = max_len;
*size = dyns;
return S_OK;
-} /* find_longest_set_chain */
+}
/*
* Format a pset
_tcsncpy(pResult, name, max);
return S_OK;
-} /* format_pset */
+}
/*
* Format a set
_tcsncpy(pResult, name, max);
return S_OK;
-} /* format_set */
+}
struct pdeq {
unsigned magic; /**< debug magic, only available in DEBUG builds */
};
return n;
-} /* get_pdeq_len */
+}
/*
* Format a pdeq
_tcsncpy(pResult, name, max);
return S_OK;
-} /* format_pdeq */
+}
/** show the first 2 units */
static HRESULT fill_bits(DEBUGHELPER *pHelper, bitset_t *bs, char *pResult)
}
sprintf(pResult + l, "}");
return S_OK;
-} /* fill_bits */
+}
/*
* Format a bitset
_tcsncpy(pResult, name, max);
return S_OK;
-} /* format_bitset */
+}