/*
- * Project: libFIRM
- * File name: ir/ana/irscc.c
- * Purpose: Compute the strongly connected regions and build
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Compute the strongly connected regions and build
* backedge/loop datastructures.
* A variation on the Tarjan algorithm. See also [Trapp:99],
* Chapter 5.2.1.2.
- * Author: Goetz Lindenmaier
- * Modified by:
- * Created: 7.2002
- * CVS-ID: $Id$
- * Copyright: (c) 2002-2003 Universität Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ * @author Goetz Lindenmaier
+ * @date 7.2002
+ * @version $Id$
*/
-
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
}
/* Uses temporary information to get the loop */
-ir_loop *
-get_irn_loop (ir_node *n) {
- return n->loop;
+ir_loop *(get_irn_loop)(const ir_node *n) {
+ return _get_irn_loop(n);
}
static INLINE void
push (ir_node *n)
{
- /*DDMN(n);*/
-
if (tos == ARR_LEN (stack)) {
int nlen = ARR_LEN (stack) * 2;
ARR_RESIZE (ir_node *, stack, nlen);
do {
m = pop();
- //printf(" dfn: %d, upl %d upl-new %d ", get_irn_dfn(m), get_irn_uplink(m), loop_node_cnt+1); DDMN(m);
-
loop_node_cnt++;
set_irn_dfn(m, loop_node_cnt);
add_loop_node(current_loop, m);
#endif
/* Returns outer loop, itself if outermost. */
-ir_loop *get_loop_outer_loop (ir_loop *loop) {
- assert(loop && loop->kind == k_ir_loop);
- return loop->outer_loop;
+ir_loop *(get_loop_outer_loop)(const ir_loop *loop) {
+ return _get_loop_outer_loop(loop);
}
/* Returns nesting depth of this loop */
-int get_loop_depth (ir_loop *loop) {
- assert(loop); assert(loop->kind == k_ir_loop);
- return loop->depth;
+int (get_loop_depth)(const ir_loop *loop) {
+ return _get_loop_depth(loop);
}
/* Returns the number of inner loops */
-int get_loop_n_sons (ir_loop *loop) {
- assert(loop && loop->kind == k_ir_loop);
- return(loop -> n_sons);
+int (get_loop_n_sons)(const ir_loop *loop) {
+ return _get_loop_n_sons(loop);
}
/* Returns the pos`th loop_node-child *
if(node_nr == pos)
return(loop -> children[child_nr].node);
}
- DDML(loop);
- printf("pos: %d\n", pos);
+
assert(0 && "no child at pos found");
return NULL;
}
loop->n_nodes++;
}
-/** Returns the number of elements contained in loop. */
-int get_loop_n_elements (ir_loop *loop) {
+/* Returns the number of elements contained in loop. */
+int get_loop_n_elements (const ir_loop *loop) {
assert(loop && loop->kind == k_ir_loop);
return(ARR_LEN(loop->children));
}
and then select the appropriate "loop_element.node" or "loop_element.son".
*/
-loop_element get_loop_element (ir_loop *loop, int pos) {
+loop_element get_loop_element(const ir_loop *loop, int pos) {
assert(loop && loop->kind == k_ir_loop && pos < ARR_LEN(loop->children));
-
return(loop -> children[pos]);
}
-int get_loop_element_pos(ir_loop *loop, void *le) {
- int i;
+int get_loop_element_pos(const ir_loop *loop, void *le) {
+ int i, n;
assert(loop && loop->kind == k_ir_loop);
- for (i = 0; i < get_loop_n_elements(loop); i++)
+ n = get_loop_n_elements(loop);
+ for (i = 0; i < n; i++)
if (get_loop_element(loop, i).node == le) return i;
return -1;
}
-int get_loop_loop_nr(ir_loop *loop) {
+int get_loop_loop_nr(const ir_loop *loop) {
assert(loop && loop->kind == k_ir_loop);
#ifdef DEBUG_libfirm
return loop->loop_nr;
if libfirm_debug is set. */
void set_loop_link (ir_loop *loop, void *link) {
assert(loop && loop->kind == k_ir_loop);
-#ifdef DEBUG_libfirm
loop->link = link;
-#endif
}
void *get_loop_link (const ir_loop *loop) {
assert(loop && loop->kind == k_ir_loop);
-#ifdef DEBUG_libfirm
return loop->link;
-#else
- return NULL;
-#endif
}
int (is_ir_loop)(const void *thing) {
static INLINE void
init_node (ir_node *n, void *env) {
+ (void) env;
set_irn_link (n, new_scc_info());
clear_backedges(n);
}
*/
}
+#ifdef INTERPROCEDURAL_VIEW
static INLINE void
init_ip_scc (void) {
init_scc_common();
cg_walk (link_to_reg_end, NULL, NULL);
#endif
}
+#endif
/* Condition for breaking the recursion. */
static int is_outermost_Start(ir_node *n) {
#endif
}
-
-#if 0
-static void test(ir_node *pred, ir_node *root, ir_node *this) {
- int i;
- if (get_irn_uplink(pred) >= get_irn_uplink(root)) return;
-
- printf("this: %d ", get_irn_uplink(this)); DDMN(this);
- printf("pred: %d ", get_irn_uplink(pred)); DDMN(pred);
- printf("root: %d ", get_irn_uplink(root)); DDMN(root);
-
- printf("tos: %d\n", tos);
-
- for (i = tos; i >= 0; i--) {
- ir_node *n = stack[i];
- if (!n) continue;
- printf(" uplink: %d, pos: %d ", get_irn_uplink(n), i); DDMN(n);
- }
-}
-#endif
-
/* Test for legal loop header: Block, Phi, ... */
static INLINE int is_possible_loop_head(ir_node *n) {
ir_op *op = get_irn_op(n);
some_outof_loop = 1;
} else {
if(get_irn_uplink(pred) < get_irn_uplink(root)) {
- DDMN(n); DDMN(pred); DDMN(root);
assert(get_irn_uplink(pred) >= get_irn_uplink(root));
}
some_in_loop = 1;
some_outof_loop = 1; //printf(" some out of loop ");
} else {
if(get_irn_uplink(pred) < get_irn_uplink(root)) {
- DDMN(pred); DDMN(root);
assert(get_irn_uplink(pred) >= get_irn_uplink(root));
}
some_in_loop = 1;
assert(is_Block(start_block));
for(i = tos - 1; i >= 0; --i)
{
- DDMN(stack[i]);
if(get_irn_op(stack[i]) == op_Proj && get_irn_mode(stack[i]) == mode_X &&
get_irn_op(get_irn_n(stack[i], 0)) == op_EndReg)
{
{
ir_node *begin_projx = get_Block_cfgpred(get_irg_start_block(get_irn_irg(end_projx)),
get_Proj_proj(end_projx));
- DDMN(begin_projx);
if(get_irn_n(start_block, j) == begin_projx)
{
printf("FOUND IT!!!!!!!!!!!!!!!!!!\n");
ir_node *end_projx = n;
ir_node *begin_projx = get_Block_cfgpred(get_irg_start_block(get_irn_irg(end_projx)),
get_Proj_proj(end_projx));
- printf("Linked the following ProjxNodes:\n");
- DDMN(begin_projx);
- DDMN(end_projx);
set_projx_link(begin_projx, end_projx);
}
}
}
+#ifdef INTERPROCEDURAL_VIEW
int construct_ip_backedges (void) {
ir_graph *rem = current_ir_graph;
int rem_ipv = get_interprocedural_view();
current_ir_graph = rem;
set_interprocedural_view(rem_ipv);
}
+#endif
static void reset_backedges(ir_node *n) {
if (is_possible_loop_head(n)) {
+#ifdef INTERPROCEDURAL_VIEW
int rem = get_interprocedural_view();
set_interprocedural_view(1);
set_interprocedural_view(1);
clear_backedges(n);
set_interprocedural_view(rem);
+#else
+ clear_backedges(n);
+#endif
}
}
*/
static void loop_reset_node(ir_node *n, void *env) {
+ (void) env;
set_irn_loop(n, NULL);
reset_backedges(n);
}
void free_all_loop_information (void) {
int i;
+#ifdef INTERPROCEDURAL_VIEW
int rem = get_interprocedural_view();
set_interprocedural_view(1); /* To visit all filter nodes */
+#endif
for (i = 0; i < get_irp_n_irgs(); i++) {
free_loop_information(get_irp_irg(i));
}
+#ifdef INTERPROCEDURAL_VIEW
set_interprocedural_view(rem);
+#endif
}
assert(l && l->kind == k_ir_loop);
if (get_loop_n_elements(l) == 0) {
- printf(" Loop completely empty! "); DDML(l);
found_problem = 1;
dump_loop(l, "-ha");
}
le = get_loop_element(l, 0);
if (*(le.kind) != k_ir_node) {
assert(le.kind && *(le.kind) == k_ir_loop);
- printf(" First loop element is not a node! "); DDML(l);
- printf(" "); DDML(le.son);
found_problem = 1;
dump_loop(l, "-ha");
}
if ((*(le.kind) == k_ir_node) && !is_possible_loop_head(le.node)) {
- printf(" Wrong node as head! "); DDML(l);
- printf(" "); DDMN(le.node);
found_problem = 1;
dump_loop(l, "-ha");
}
if ((get_loop_depth(l) != 0) &&
(*(le.kind) == k_ir_node) && !has_backedges(le.node)) {
- printf(" Loop head has no backedges! "); DDML(l);
- printf(" "); DDMN(le.node);
found_problem = 1;
dump_loop(l, "-ha");
}
}
if (has_node == 0) {
- printf(" Loop has no firm node! "); DDML(l);
found_problem = 1;
dump_loop(l, "-ha");
}
*/
void find_strange_loop_nodes(ir_loop *l) {
int found_problem = 0;
- printf("\nTesting loop "); DDML(l);
found_problem = test_loop_node(l);
printf("Finished Test\n\n");
if (found_problem) exit(0);