/*
- * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
#include "irbackedge_t.h"
#include "cgana.h"
#include "trouts.h"
-
+#include "error.h"
#include "irflag_t.h"
#include "irhooks.h"
/* Applies local optimizations to all nodes in the graph until fixpoint. */
void optimize_graph_df(ir_graph *irg) {
pdeq *waitq = new_pdeq();
- int state = edges_activated(irg);
ir_graph *rem = current_ir_graph;
ir_node *end;
- int i;
+ int i, state;
current_ir_graph = irg;
- if (! state)
- edges_activate(irg);
+ state = edges_assure(irg);
if (get_opt_global_cse())
set_irg_pinned(current_ir_graph, op_pin_state_floats);
ir_node *nn, *block;
int new_arity;
ir_op *op = get_irn_op(n);
+ (void) env;
/* The end node looses it's flexible in array. This doesn't matter,
as dead node elimination builds End by hand, inlineing doesn't use
get_irn_mode(n),
new_arity,
get_irn_in(n) + 1);
- /* Copy the attributes. These might point to additional data. If this
- was allocated on the old obstack the pointers now are dangling. This
- frees e.g. the memory of the graph_arr allocated in new_immBlock. */
+ /* Copy the attributes. These might point to additional data. If this
+ was allocated on the old obstack the pointers now are dangling. This
+ frees e.g. the memory of the graph_arr allocated in new_immBlock. */
+ if (op == op_Block) {
+ /* we cannot allow blocks WITHOUT macroblock input */
+ set_irn_n(nn, -1, get_irn_n(n, -1));
+ }
copy_node_attr(n, nn);
#ifdef DEBUG_libfirm
set_irn_n(nn, -1, nn);
} else {
/* get the macro block header */
- set_irn_n(nn, -1, get_new_node(mbh));
+ ir_node *nmbh = get_new_node(mbh);
+ assert(nmbh != NULL);
+ set_irn_n(nn, -1, nmbh);
}
/* Don't copy Bad nodes. */
* Adds all new nodes to a new hash table for CSE. Does not
* perform CSE, so the hash table might contain common subexpressions.
*/
-void
-dead_node_elimination(ir_graph *irg) {
- if (get_opt_optimize() && get_opt_dead_node_elimination()) {
- ir_graph *rem;
+void dead_node_elimination(ir_graph *irg) {
+ ir_graph *rem;
#ifdef INTERPROCEDURAL_VIEW
- int rem_ipview = get_interprocedural_view();
+ int rem_ipview = get_interprocedural_view();
#endif
- struct obstack *graveyard_obst = NULL;
- struct obstack *rebirth_obst = NULL;
- assert(! edges_activated(irg) && "dead node elimination requires disabled edges");
+ struct obstack *graveyard_obst = NULL;
+ struct obstack *rebirth_obst = NULL;
+ assert(! edges_activated(irg) && "dead node elimination requires disabled edges");
- /* inform statistics that we started a dead-node elimination run */
- hook_dead_node_elim(irg, 1);
+ /* inform statistics that we started a dead-node elimination run */
+ hook_dead_node_elim(irg, 1);
- /* Remember external state of current_ir_graph. */
- rem = current_ir_graph;
- current_ir_graph = irg;
+ /* Remember external state of current_ir_graph. */
+ rem = current_ir_graph;
+ current_ir_graph = irg;
#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(0);
+ set_interprocedural_view(0);
#endif
- assert(get_irg_phase_state(irg) != phase_building);
+ assert(get_irg_phase_state(irg) != phase_building);
- /* Handle graph state */
- free_callee_info(irg);
- free_irg_outs(irg);
- free_trouts();
+ /* Handle graph state */
+ free_callee_info(irg);
+ free_irg_outs(irg);
+ free_trouts();
- /* @@@ so far we loose loops when copying */
- free_loop_information(irg);
+ /* @@@ so far we loose loops when copying */
+ free_loop_information(irg);
- set_irg_doms_inconsistent(irg);
+ set_irg_doms_inconsistent(irg);
- /* A quiet place, where the old obstack can rest in peace,
- until it will be cremated. */
- graveyard_obst = irg->obst;
+ /* A quiet place, where the old obstack can rest in peace,
+ until it will be cremated. */
+ graveyard_obst = irg->obst;
- /* A new obstack, where the reachable nodes will be copied to. */
- rebirth_obst = xmalloc(sizeof(*rebirth_obst));
- irg->obst = rebirth_obst;
- obstack_init(irg->obst);
- irg->last_node_idx = 0;
+ /* A new obstack, where the reachable nodes will be copied to. */
+ rebirth_obst = xmalloc(sizeof(*rebirth_obst));
+ irg->obst = rebirth_obst;
+ obstack_init(irg->obst);
+ irg->last_node_idx = 0;
- /* We also need a new value table for CSE */
- del_identities(irg->value_table);
- irg->value_table = new_identities();
+ /* We also need a new value table for CSE */
+ del_identities(irg->value_table);
+ irg->value_table = new_identities();
- /* Copy the graph from the old to the new obstack */
- copy_graph_env(/*copy_node_nr=*/1);
+ /* Copy the graph from the old to the new obstack */
+ copy_graph_env(/*copy_node_nr=*/1);
- /* Free memory from old unoptimized obstack */
- obstack_free(graveyard_obst, 0); /* First empty the obstack ... */
- xfree(graveyard_obst); /* ... then free it. */
+ /* Free memory from old unoptimized obstack */
+ obstack_free(graveyard_obst, 0); /* First empty the obstack ... */
+ xfree(graveyard_obst); /* ... then free it. */
- /* inform statistics that the run is over */
- hook_dead_node_elim(irg, 0);
+ /* inform statistics that the run is over */
+ hook_dead_node_elim(irg, 0);
- current_ir_graph = rem;
+ current_ir_graph = rem;
#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(rem_ipview);
+ set_interprocedural_view(rem_ipview);
#endif
- }
}
/**
* changes).
*/
void remove_bad_predecessors(ir_graph *irg) {
+ panic("Fix backedge handling first");
irg_walk_graph(irg, firm_clear_link, relink_bad_predecessors, NULL);
}
ir_type *called_frame;
irg_inline_property prop = get_irg_inline_property(called_graph);
- if ( (prop < irg_inline_forced) &&
- (!get_opt_optimize() || !get_opt_inline() || (prop == irg_inline_forbidden))) return 0;
+ if ( (prop < irg_inline_forced) || (prop == irg_inline_forbidden))
+ return 0;
/* Do not inline variadic functions. */
if (get_method_variadicity(get_entity_type(get_irg_entity(called_graph))) == variadicity_variadic)
ir_graph *called_irg = NULL;
addr = get_Call_ptr(call);
- if (is_SymConst(addr) && get_SymConst_kind(addr) == symconst_addr_ent) {
+ if (is_SymConst_addr_ent(addr)) {
called_irg = get_entity_irg(get_SymConst_entity(addr));
}
call_entry *entry;
DEBUG_ONLY(firm_dbg_module_t *dbg;)
- if (!(get_opt_optimize() && get_opt_inline())) return;
-
FIRM_DBG_REGISTER(dbg, "firm.opt.inline");
current_ir_graph = irg;
struct obstack obst;
DEBUG_ONLY(firm_dbg_module_t *dbg;)
- if (!(get_opt_optimize() && get_opt_inline())) return;
-
FIRM_DBG_REGISTER(dbg, "firm.opt.inline");
rem = current_ir_graph;
obstack_init(&obst);
optimize_graph_df(irg);
optimize_cf(irg);
}
- if (env->got_inline || (env->n_callers_orig != env->n_callers))
+ if (env->got_inline || (env->n_callers_orig != env->n_callers)) {
DB((dbg, SET_LEVEL_1, "Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
env->n_callers_orig, env->n_callers,
get_entity_name(get_irg_entity(irg))));
+ }
}
obstack_free(&obst, NULL);
}
typedef struct cf_env {
- char changed; /**< flag indicates that the cf graphs has changed. */
+ char ignore_exc_edges; /**< set if exception edges should be ignored. */
+ char changed; /**< flag indicates that the cf graphs has changed. */
} cf_env;
/**
const ir_op *cfop;
pre = get_irn_n(n, i);
- cfop = get_irn_op(skip_Proj(pre));
+ /* don't count Bad's */
+ if (is_Bad(pre))
+ continue;
+ cfop = get_irn_op(skip_Proj(pre));
if (is_op_fragile(cfop)) {
- if (cfop != op_Raise)
- goto insert;
- continue;
+ if (cenv->ignore_exc_edges && get_Proj_proj(pre) == pn_Generic_X_except)
+ continue;
+ goto insert;
}
- if (is_op_forking(cfop)) {
+ /* we don't want place nodes in the start block, so handle it like forking */
+ if (is_op_forking(cfop) || cfop == op_Start) {
/* Predecessor has multiple successors. Insert new control flow edge edges. */
insert:
/* set predecessor of new block */
void remove_critical_cf_edges(ir_graph *irg) {
cf_env env;
- env.changed = 0;
+ env.ignore_exc_edges = 1;
+ env.changed = 0;
irg_block_walk_graph(irg, NULL, walk_critical_cf_edges, &env);
if (env.changed) {