/*
- * Project: libFIRM
- * File name: ir/ana/height.c
- * Purpose: Compute heights of nodes inside basic blocks
- * Author: Sebastian Hack
- * Modified by:
- * Created: 19.04.2006
- * CVS-ID: $Id$
- * Copyright: (c) 2006 Universität Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+/**
+ * @file
+ * @brief Compute heights of nodes inside basic blocks
+ * @author Sebastian Hack
+ * @date 19.04.2006
+ * @version $Id$
+ */
+#include "config.h"
+
+#include "height.h"
#include <stdlib.h>
#include <stdio.h>
#include "list.h"
-
#include "irdump.h"
#include "irgwalk.h"
#include "irtools.h"
#include "irphase_t.h"
#include "iredges_t.h"
-typedef struct _heights_t heights_t;
-
struct _heights_t {
- phase_t ph;
+ ir_phase ph;
unsigned visited;
void *dump_handle;
};
unsigned visited;
} irn_height_t;
-static void *irn_height_init(phase_t *ph, ir_node *irn, void *data)
+static void *irn_height_init(ir_phase *ph, const ir_node *irn, void *data)
{
irn_height_t *h = data ? data : phase_alloc(ph, sizeof(h[0]));
+ (void)irn;
memset(h, 0, sizeof(h[0]));
return h;
}
heights_t *heights = data;
irn_height_t *h = phase_get_irn_data(&heights->ph, irn);
- if(h)
+ if (h)
fprintf(f, "height: %u\n", h->height);
}
int i, n;
/* if the current node is the one we were looking for, we're done. */
- if(curr == tgt)
+ if (curr == tgt)
return 1;
- /* If we are in another block we won't find our target. */
- if(get_nodes_block(curr) != get_nodes_block(tgt))
+ /* If we are in another block or at a phi we won't find our target. */
+ if (get_nodes_block(curr) != get_nodes_block(tgt))
+ return 0;
+ if (is_Phi(curr))
return 0;
/* Check, if we have already been here. Coming more often won't help :-) */
h_curr = phase_get_irn_data(&h->ph, curr);
- if(h_curr->visited >= h->visited)
+ if (h_curr->visited >= h->visited)
return 0;
/* If we are too deep into the DAG we won't find the target either. */
h_tgt = phase_get_irn_data(&h->ph, tgt);
- if(h_curr->height > h_tgt->height)
+ if (h_curr->height > h_tgt->height)
return 0;
/* Mark this place as visited. */
h_curr->visited = h->visited;
/* Start a search from this node. */
- for(i = 0, n = get_irn_ins_or_deps(curr); i < n; ++i) {
+ for (i = 0, n = get_irn_ins_or_deps(curr); i < n; ++i) {
ir_node *op = get_irn_in_or_dep(curr, i);
- if(search(h, op, tgt))
+ if (search(h, op, tgt))
return 1;
}
assert(get_nodes_block(n) == get_nodes_block(m));
assert(hn != NULL && hm != NULL);
- if(hn->height <= hm->height) {
+ if (hn->height <= hm->height) {
h->visited++;
res = search(h, n, m);
}
const ir_edge_t *edge;
/* bail out if we already visited that node. */
- if(ih->visited >= h->visited)
+ if (ih->visited >= h->visited)
return ih->height;
ih->visited = h->visited;
foreach_out_edge(irn, edge) {
ir_node *dep = get_edge_src_irn(edge);
- if(!is_Block(dep) && get_nodes_block(dep) == bl) {
+ if (!is_Block(dep) && !is_Phi(dep) && get_nodes_block(dep) == bl) {
unsigned dep_height = compute_height(h, dep, bl);
ih->height = MAX(ih->height, dep_height);
}
foreach_out_edge_kind(irn, edge, EDGE_KIND_DEP) {
ir_node *dep = get_edge_src_irn(edge);
- if(!is_Block(dep) && get_nodes_block(dep) == bl) {
+ assert(!is_Phi(dep));
+ if (!is_Block(dep) && get_nodes_block(dep) == bl) {
unsigned dep_height = compute_height(h, dep, bl);
ih->height = MAX(ih->height, dep_height);
}
heights_t *heights_new(ir_graph *irg)
{
- heights_t *res = xmalloc(sizeof(res[0]));
- phase_init(&res->ph, "heights", irg, PHASE_DEFAULT_GROWTH, irn_height_init);
+ heights_t *res = XMALLOC(heights_t);
+ phase_init(&res->ph, irg, irn_height_init);
res->dump_handle = dump_add_node_info_callback(height_dump_cb, res);
heights_recompute(res);
void heights_free(heights_t *h)
{
- phase_free(&h->ph);
+ phase_deinit(&h->ph);
dump_remv_node_info_callback(h->dump_handle);
xfree(h);
}