#include "iroptimize.h"
#include "adt/pdeq.h"
#include "irnode_t.h"
-#include "irouts.h"
+#include "iredges_t.h"
#include "irgopt.h"
#include "irpass.h"
return get_Block_dom_depth(block) >= 0;
}
+/**
+ * Firm keepalive edges are broken (the user should really be the endless loop
+ * and not the End node.) This wrong place of the user will lead to wrong
+ * results in place_early()/place_late(). We work around these problems by not
+ * moving nodes which just have keepalive edges as their users (or no users at
+ * all)
+ */
+static bool float_exceptions(const ir_node *node)
+{
+ foreach_out_edge(node, edge) {
+ ir_node *succ = get_edge_src_irn(edge);
+ if (is_End(succ))
+ continue;
+ /* found a real user */
+ return false;
+ }
+ return true;
+}
+
/**
* Find the earliest correct block for node n. --- Place n into the
* same Block as its dominance-deepest Input.
* This works because in firm each cycle contains a Phi or Block node
* (which are pinned)
*/
- if (get_irn_pinned(n) != op_pin_state_floats) {
+ if (get_irn_pinned(n) != op_pin_state_floats || float_exceptions(n)) {
/* we can't move pinned nodes */
arity = get_irn_arity(n);
for (i = 0; i < arity; ++i) {
start_block = get_irg_start_block(irg);
if (new_block == start_block && block != start_block &&
get_irg_phase_state(irg) != phase_backend) {
- assert(get_Block_n_cfg_outs(start_block) == 1);
- new_block = get_Block_cfg_out(start_block, 0);
+ assert(get_irn_n_edges_kind(start_block, EDGE_KIND_BLOCK) == 1);
+ const ir_edge_t *edge = get_block_succ_first(start_block);
+ new_block = get_edge_src_irn(edge);
}
/* Set the new block */
*/
static ir_node *get_deepest_common_dom_ancestor(ir_node *node, ir_node *dca)
{
- for (unsigned i = get_irn_n_outs(node); i-- > 0; ) {
- ir_node *succ = get_irn_out(node, i);
+ foreach_out_edge(node, edge) {
+ ir_node *succ = get_edge_src_irn(edge);
/* keepalive edges are special and don't respect the dominance */
if (is_End(succ))
dca = consumer_dom_dca(dca, succ, node);
}
}
+ foreach_out_edge_kind(node, edge, EDGE_KIND_DEP) {
+ ir_node *succ = get_edge_src_irn(edge);
+ assert(is_block_reachable(get_nodes_block(succ)));
+ dca = consumer_dom_dca(dca, succ, node);
+ }
return dca;
}
*/
static void set_projs_block(ir_node *node, ir_node *block)
{
- for (unsigned i = get_irn_n_outs(node); i-- > 0; ) {
- ir_node *succ = get_irn_out(node, i);
+ foreach_out_edge(node, edge) {
+ ir_node *succ = get_edge_src_irn(edge);
- assert(is_Proj(succ));
+ if (!is_Proj(succ))
+ continue;
+ set_nodes_block(succ, block);
if (get_irn_mode(succ) == mode_T) {
set_projs_block(succ, block);
}
- set_nodes_block(succ, block);
}
}
if (irn_visited_else_mark(n))
return;
- unsigned n_outs = get_irn_n_outs(n);
/* break cycles at pinned nodes (see place place_floats_early) as to why */
if (get_irn_pinned(n) != op_pin_state_floats) {
- for (unsigned i = 0; i < n_outs; ++i) {
- ir_node *succ = get_irn_out(n, i);
+ foreach_out_edge(n, edge) {
+ ir_node *succ = get_edge_src_irn(edge);
pdeq_putr(worklist, succ);
}
return;
}
/* place our users */
- for (unsigned i = 0; i < n_outs; ++i) {
- ir_node *succ = get_irn_out(n, i);
+ foreach_out_edge(n, edge) {
+ ir_node *succ = get_edge_src_irn(edge);
place_floats_late(succ, worklist);
}
assure_irg_properties(irg,
IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES |
IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE |
- IR_GRAPH_PROPERTY_CONSISTENT_OUTS |
+ IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES |
IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE |
IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
place_late(irg, worklist);
del_waitq(worklist);
- confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_NONE);
+ confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW);
}
/**