#include "config.h"
#endif
+#ifdef HAVE_STRING_H
#include <string.h>
+#endif
+
+#include <stdlib.h>
#include "irloop_t.h"
#endif
}
+int is_ir_loop(const void *thing) {
+ return (get_kind(thing) == k_ir_loop);
+}
+
/* The outermost loop is remarked in the surrounding graph. */
void set_irg_loop(ir_graph *irg, ir_loop *loop) {
assert(irg);
init_node (ir_node *n, void *env) {
set_irn_link (n, new_scc_info());
clear_backedges(n);
-#if 0
- /* Also init nodes not visible in intraproc_view. */
- /* @@@ init_node is called for too many nodes -- this wastes memory!.
- The mem is not lost as its on the obstack. */
- if (get_irn_op(n) == op_Filter) {
- for (i = 0; i < get_Filter_n_cg_preds(n); i++)
- init_node(get_Filter_cg_pred(n, i), NULL);
- }
- if (get_irn_op(n) == op_Block) {
- for (i = 0; i < get_Block_cg_n_cfgpreds(n); i++) {
- init_node(get_Block_cg_cfgpred(n, i), NULL);
- }
- }
- /* The following pattern matches only after a call from above pattern. */
- if ((get_irn_op(n) == op_Proj) /*&& (get_Proj_proj(n) == 0)*/) {
- /* @@@ init_node is called for every proj -- this wastes memory!.
- The mem is not lost as its on the obstack. */
- ir_node *cb = get_Proj_pred(n);
- if ((get_irn_op(cb) == op_CallBegin) ||
- (get_irn_op(cb) == op_EndReg) ||
- (get_irn_op(cb) == op_EndExcept)) {
- init_node(cb, NULL);
- init_node(get_nodes_block(cb), NULL);
- }
- }
-#endif
}
static INLINE void
Besides current_ir_graph is not set properly. */
if ((get_irn_op(n) == op_Block) &&
(n == get_irg_start_block(current_ir_graph))) {
- if ((!interprocedural_view) ||
+ if ((!get_interprocedural_view()) ||
(current_ir_graph == outermost_ir_graph))
return true;
}
test showed the loop tree is deeper. */
if (get_irn_op(n) == op_Phi ||
get_irn_op(n) == op_Block ||
- (get_irn_op(n) == op_Filter && interprocedural_view) ||
+ (get_irn_op(n) == op_Filter && get_interprocedural_view()) ||
(get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats &&
- get_op_pinned(get_irn_op(n)) == op_pin_state_floats))
+ get_irn_pinned(n) == op_pin_state_floats))
// Here we could test for backedge at -1 which is illegal
return 0;
else
ir_op *op = get_irn_op(n);
return ((op == op_Block) ||
(op == op_Phi) ||
- ((op == op_Filter) && interprocedural_view));
+ ((op == op_Filter) && get_interprocedural_view()));
}
/* Returns true if n is a loop header, i.e., it is a Block, Phi
ir_graph *rem = current_ir_graph;
ir_loop *head_rem;
- assert(!interprocedural_view &&
+ assert(!get_interprocedural_view() &&
"not implemented, use construct_ip_backedges");
max_loop_depth = 0;
int construct_ip_backedges (void) {
ir_graph *rem = current_ir_graph;
- int rem_ipv = interprocedural_view;
+ int rem_ipv = get_interprocedural_view();
int i;
max_loop_depth = 0;
current_loop = NULL;
new_loop(); /* sets current_loop */
- interprocedural_view = 1;
+ set_interprocedural_view(true);
inc_max_irg_visited();
for (i = 0; i < get_irp_n_irgs(); i++)
assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
current_ir_graph = rem;
- interprocedural_view = rem_ipv;
+ set_interprocedural_view(rem_ipv);
return max_loop_depth;
}
void my_construct_ip_backedges (void) {
ir_graph *rem = current_ir_graph;
- int rem_ipv = interprocedural_view;
+ int rem_ipv = get_interprocedural_view();
int i;
assert(get_irp_ip_view_state() == ip_view_valid);
current_loop = NULL;
new_loop(); /* sets current_loop */
- interprocedural_view = 1;
+ set_interprocedural_view(true);
inc_max_irg_visited();
for (i = 0; i < get_irp_n_irgs(); i++)
assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
current_ir_graph = rem;
- interprocedural_view = rem_ipv;
+ set_interprocedural_view(rem_ipv);
}
static void reset_backedges(ir_node *n) {
if (is_possible_loop_head(n)) {
- int rem = interprocedural_view;
- interprocedural_view = 1;
+ int rem = get_interprocedural_view();
+
+ set_interprocedural_view(true);
clear_backedges(n);
- interprocedural_view = 0;
+ set_interprocedural_view(true);
clear_backedges(n);
- interprocedural_view = rem;
+ set_interprocedural_view(rem);
}
}
void free_all_loop_information (void) {
int i;
- int rem = interprocedural_view;
- interprocedural_view = 1; /* To visit all filter nodes */
+ int rem = get_interprocedural_view();
+ set_interprocedural_view(true); /* To visit all filter nodes */
for (i = 0; i < get_irp_n_irgs(); i++) {
free_loop_information(get_irp_irg(i));
}
- interprocedural_view = rem;
+ set_interprocedural_view(rem);
}
if (found_problem) exit(0);
}
+
+/* ------------------------------------------------------------------- */
+/* Simple analyses based on the loop information */
+/* ------------------------------------------------------------------- */
+
+int is_loop_variant(ir_loop *l, ir_loop *b) {
+ int i, n_elems;
+
+ if (l == b) return true;
+
+ n_elems = get_loop_n_elements(l);
+ for (i = 0; i < n_elems; ++i) {
+ loop_element e = get_loop_element(l, i);
+ if (is_ir_loop(e.kind))
+ if (is_loop_variant(e.son, b))
+ return true;
+ }
+
+ return false;
+}
+
+/* Test whether a value is loop invariant.
+ *
+ * @param n The node to be tested.
+ * @param block A block node. We pass the block, not the loop as we must
+ * start off with a block loop to find all proper uses.
+ *
+ * Returns true, if the node n is not changed in the loop block
+ * belongs to or in inner loops of this block. */
+int is_loop_invariant(ir_node *n, ir_node *block) {
+ ir_loop *l = get_irn_loop(block);
+ ir_node *b = (is_Block(n)) ? n : get_nodes_block(n);
+ return !is_loop_variant(l, get_irn_loop(b));
+}