/*
- * 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);
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. */
}
ARR_SETLEN(ir_node *, n->in, new_irn_arity);
- ARR_SETLEN(int, n->attr.phi_backedge, new_irn_arity);
+ ARR_SETLEN(int, n->attr.phi.u.backedge, new_irn_arity);
}
} /* n is a Phi node */
}
* 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_node **res_pred;
ir_node **cf_pred;
ir_node *ret, *phi;
- int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
+ int arity, n_ret, n_exc, n_res, i, n, j, rem_opt, irn_arity;
enum exc_mode exc_handling;
ir_type *called_frame;
irg_inline_property prop = get_irg_inline_property(called_graph);
- if ( (prop < irg_inline_forced) || (prop == irg_inline_forbidden))
+ if (prop == irg_inline_forbidden)
return 0;
/* Do not inline variadic functions. */
/* -- Replicate local entities of the called_graph -- */
/* copy the entities. */
called_frame = get_irg_frame_type(called_graph);
- for (i = 0; i < get_class_n_members(called_frame); i++) {
+ for (i = 0, n = get_class_n_members(called_frame); i < n; ++i) {
ir_entity *new_ent, *old_ent;
old_ent = get_class_member(called_frame, i);
new_ent = copy_entity_own(old_ent, get_cur_frame_type());
res_pred[j] = phi;
/* Conserve Phi-list for further inlinings -- but might be optimized */
if (get_nodes_block(phi) == post_bl) {
- set_irn_link(phi, get_irn_link(post_bl));
- set_irn_link(post_bl, phi);
+ set_Phi_next(phi, get_Block_phis(post_bl));
+ set_Block_phis(post_bl, phi);
}
}
set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
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->call;
callee = entry->callee;
- if (is_leave(callee) && is_smaller(callee, leavesize)) {
+ if (is_leave(callee) && (
+ is_smaller(callee, leavesize) || (get_irg_inline_property(callee) >= irg_inline_forced))) {
if (!phiproj_computed) {
phiproj_computed = 1;
collect_phiprojs(current_ir_graph);
did_inline = inline_method(call, callee);
if (did_inline) {
- /* Do some statistics */
inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
+ /* Do some statistics */
env->got_inline = 1;
--env->n_call_nodes;
env->n_nodes += callee_env->n_nodes;
}
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;
}
/* we don't want place nodes in the start block, so handle it like forking */
if (is_op_forking(cfop) || cfop == op_Start) {
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) {