From 53bb233f7386bdf8009214518b3186ee247da956 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=B6tz=20Lindenmaier?= Date: Thu, 12 Sep 2002 13:12:50 +0000 Subject: [PATCH] Bugfix in inlineing: moved Phi nodes into wrong block as no check for optimized nodes. [r477] --- ir/ir/irdump.c | 22 ++++++++++++++-------- ir/ir/irgmod.c | 5 ++++- ir/ir/irgopt.c | 37 ++++++++++++++++++++----------------- ir/ir/iropt.c | 2 ++ 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index dc6b74961..4a3bbf3f6 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -250,6 +250,13 @@ bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) { } +static INLINE +bool is_constlike_node(ir_node *n) { + ir_op *op = get_irn_op(n); + return (op == op_Const || op == op_Bad || op == op_SymConst); +} + + void dump_const_node_local(ir_node *n, pmap *irgmap) { int i; if (!dump_const_local_set()) return; @@ -257,14 +264,14 @@ void dump_const_node_local(ir_node *n, pmap *irgmap) { initialize it first. */ for (i = 0; i < get_irn_arity(n); i++) { ir_node *con = get_irn_n(n, i); - if (get_irn_op(con) == op_Const) { + if (is_constlike_node(con)) { if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */ set_irn_visited(con, get_irg_visited(current_ir_graph)-1); } } for (i = 0; i < get_irn_arity(n); i++) { ir_node *con = get_irn_n(n, i); - if ((get_irn_op(con) == op_Const) && irn_not_visited(con)) { + if (is_constlike_node(con) && irn_not_visited(con)) { if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */ mark_irn_visited(con); /* Generate a new name for the node by appending the names of @@ -287,7 +294,7 @@ void dump_const_node_local(ir_node *n, pmap *irgmap) { void dump_node (ir_node *n, pmap * map) { - if (dump_const_local_set() && (get_irn_op(n) == op_Const)) return; + if (dump_const_local_set() && is_constlike_node(n)) return; /* dump this node */ xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \""); @@ -502,7 +509,7 @@ dump_ir_node (ir_node *n) /* dump the edge to the block this node belongs to */ void dump_ir_block_edge(ir_node *n) { - if (dump_const_local_set() && (get_irn_op(n) == op_Const)) return; + if (dump_const_local_set() && is_constlike_node(n)) return; if (is_no_Block(n)) { xfprintf (F, "edge: { sourcename: \""); PRINT_NODEID(n); @@ -617,7 +624,7 @@ dump_ir_data_edges(ir_node *n) { fprintf (F, "edge: {sourcename: \""); PRINT_NODEID(n); fprintf (F, "\" targetname: \""); - if ((dump_const_local_set()) && (get_irn_op(pred) == op_Const)) + if ((dump_const_local_set()) && is_constlike_node(pred)) PRINT_NODEID(n); PRINT_NODEID(pred); fprintf (F, "\""); @@ -1149,6 +1156,7 @@ dump_ir_block (ir_node *block, void *env) { /* Close the vcg information for the block */ xfprintf(F, "}\n\n"); + dump_const_node_local(block, NULL); } } @@ -1194,9 +1202,7 @@ dump_ir_block_graph (ir_graph *irg) dump_ir_block_graph_2 (irg); - if (dump_loop_information_flag) { - dump_loop_info(irg); - } + if (dump_loop_information_flag) dump_loop_info(irg); vcg_close(); current_ir_graph = rem; diff --git a/ir/ir/irgmod.c b/ir/ir/irgmod.c index e6fdbb7e3..d19b21a6e 100644 --- a/ir/ir/irgmod.c +++ b/ir/ir/irgmod.c @@ -156,7 +156,10 @@ void part_block(ir_node *node) { set_irn_link(new_block, phi); set_irn_link(old_block, NULL); while (phi) { - set_nodes_Block(phi, new_block); + if(get_nodes_Block(phi) == old_block); /* @@@ inlinening chokes on phis that don't + obey this condition. How do they get into + the list??? Example: InterfaceIII */ + set_nodes_Block(phi, new_block); phi = get_irn_link(phi); } diff --git a/ir/ir/irgopt.c b/ir/ir/irgopt.c index c7a3cc9a0..cac152779 100644 --- a/ir/ir/irgopt.c +++ b/ir/ir/irgopt.c @@ -459,11 +459,10 @@ void inline_method(ir_node *call, ir_graph *called_graph) { /** Check preconditions **/ assert(get_irn_op(call) == op_Call); - /* assert(get_Call_type(call) == get_entity_type(get_irg_ent(called_graph))); */ - /* - @@@ TODO does not work for InterfaceIII.java after cgana - assert(smaller_type(get_entity_type(get_irg_ent(called_graph)), - get_Call_type(call))); + /* @@@ TODO does not work for InterfaceIII.java after cgana + assert(get_Call_type(call) == get_entity_type(get_irg_ent(called_graph))); + assert(smaller_type(get_entity_type(get_irg_ent(called_graph)), + get_Call_type(call))); */ assert(get_type_tpop(get_Call_type(call)) == type_method); if (called_graph == current_ir_graph) return; @@ -493,7 +492,7 @@ void inline_method(ir_node *call, ir_graph *called_graph) { /* Visited flags in calling irg must be >= flag in called irg. Else walker and arity computation will not work. */ if (get_irg_visited(current_ir_graph) <= get_irg_visited(called_graph)) - set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1); /***/ + set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1); if (get_irg_block_visited(current_ir_graph)< get_irg_block_visited(called_graph)) set_irg_block_visited(current_ir_graph, get_irg_block_visited(called_graph)); /* Set pre_call as new Start node in link field of the start node of @@ -503,11 +502,11 @@ void inline_method(ir_node *call, ir_graph *called_graph) { copying. */ set_irn_link(get_irg_start(called_graph), pre_call); set_irn_visited(get_irg_start(called_graph), - get_irg_visited(current_ir_graph));/***/ + get_irg_visited(current_ir_graph)); set_irn_link(get_irg_start_block(called_graph), - get_nodes_Block(pre_call)); + get_nodes_Block(pre_call)); set_irn_visited(get_irg_start_block(called_graph), - get_irg_visited(current_ir_graph)); /***/ + get_irg_visited(current_ir_graph)); /* Initialize for compaction of in arrays */ inc_irg_block_visited(current_ir_graph); @@ -530,7 +529,7 @@ void inline_method(ir_node *call, ir_graph *called_graph) { /** Performing dead node elimination inlines the graph **/ /* Copies the nodes to the obstack of current_ir_graph. Updates links to new entities. */ - /* @@@ endless loops are not copied!! */ + /* @@@ endless loops are not copied!! -- they should be, I think... */ irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds, get_irg_frame_type(called_graph)); @@ -594,8 +593,11 @@ void inline_method(ir_node *call, ir_graph *called_graph) { } phi = new_Phi(n_ret, cf_pred, mode_M); set_Tuple_pred(call, 0, phi); - set_irn_link(phi, get_irn_link(post_bl)); /* Conserve Phi-list for further inlinings */ - set_irn_link(post_bl, 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); + } /* Now the real results */ if (n_res > 0) { for (j = 0; j < n_res; j++) { @@ -609,8 +611,11 @@ void inline_method(ir_node *call, ir_graph *called_graph) { } phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0])); res_pred[j] = phi; - set_irn_link(phi, get_irn_link(post_bl)); /* Conserve Phi-list for further inlinings */ - set_irn_link(post_bl, 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_Tuple_pred(call, 2, new_Tuple(n_res, res_pred)); } else { @@ -729,7 +734,6 @@ static void collect_calls(ir_node *call, void *env) { } } - /* Inlines all small methods at call sites where the called address comes from a Const node that references the entity representing the called method. @@ -743,8 +747,6 @@ void inline_small_irgs(ir_graph *irg, int size) { if (!(get_optimize() && get_opt_inline())) return; - //DDME(get_irg_ent(current_ir_graph)); - current_ir_graph = irg; /* Handle graph state */ assert(get_irg_phase_state(current_ir_graph) != phase_building); @@ -761,6 +763,7 @@ void inline_small_irgs(ir_graph *irg, int size) { /* There are calls to inline */ collect_phiprojs(irg); for (i = 0; i < pos; i++) { + char buf[1024]; tarval *tv; ir_graph *callee; tv = get_Const_tarval(get_Call_ptr(calls[i])); diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index e2ed9e229..8150b4496 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -451,6 +451,8 @@ equivalent_node (ir_node *n) n_preds = get_Phi_n_preds(n); block = get_nodes_Block(n); + /* @@@ fliegt 'raus, sollte aber doch immer wahr sein!!! + assert(get_irn_arity(block) == n_preds && "phi in wrong block!"); */ if ((is_Bad(block)) || /* Control dead */ (block == current_ir_graph->start_block)) /* There should be no Phi nodes */ return new_Bad(); /* in the Start Block. */ -- 2.20.1